diff --git a/.asf.yaml b/.asf.yaml
index 092e06d97168..f27b5afa4258 100644
--- a/.asf.yaml
+++ b/.asf.yaml
@@ -16,7 +16,6 @@
# under the License.
# https://cwiki.apache.org/confluence/display/INFRA/git+-+.asf.yaml+features
----
github:
description: "Apache CloudStack is an opensource Infrastructure as a Service (IaaS) cloud computing platform"
homepage: https://cloudstack.apache.org/
@@ -50,18 +49,33 @@ github:
rebase: false
collaborators:
- - acs-robot
- - gpordeus
- - hsato03
- - FelipeM525
- - lucas-a-martins
- - nicoschmdt
- - abh1sar
- - rosi-shapeblue
- - sudo87
+ - ingox
+ - gp-santos
- erikbocks
+ - Imvedansh
+ - Damans227
+ - jmsperu
+ - GaOrtiga
+ - bhouse-nexthop
- protected_branches: ~
+ protected_branches:
+
+ rulesets:
+ - name: "Default Branch Protection"
+ type: branch
+ branches:
+ includes:
+ - "~DEFAULT_BRANCH"
+ excludes: []
+ bypass_teams:
+ - root
+ restrict_deletion: true
+ restrict_force_push: true
+
+ copilot_code_review:
+ enabled: true
+ review_drafts: true
+ review_on_push: true
notifications:
commits: commits@cloudstack.apache.org
diff --git a/.codespellrc b/.codespellrc
new file mode 100644
index 000000000000..3c632f8ba534
--- /dev/null
+++ b/.codespellrc
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[codespell]
+ignore-words = .github/linters/codespell.txt
+skip = systemvm/agent/noVNC/*,ui/package.json,ui/package-lock.json,ui/public/js/less.min.js,ui/public/locales/*.json,server/src/test/java/org/apache/cloudstack/network/ssl/CertServiceTest.java,test/integration/smoke/test_ssl_offloading.py
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000000..1b06f3ebf53c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+.github/workflows/*.lock.yml linguist-generated=true merge=ours
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 000000000000..689275cff115
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,25 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+/plugins/storage/volume/linstor @rp-
+/plugins/storage/volume/storpool @slavkap
+/plugins/storage/volume/ontap @rajiv1 @sandeeplocharla @piyush5 @suryag
+
+.pre-commit-config.yaml @jbampton
+/.github/linters/ @jbampton
+
+/plugins/network-elements/nsx/ @Pearl1594 @nvazquez
diff --git a/.github/actions/install-nonoss/action.yml b/.github/actions/install-nonoss/action.yml
new file mode 100644
index 000000000000..39a03213c29d
--- /dev/null
+++ b/.github/actions/install-nonoss/action.yml
@@ -0,0 +1,31 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: 'Install CloudStack Non-OSS'
+description: 'Clones and installs the shapeblue/cloudstack-nonoss repository.'
+
+runs:
+ using: "composite"
+ steps:
+ - name: Install cloudstack-nonoss
+ shell: bash
+ run: |
+ git clone --depth 1 https://github.com/shapeblue/cloudstack-nonoss.git nonoss
+ cd nonoss
+ bash -x install-non-oss.sh
+ cd ..
+ rm -fr nonoss
diff --git a/.github/actions/setup-env/action.yml b/.github/actions/setup-env/action.yml
new file mode 100644
index 000000000000..0f8425229242
--- /dev/null
+++ b/.github/actions/setup-env/action.yml
@@ -0,0 +1,58 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: 'Setup CloudStack Environment'
+description: 'Sets up JDK (with Maven cache), optionally Python, and optionally APT build dependencies for CloudStack.'
+
+inputs:
+ java-version:
+ description: 'The JDK version to use'
+ required: false
+ default: '17'
+ install-python:
+ description: 'Whether to install Python 3.10'
+ required: false
+ default: 'false'
+ install-apt-deps:
+ description: 'Whether to install CloudStack APT build dependencies'
+ required: false
+ default: 'false'
+
+runs:
+ using: "composite"
+ steps:
+ - name: Set up JDK ${{ inputs.java-version }}
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
+ with:
+ java-version: ${{ inputs.java-version }}
+ distribution: 'adopt'
+ architecture: x64
+ cache: 'maven'
+
+ - name: Set up Python
+ if: ${{ inputs.install-python == 'true' }}
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ with:
+ python-version: '3.10'
+ architecture: x64
+
+ - name: Install Build Dependencies
+ if: ${{ inputs.install-apt-deps == 'true' }}
+ shell: bash
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y git uuid-runtime genisoimage netcat-openbsd ipmitool build-essential libgcrypt20 libgpg-error-dev libgpg-error0 libopenipmi0 libpython3-dev libssl-dev libffi-dev python3-openssl python3-dev python3-setuptools
diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json
new file mode 100644
index 000000000000..ea25ffab6b9e
--- /dev/null
+++ b/.github/aw/actions-lock.json
@@ -0,0 +1,56 @@
+{
+ "entries": {
+ "actions/github-script@v9.0.0": {
+ "repo": "actions/github-script",
+ "version": "v9.0.0",
+ "sha": "3a2844b7e9c422d3c10d287c895573f7108da1b3"
+ },
+ "github/gh-aw-actions/setup@v0.76.1": {
+ "repo": "github/gh-aw-actions/setup",
+ "version": "v0.76.1",
+ "sha": "46d564922b082d0db93244972e8005ea6904ee5f"
+ }
+ },
+ "containers": {
+ "ghcr.io/github/gh-aw-firewall/agent:0.18.0": {
+ "image": "ghcr.io/github/gh-aw-firewall/agent:0.18.0",
+ "digest": "sha256:ab84dfc7f5998cb8cd0c596526dd573b7e7d06c6a740266a1e6df879fa16c866",
+ "pinned_image": "ghcr.io/github/gh-aw-firewall/agent:0.18.0@sha256:ab84dfc7f5998cb8cd0c596526dd573b7e7d06c6a740266a1e6df879fa16c866"
+ },
+ "ghcr.io/github/gh-aw-firewall/agent:0.25.55": {
+ "image": "ghcr.io/github/gh-aw-firewall/agent:0.25.55",
+ "digest": "sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731",
+ "pinned_image": "ghcr.io/github/gh-aw-firewall/agent:0.25.55@sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731"
+ },
+ "ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55": {
+ "image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55",
+ "digest": "sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3",
+ "pinned_image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55@sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3"
+ },
+ "ghcr.io/github/gh-aw-firewall/squid:0.18.0": {
+ "image": "ghcr.io/github/gh-aw-firewall/squid:0.18.0",
+ "digest": "sha256:82a5d062a5612a57a43a171a5b79ddbb690a86a8ddda02339cc1675131ae9f8b",
+ "pinned_image": "ghcr.io/github/gh-aw-firewall/squid:0.18.0@sha256:82a5d062a5612a57a43a171a5b79ddbb690a86a8ddda02339cc1675131ae9f8b"
+ },
+ "ghcr.io/github/gh-aw-firewall/squid:0.25.55": {
+ "image": "ghcr.io/github/gh-aw-firewall/squid:0.25.55",
+ "digest": "sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca",
+ "pinned_image": "ghcr.io/github/gh-aw-firewall/squid:0.25.55@sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca"
+ },
+ "ghcr.io/github/gh-aw-mcpg:v0.1.4": {
+ "image": "ghcr.io/github/gh-aw-mcpg:v0.1.4",
+ "digest": "sha256:0acf25aa1d409f9c73be9e39ac84f4bd4b90d8bfa1db4dc6d7f47d38ccd58914",
+ "pinned_image": "ghcr.io/github/gh-aw-mcpg:v0.1.4@sha256:0acf25aa1d409f9c73be9e39ac84f4bd4b90d8bfa1db4dc6d7f47d38ccd58914"
+ },
+ "ghcr.io/github/gh-aw-mcpg:v0.3.19": {
+ "image": "ghcr.io/github/gh-aw-mcpg:v0.3.19",
+ "digest": "sha256:a6c890d7c24d7190c9ef97b9c954cc4cffaae6b01c371ced1f959f1370b1f68f",
+ "pinned_image": "ghcr.io/github/gh-aw-mcpg:v0.3.19@sha256:a6c890d7c24d7190c9ef97b9c954cc4cffaae6b01c371ced1f959f1370b1f68f"
+ },
+ "ghcr.io/github/github-mcp-server:v0.30.3": {
+ "image": "ghcr.io/github/github-mcp-server:v0.30.3",
+ "digest": "sha256:a2b5fb79b1cee851bfc3532dfe480c3dc5736974ca9d93a7a9f68e52ce4b62a0",
+ "pinned_image": "ghcr.io/github/github-mcp-server:v0.30.3@sha256:a2b5fb79b1cee851bfc3532dfe480c3dc5736974ca9d93a7a9f68e52ce4b62a0"
+ }
+ }
+}
diff --git a/.github/aw/imports/.gitattributes b/.github/aw/imports/.gitattributes
new file mode 100644
index 000000000000..f0516fad90e4
--- /dev/null
+++ b/.github/aw/imports/.gitattributes
@@ -0,0 +1,5 @@
+# Mark all cached import files as generated
+* linguist-generated=true
+
+# Use 'ours' merge strategy to keep local cached versions
+* merge=ours
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 000000000000..6ffb926f6fa0
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,43 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ open-pull-requests-limit: 2
+ schedule:
+ interval: "weekly"
+ groups:
+ github-actions-dependencies:
+ patterns:
+ - "*"
+ ignore:
+ - dependency-name: "github/gh-aw-actions/**" # Managed by gh aw compile. Version-locked to the gh-aw compiler; do not bump.
+ cooldown:
+ default-days: 7
+ - package-ecosystem: "maven"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ cooldown:
+ default-days: 7
diff --git a/.github/linters/.yamllint.yml b/.github/linters/.yamllint.yml
index 8a72aee0adbe..97b66848696a 100644
--- a/.github/linters/.yamllint.yml
+++ b/.github/linters/.yamllint.yml
@@ -15,13 +15,14 @@
# specific language governing permissions and limitations
# under the License.
---
-extends: relaxed
+extends: default
rules:
line-length:
max: 400 # Very forgiving for GitHub Actions and infrastructure files
indentation: disable # Disable indentation checking for existing files
comments: disable # Disable comment formatting checks
+ braces: disable
brackets: disable # Disable bracket spacing checks
colons:
max-spaces-after: -1 # Allow any number of spaces after colon
diff --git a/.github/linters/codespell.txt b/.github/linters/codespell.txt
index 7c8e94021b0e..67cbeaa7cbb3 100644
--- a/.github/linters/codespell.txt
+++ b/.github/linters/codespell.txt
@@ -255,7 +255,6 @@ ingore
initalize
initator
inspite
-instace
instal
instnace
intefaces
@@ -376,7 +375,6 @@ renabling
reponse
reqest
reqiured
-requried
reserv
reserverd
reseted
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 84020f4a6b06..62b816719c7b 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -16,40 +16,27 @@
# under the License.
name: Build
-
-on: [push, pull_request]
-
+on:
+ - push
+ - pull_request
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
- cancel-in-progress: true
-
+ cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
permissions:
contents: read
-
jobs:
build:
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
steps:
- - uses: actions/checkout@v5
-
- - name: Set up JDK 17
- uses: actions/setup-java@v5
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
- distribution: 'temurin'
- java-version: '17'
- cache: 'maven'
+ persist-credentials: false
- - name: Set up Python
- uses: actions/setup-python@v6
+ - name: Setup Environment
+ uses: ./.github/actions/setup-env
with:
- python-version: '3.10'
- architecture: 'x64'
-
- - name: Install Build Dependencies
- run: |
- sudo apt-get update
- sudo apt-get install -y git uuid-runtime genisoimage netcat ipmitool build-essential libgcrypt20 libgpg-error-dev libgpg-error0 libopenipmi0 ipmitool libpython3-dev libssl-dev libffi-dev python3-openssl python3-dev python3-setuptools
-
+ install-python: 'true'
+ install-apt-deps: 'true'
- name: Env details
run: |
uname -a
@@ -60,9 +47,8 @@ jobs:
free -m
nproc
git status
-
+ - name: Install Non-OSS
+ uses: ./.github/actions/install-nonoss
- name: Noredist Build
run: |
- git clone https://github.com/shapeblue/cloudstack-nonoss.git nonoss && cd nonoss && bash -x install-non-oss.sh && cd ..
- rm -fr nonoss
mvn -B -P developer,systemvm -Dsimulator -Dnoredist clean install -T$(nproc)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4edd448067ae..63484def8f9b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -16,21 +16,56 @@
# under the License.
name: Simulator CI
-
-on: [push, pull_request]
-
+on:
+ - push
+ - pull_request
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
- cancel-in-progress: true
-
+ cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
permissions:
contents: read
-
jobs:
build:
if: github.repository == 'apache/cloudstack'
runs-on: ubuntu-24.04
-
+ steps:
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ fetch-depth: 0
+ persist-credentials: false
+ - name: Setup Environment
+ uses: ./.github/actions/setup-env
+ with:
+ install-python: 'true'
+ install-apt-deps: 'true'
+ - name: Env details
+ run: |
+ uname -a
+ whoami
+ javac -version
+ mvn -v
+ python3 --version
+ free -m
+ nproc
+ git status
+ ipmitool -V
+ - name: Build with Maven
+ run: |
+ mvn -B -P developer,systemvm -Dsimulator clean install -DskipTests=true -T$(nproc)
+ - name: Archive artifacts
+ run: |
+ mkdir -p /tmp/artifacts
+ tar -czf /tmp/artifacts/targets.tar.gz $(find . -name "target" -type d) tools/marvin/dist engine/schema/dist utils/conf
+ tar -czf /tmp/artifacts/m2-cloudstack.tar.gz -C ~/.m2/repository org/apache/cloudstack
+ - name: Upload artifacts
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: build-artifacts
+ path: /tmp/artifacts/
+ test:
+ needs: build
+ if: github.repository == 'apache/cloudstack'
+ runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
@@ -146,6 +181,7 @@ jobs:
smoke/test_vm_snapshot_kvm
smoke/test_vm_snapshots
smoke/test_volumes
+ smoke/test_vpc_conserve_mode
smoke/test_vpc_ipv6
smoke/test_vpc_redundant
smoke/test_vpc_router_nics
@@ -214,30 +250,16 @@ jobs:
smoke/test_list_service_offerings
smoke/test_list_storage_pools
smoke/test_list_volumes"]
-
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
fetch-depth: 0
-
- - name: Set up JDK 17
- uses: actions/setup-java@v5
+ persist-credentials: false
+ - name: Setup Environment
+ uses: ./.github/actions/setup-env
with:
- distribution: 'temurin'
- java-version: '17'
- cache: 'maven'
-
- - name: Set up Python
- uses: actions/setup-python@v6
- with:
- python-version: '3.10'
- architecture: 'x64'
-
- - name: Install Build Dependencies
- run: |
- sudo apt-get update
- sudo apt-get install -y git uuid-runtime genisoimage netcat-openbsd ipmitool build-essential libgcrypt20 libgpg-error-dev libgpg-error0 libopenipmi0 ipmitool libpython3-dev libssl-dev libffi-dev python3-openssl python3-dev python3-setuptools
-
+ install-python: 'true'
+ install-apt-deps: 'true'
- name: Setup IPMI Tool for CloudStack
run: |
# Create cloudstack-common directory if it doesn't exist
@@ -255,55 +277,43 @@ jobs:
/usr/share/cloudstack-common/ipmitool -C3 $@
EOF
sudo chmod 755 /usr/bin/ipmitool
-
- name: Install Python dependencies
run: |
python3 -m pip install --user --upgrade urllib3 lxml paramiko nose texttable ipmisim pyopenssl pycryptodome mock flask netaddr pylint pycodestyle six astroid pynose
-
- name: Install jacoco dependencies
run: |
wget https://github.com/jacoco/jacoco/releases/download/v0.8.10/jacoco-0.8.10.zip
unzip jacoco-0.8.10.zip -d jacoco
-
- - name: Env details
- run: |
- uname -a
- whoami
- javac -version
- mvn -v
- python3 --version
- free -m
- nproc
- git status
- ipmitool -V
-
- name: Setup MySQL Server
run: |
# https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2004-Readme.md#mysql
sudo apt-get install -y mysql-server
sudo systemctl start mysql
- sudo mysql -uroot -proot -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY ''; FLUSH PRIVILEGES;"
+ sudo mysql -uroot -proot -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY ''; FLUSH PRIVILEGES;"
sudo systemctl restart mysql
sudo mysql -uroot -e "SELECT VERSION();"
-
- - name: Build with Maven
+ - name: Download artifacts
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: build-artifacts
+ path: /tmp/artifacts/
+ - name: Extract artifacts
run: |
- mvn -B -P developer,systemvm -Dsimulator clean install -DskipTests=true -T$(nproc)
-
+ tar -xzf /tmp/artifacts/targets.tar.gz
+ mkdir -p ~/.m2/repository
+ tar -xzf /tmp/artifacts/m2-cloudstack.tar.gz -C ~/.m2/repository
- name: Setup Simulator Prerequisites
run: |
sudo python3 -m pip install --upgrade netaddr mysql-connector-python
python3 -m pip install --user --upgrade tools/marvin/dist/[mM]arvin-*.tar.gz
mvn -q -Pdeveloper -pl developer -Ddeploydb
mvn -q -Pdeveloper -pl developer -Ddeploydb-simulator
-
- name: Generate jacoco-coverage.sh
run: |
echo "java -jar jacoco/lib/jacococli.jar report jacoco-it.exec \\" > jacoco-report.sh
find . | grep "target/classes" | sed 's/\/classes\//\/classes /g' | awk '{print "--classfiles", $1, "\\"}' | sort |uniq >> jacoco-report.sh
find . | grep "src/main/java" | sed 's/\/java\//\/java /g' | awk '{print "--sourcefiles", $1, "\\"}' | sort | uniq >> jacoco-report.sh
echo "--xml jacoco-coverage.xml" >> jacoco-report.sh
-
- name: Start CloudStack Management Server with Simulator
run: |
export MAVEN_OPTS="-Xmx4096m -XX:MaxMetaspaceSize=800m -Djava.security.egd=file:/dev/urandom -javaagent:jacoco/lib/jacocoagent.jar=address=*,port=36320,output=tcpserver --add-opens=java.base/java.lang=ALL-UNNAMED --add-exports=java.base/sun.security.x509=ALL-UNNAMED --add-opens=java.base/jdk.internal.reflect=ALL-UNNAMED"
@@ -314,7 +324,6 @@ jobs:
set -e
echo -e "\nStarting Advanced Zone DataCenter deployment"
python3 tools/marvin/marvin/deployDataCenter.py -i setup/dev/advdualzone.cfg 2>&1 || true
-
- name: Run Integration Tests with Simulator
run: |
mkdir -p integration-test-results/smoke/misc
@@ -334,13 +343,12 @@ jobs:
bash jacoco-report.sh
mvn -Dsimulator -pl client jetty:stop 2>&1
find /tmp//MarvinLogs -type f -exec echo -e "Printing marvin logs {} :\n" \; -exec cat {} \;
-
- name: Integration Tests Result
run: |
echo -e "Simulator CI Test Results: (only failures listed)\n"
python3 ./tools/marvin/xunit-reader.py integration-test-results/
- - uses: codecov/codecov-action@v4
+ - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
files: jacoco-coverage.xml
fail_ci_if_error: true
diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml
deleted file mode 100644
index fbd944a758f9..000000000000
--- a/.github/workflows/codecov.yml
+++ /dev/null
@@ -1,59 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-name: Coverage Check
-
-on: [pull_request, push]
-
-permissions:
- contents: read
-
-concurrency:
- group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
- cancel-in-progress: true
-
-jobs:
- build:
- if: github.repository == 'apache/cloudstack'
- name: codecov
- runs-on: ubuntu-22.04
- steps:
- - uses: actions/checkout@v5
- with:
- fetch-depth: 0
-
- - name: Set up JDK 17
- uses: actions/setup-java@v5
- with:
- distribution: 'temurin'
- java-version: '17'
- cache: 'maven'
-
- - name: Build CloudStack with Quality Checks
- run: |
- git clone https://github.com/shapeblue/cloudstack-nonoss.git nonoss
- cd nonoss && bash -x install-non-oss.sh && cd ..
- mvn -P quality -Dsimulator -Dnoredist clean install -T$(nproc)
-
- - uses: codecov/codecov-action@v4
- with:
- files: ./client/target/site/jacoco-aggregate/jacoco.xml
- fail_ci_if_error: true
- flags: unittests
- verbose: true
- name: codecov
- token: ${{ secrets.CODECOV_TOKEN }}
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 74e59aa821d1..f6bc65ad4b5b 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -35,14 +35,16 @@ jobs:
language: ["actions"]
steps:
- name: Checkout repository
- uses: actions/checkout@v5
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
- name: Initialize CodeQL
- uses: github/codeql-action/init@v3
+ uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
with:
languages: ${{ matrix.language }}
- name: Autobuild
- uses: github/codeql-action/autobuild@v3
+ uses: github/codeql-action/autobuild@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v3
+ uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
with:
category: "Security"
diff --git a/.github/workflows/daily-issue-triage.lock.yml b/.github/workflows/daily-issue-triage.lock.yml
new file mode 100644
index 000000000000..bd07aeefd811
--- /dev/null
+++ b/.github/workflows/daily-issue-triage.lock.yml
@@ -0,0 +1,1400 @@
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"919fb17c7928e5e96d9c0a2854670a42f9c5f6cfc2059b46009bb3c23640d0ca","compiler_version":"v0.76.1","strict":true,"agent_id":"copilot"}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"46d564922b082d0db93244972e8005ea6904ee5f","version":"v0.76.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55","digest":"sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55@sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55","digest":"sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55@sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55","digest":"sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55@sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.19","digest":"sha256:a6c890d7c24d7190c9ef97b9c954cc4cffaae6b01c371ced1f959f1370b1f68f","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.19@sha256:a6c890d7c24d7190c9ef97b9c954cc4cffaae6b01c371ced1f959f1370b1f68f"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14","pinned_image":"node:lts-alpine@sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14"}]}
+# ___ _ _
+# / _ \ | | (_)
+# | |_| | __ _ ___ _ __ | |_ _ ___
+# | _ |/ _` |/ _ \ '_ \| __| |/ __|
+# | | | | (_| | __/ | | | |_| | (__
+# \_| |_/\__, |\___|_| |_|\__|_|\___|
+# __/ |
+# _ _ |___/
+# | | | | / _| |
+# | | | | ___ _ __ _ __| |_| | _____ ____
+# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___|
+# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
+# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
+#
+# This file was automatically generated by gh-aw (v0.76.1). DO NOT EDIT.
+#
+# To update this file, edit githubnext/agentics/workflows/daily-issue-triage.md@d7c1dc4b72b00607a67caaffdcc216cb64379cf9 and run:
+# gh aw compile
+# Not all edits will cause changes to this file.
+#
+# For more information: https://github.github.com/gh-aw/introduction/overview/
+#
+# Scheduled daily triage that processes untriaged CloudStack issues in batches.
+# Detects duplicates, filters spam, and assigns CloudStack-specific labels
+# (type:*, component:*, Severity:*, status:*), then posts a structured triage report.
+#
+# Source: githubnext/agentics/workflows/daily-issue-triage.md@d7c1dc4b72b00607a67caaffdcc216cb64379cf9
+#
+# Secrets used:
+# - COPILOT_GITHUB_TOKEN
+# - GH_AW_GITHUB_MCP_SERVER_TOKEN
+# - GH_AW_GITHUB_TOKEN
+# - GITHUB_TOKEN
+#
+# Custom actions used:
+# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+# - github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+#
+# Container images used:
+# - ghcr.io/github/gh-aw-firewall/agent:0.25.55@sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55@sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3
+# - ghcr.io/github/gh-aw-firewall/squid:0.25.55@sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca
+# - ghcr.io/github/gh-aw-mcpg:v0.3.19@sha256:a6c890d7c24d7190c9ef97b9c954cc4cffaae6b01c371ced1f959f1370b1f68f
+# - ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4
+# - node:lts-alpine@sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14
+
+name: "Daily Issue Triage"
+on:
+ schedule:
+ - cron: "26 13 * * 1-5"
+ # Friendly format: daily around 14:00 on weekdays (scattered)
+ workflow_dispatch:
+ inputs:
+ aw_context:
+ default: ""
+ description: "Agent caller context (used internally by Agentic Workflows)."
+ required: false
+ type: string
+
+permissions: {}
+
+concurrency:
+ group: "gh-aw-${{ github.workflow }}"
+
+run-name: "Daily Issue Triage"
+
+jobs:
+ activation:
+ runs-on: ubuntu-slim
+ permissions:
+ actions: read
+ contents: read
+ outputs:
+ comment_id: ""
+ comment_repo: ""
+ engine_id: ${{ steps.generate_aw_info.outputs.engine_id }}
+ lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
+ model: ${{ steps.generate_aw_info.outputs.model }}
+ secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Daily Issue Triage"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-issue-triage.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.52"
+ GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_BODY_MODIFIED: "false"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Generate agentic run info
+ id: generate_aw_info
+ env:
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
+ GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_INFO_VERSION: "1.0.52"
+ GH_AW_INFO_AGENT_VERSION: "1.0.52"
+ GH_AW_INFO_CLI_VERSION: "v0.76.1"
+ GH_AW_INFO_WORKFLOW_NAME: "Daily Issue Triage"
+ GH_AW_INFO_EXPERIMENTAL: "false"
+ GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
+ GH_AW_INFO_STAGED: "false"
+ GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
+ GH_AW_INFO_FIREWALL_ENABLED: "true"
+ GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_AWMG_VERSION: ""
+ GH_AW_INFO_FIREWALL_TYPE: "squid"
+ GH_AW_INFO_FRONTMATTER_SOURCE: "githubnext/agentics/workflows/daily-issue-triage.md@d7c1dc4b72b00607a67caaffdcc216cb64379cf9"
+ GH_AW_INFO_BODY_MODIFIED: "false"
+ GH_AW_COMPILED_STRICT: "true"
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
+ await main(core, context);
+ - name: Validate COPILOT_GITHUB_TOKEN secret
+ id: validate-secret
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh" COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
+ env:
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ - name: Checkout .github and .agents folders
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+ sparse-checkout: |
+ .github
+ .agents
+ .antigravity
+ .claude
+ .codex
+ .crush
+ .gemini
+ .opencode
+ .pi
+ sparse-checkout-cone-mode: true
+ fetch-depth: 1
+ - name: Save agent config folders for base branch restoration
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi"
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
+ # poutine:ignore untrusted_checkout_exec
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh"
+ - name: Check workflow lock file
+ id: check-lock-file
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_WORKFLOW_FILE: "daily-issue-triage.lock.yml"
+ GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}"
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
+ await main();
+ - name: Check compile-agentic version
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_COMPILED_VERSION: "v0.76.1"
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs');
+ await main();
+ - name: Create prompt with built-in context
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl
+ GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+ # poutine:ignore untrusted_checkout_exec
+ run: |
+ bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
+ {
+ cat << 'GH_AW_PROMPT_7c51e8f15cc7af75_EOF'
+
+ GH_AW_PROMPT_7c51e8f15cc7af75_EOF
+ cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
+ cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
+ cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
+ cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
+ cat << 'GH_AW_PROMPT_7c51e8f15cc7af75_EOF'
+
+ Tools: add_comment(max:10), add_labels(max:10), missing_tool, missing_data, noop
+
+ GH_AW_PROMPT_7c51e8f15cc7af75_EOF
+ cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
+ cat << 'GH_AW_PROMPT_7c51e8f15cc7af75_EOF'
+
+ The following GitHub context information is available for this workflow:
+ {{#if github.actor}}
+ - **actor**: __GH_AW_GITHUB_ACTOR__
+ {{/if}}
+ {{#if github.repository}}
+ - **repository**: __GH_AW_GITHUB_REPOSITORY__
+ {{/if}}
+ {{#if github.workspace}}
+ - **workspace**: __GH_AW_GITHUB_WORKSPACE__
+ {{/if}}
+ {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}
+ - **issue-number**: #__GH_AW_EXPR_802A9F6A__
+ {{/if}}
+ {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}
+ - **discussion-number**: #__GH_AW_EXPR_1A3A194A__
+ {{/if}}
+ {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}
+ - **pull-request-number**: #__GH_AW_EXPR_463A214A__
+ {{/if}}
+ {{#if github.event.comment.id || github.aw.context.comment_id}}
+ - **comment-id**: __GH_AW_EXPR_FF1D34CE__
+ {{/if}}
+ {{#if github.run_id}}
+ - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
+ {{/if}}
+
+
+ GH_AW_PROMPT_7c51e8f15cc7af75_EOF
+ cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
+ cat << 'GH_AW_PROMPT_7c51e8f15cc7af75_EOF'
+
+ {{#runtime-import .github/workflows/daily-issue-triage.md}}
+ GH_AW_PROMPT_7c51e8f15cc7af75_EOF
+ } > "$GH_AW_PROMPT"
+ - name: Interpolate variables and render templates
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_ENGINE_ID: "copilot"
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs');
+ await main();
+ - name: Substitute placeholders
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+ GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+
+ const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs');
+
+ // Call the substitution function
+ return await substitutePlaceholders({
+ file: process.env.GH_AW_PROMPT,
+ substitutions: {
+ GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A,
+ GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A,
+ GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A,
+ GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE,
+ GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
+ GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
+ GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
+ GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
+ GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST
+ }
+ });
+ - name: Validate prompt placeholders
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ # poutine:ignore untrusted_checkout_exec
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh"
+ - name: Print prompt
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ # poutine:ignore untrusted_checkout_exec
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh"
+ - name: Upload activation artifact
+ if: success()
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: activation
+ include-hidden-files: true
+ path: |
+ /tmp/gh-aw/aw_info.json
+ /tmp/gh-aw/aw-prompts/prompt.txt
+ /tmp/gh-aw/aw-prompts/prompt-template.txt
+ /tmp/gh-aw/aw-prompts/prompt-import-tree.json
+ /tmp/gh-aw/github_rate_limits.jsonl
+ /tmp/gh-aw/base
+ /tmp/gh-aw/.github/agents
+ /tmp/gh-aw/.github/skills
+ if-no-files-found: ignore
+ retention-days: 1
+
+ agent:
+ needs: activation
+ runs-on: ubuntu-latest
+ permissions: read-all
+ concurrency:
+ group: "gh-aw-copilot-${{ github.workflow }}"
+ env:
+ DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
+ GH_AW_ASSETS_ALLOWED_EXTS: ""
+ GH_AW_ASSETS_BRANCH: ""
+ GH_AW_ASSETS_MAX_SIZE_KB: 0
+ GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
+ GH_AW_WORKFLOW_ID_SANITIZED: dailyissuetriage
+ outputs:
+ agentic_engine_timeout: ${{ steps.detect-agent-errors.outputs.agentic_engine_timeout || 'false' }}
+ checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
+ effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }}
+ effective_tokens_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.effective_tokens_rate_limit_error || 'false' }}
+ has_patch: ${{ steps.collect_output.outputs.has_patch }}
+ inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }}
+ mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }}
+ model: ${{ needs.activation.outputs.model }}
+ model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }}
+ output: ${{ steps.collect_output.outputs.output }}
+ output_types: ${{ steps.collect_output.outputs.output_types }}
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Daily Issue Triage"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-issue-triage.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.52"
+ GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_BODY_MODIFIED: "false"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Set runtime paths
+ id: set-runtime-paths
+ run: |
+ {
+ echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl"
+ echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json"
+ echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
+ } >> "$GITHUB_OUTPUT"
+ - name: Checkout repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+ - name: Create gh-aw temp directory
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh"
+ - name: Configure gh CLI for GitHub Enterprise
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh"
+ env:
+ GH_TOKEN: ${{ github.token }}
+ - name: Configure Git credentials
+ env:
+ REPO_NAME: ${{ github.repository }}
+ SERVER_URL: ${{ github.server_url }}
+ GITHUB_TOKEN: ${{ github.token }}
+ run: |
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
+ git config --global user.name "github-actions[bot]"
+ git config --global am.keepcr true
+ # Re-authenticate git with GitHub token
+ SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+ git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+ echo "Git configured with standard GitHub Actions identity"
+ - name: Checkout PR branch
+ id: checkout-pr
+ if: |
+ github.event.pull_request || github.event.issue.pull_request
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
+ await main();
+ - name: Install GitHub Copilot CLI
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.52
+ env:
+ GH_HOST: github.com
+ - name: Install AWF binary
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55
+ - name: Parse integrity filter lists
+ id: parse-guard-vars
+ env:
+ GH_AW_BLOCKED_USERS_VAR: ${{ vars.GH_AW_GITHUB_BLOCKED_USERS || '' }}
+ GH_AW_TRUSTED_USERS_VAR: ${{ vars.GH_AW_GITHUB_TRUSTED_USERS || '' }}
+ GH_AW_APPROVAL_LABELS_VAR: ${{ vars.GH_AW_GITHUB_APPROVAL_LABELS || '' }}
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/parse_guard_list.sh"
+ - name: Download activation artifact
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: activation
+ path: /tmp/gh-aw
+ - name: Restore agent config folders from base branch
+ if: steps.checkout-pr.outcome == 'success'
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi"
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh"
+ - name: Restore inline sub-agents from activation artifact
+ env:
+ GH_AW_SUB_AGENT_DIR: ".github/agents"
+ GH_AW_SUB_AGENT_EXT: ".agent.md"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh"
+ - name: Restore inline skills from activation artifact
+ env:
+ GH_AW_SKILL_DIR: ".github/skills"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh"
+ - name: Download container images
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.55@sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55@sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3 ghcr.io/github/gh-aw-firewall/squid:0.25.55@sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca ghcr.io/github/gh-aw-mcpg:v0.3.19@sha256:a6c890d7c24d7190c9ef97b9c954cc4cffaae6b01c371ced1f959f1370b1f68f ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14
+ - name: Generate Safe Outputs Config
+ run: |
+ mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
+ mkdir -p /tmp/gh-aw/safeoutputs
+ mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_09fd9551c3cd7278_EOF'
+ {"add_comment":{"max":10,"target":"*"},"add_labels":{"max":10,"target":"*"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_09fd9551c3cd7278_EOF
+ - name: Generate Safe Outputs Tools
+ env:
+ GH_AW_TOOLS_META_JSON: |
+ {
+ "description_suffixes": {
+ "add_comment": " CONSTRAINTS: Maximum 10 comment(s) can be added. Target: *. Supports reply_to_id for discussion threading.",
+ "add_labels": " CONSTRAINTS: Maximum 10 label(s) can be added. Target: *."
+ },
+ "repo_params": {},
+ "dynamic_tools": []
+ }
+ GH_AW_VALIDATION_JSON: |
+ {
+ "add_comment": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "item_number": {
+ "issueOrPRNumber": true
+ },
+ "reply_to_id": {
+ "type": "string",
+ "maxLength": 256
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
+ "add_labels": {
+ "defaultMax": 5,
+ "fields": {
+ "item_number": {
+ "issueNumberOrTemporaryId": true
+ },
+ "labels": {
+ "required": true,
+ "type": "array",
+ "itemType": "string",
+ "itemSanitize": true,
+ "itemMaxLength": 128
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
+ "missing_data": {
+ "defaultMax": 20,
+ "fields": {
+ "alternatives": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ },
+ "context": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ },
+ "data_type": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 128
+ },
+ "reason": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ }
+ }
+ },
+ "missing_tool": {
+ "defaultMax": 20,
+ "fields": {
+ "alternatives": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 512
+ },
+ "reason": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ },
+ "tool": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 128
+ }
+ }
+ },
+ "noop": {
+ "defaultMax": 1,
+ "fields": {
+ "message": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ }
+ }
+ },
+ "report_incomplete": {
+ "defaultMax": 5,
+ "fields": {
+ "details": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "reason": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 1024
+ }
+ }
+ }
+ }
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
+ await main();
+ - name: Generate Safe Outputs MCP Server Config
+ id: safe-outputs-config
+ run: |
+ # Generate a secure random API key (360 bits of entropy, 40+ chars)
+ # Mask immediately to prevent timing vulnerabilities
+ API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
+ echo "::add-mask::${API_KEY}"
+
+ PORT=3001
+
+ # Set outputs for next steps
+ {
+ echo "safe_outputs_api_key=${API_KEY}"
+ echo "safe_outputs_port=${PORT}"
+ } >> "$GITHUB_OUTPUT"
+
+ echo "Safe Outputs MCP server will run on port ${PORT}"
+
+ - name: Start Safe Outputs MCP HTTP Server
+ id: safe-outputs-start
+ env:
+ DEBUG: '*'
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
+ GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
+ GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
+ run: |
+ # Environment variables are set above to prevent template injection
+ export DEBUG
+ export GH_AW_SAFE_OUTPUTS
+ export GH_AW_SAFE_OUTPUTS_PORT
+ export GH_AW_SAFE_OUTPUTS_API_KEY
+ export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
+ export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
+ export GH_AW_MCP_LOG_DIR
+
+ bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh"
+
+ - name: Start MCP Gateway
+ id: start-mcp-gateway
+ env:
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
+ GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+ GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ run: |
+ set -eo pipefail
+ mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
+
+ # Export gateway environment variables for MCP config and gateway script
+ export MCP_GATEWAY_PORT="8080"
+ export MCP_GATEWAY_DOMAIN="host.docker.internal"
+ export MCP_GATEWAY_HOST_DOMAIN="localhost"
+ MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
+ echo "::add-mask::${MCP_GATEWAY_API_KEY}"
+ export MCP_GATEWAY_API_KEY
+ export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads"
+ mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}"
+ export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288"
+ export DEBUG="*"
+
+ export GH_AW_ENGINE="copilot"
+ MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
+ MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
+ case "${DOCKER_HOST:-}" in
+ unix://* ) DOCKER_SOCK_PATH="${DOCKER_HOST#unix://}" ;;
+ /* ) DOCKER_SOCK_PATH="$DOCKER_HOST" ;;
+ * ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
+ esac
+ DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.19'
+
+ mkdir -p /home/runner/.copilot
+ GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
+ cat << GH_AW_MCP_CONFIG_37cac1d5ee0c175c_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ {
+ "mcpServers": {
+ "github": {
+ "type": "stdio",
+ "container": "ghcr.io/github/github-mcp-server:v1.0.4",
+ "env": {
+ "GITHUB_HOST": "\${GITHUB_SERVER_URL}",
+ "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
+ "GITHUB_READ_ONLY": "1",
+ "GITHUB_TOOLSETS": "issues,labels"
+ },
+ "guard-policies": {
+ "allow-only": {
+ "approval-labels": ${{ steps.parse-guard-vars.outputs.approval_labels }},
+ "blocked-users": ${{ steps.parse-guard-vars.outputs.blocked_users }},
+ "min-integrity": "none",
+ "repos": "all",
+ "trusted-users": ${{ steps.parse-guard-vars.outputs.trusted_users }}
+ }
+ }
+ },
+ "safeoutputs": {
+ "type": "http",
+ "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
+ "headers": {
+ "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+ },
+ "guard-policies": {
+ "write-sink": {
+ "accept": [
+ "*"
+ ]
+ }
+ }
+ }
+ },
+ "gateway": {
+ "port": $MCP_GATEWAY_PORT,
+ "domain": "${MCP_GATEWAY_DOMAIN}",
+ "apiKey": "${MCP_GATEWAY_API_KEY}",
+ "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
+ }
+ }
+ GH_AW_MCP_CONFIG_37cac1d5ee0c175c_EOF
+ - name: Mount MCP servers as CLIs
+ id: mount-mcp-clis
+ continue-on-error: true
+ env:
+ MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
+ MCP_GATEWAY_DOMAIN: ${{ steps.start-mcp-gateway.outputs.gateway-domain }}
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs');
+ await main();
+ - name: Clean credentials
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh"
+ - name: Audit pre-agent workspace
+ id: pre_agent_audit
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/audit_pre_agent_workspace.sh"
+ - name: Execute GitHub Copilot CLI
+ id: agentic_execution
+ # Copilot CLI tool arguments (sorted):
+ timeout-minutes: 60
+ run: |
+ set -o pipefail
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
+ touch /tmp/gh-aw/agent-step-summary.md
+ GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
+ export GH_AW_NODE_BIN
+ export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
+ (umask 177 && touch /tmp/gh-aw/agent-stdio.log)
+ printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/awf-config.schema.json","network":{"allowDomains":["api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","api.snapcraft.io","archive.ubuntu.com","azure.archive.ubuntu.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","github.com","host.docker.internal","json-schema.org","json.schemastore.org","keyserver.ubuntu.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","ppa.launchpad.net","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"vision":["copilot/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.25.55,squid=sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca,agent=sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731,api-proxy=sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ fi
+ # shellcheck disable=SC1003
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ env:
+ AWF_REFLECT_ENABLED: 1
+ COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+ COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
+ GH_AW_PHASE: agent
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ GH_AW_VERSION: v0.76.1
+ GITHUB_API_URL: ${{ github.api_url }}
+ GITHUB_AW: true
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
+ GITHUB_HEAD_REF: ${{ github.head_ref }}
+ GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ GITHUB_REF_NAME: ${{ github.ref_name }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
+ GITHUB_WORKSPACE: ${{ github.workspace }}
+ GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
+ GIT_AUTHOR_NAME: github-actions[bot]
+ GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
+ GIT_COMMITTER_NAME: github-actions[bot]
+ XDG_CONFIG_HOME: /home/runner
+ - name: Detect agent errors
+ if: always()
+ id: detect-agent-errors
+ continue-on-error: true
+ run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs"
+ - name: Configure Git credentials
+ env:
+ REPO_NAME: ${{ github.repository }}
+ SERVER_URL: ${{ github.server_url }}
+ GITHUB_TOKEN: ${{ github.token }}
+ run: |
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
+ git config --global user.name "github-actions[bot]"
+ git config --global am.keepcr true
+ # Re-authenticate git with GitHub token
+ SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+ git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+ echo "Git configured with standard GitHub Actions identity"
+ - name: Copy Copilot session state files to logs
+ if: always()
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh"
+ - name: Stop MCP Gateway
+ if: always()
+ continue-on-error: true
+ env:
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
+ MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
+ GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }}
+ run: |
+ bash "${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh" "$GATEWAY_PID"
+ - name: Redact secrets in logs
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
+ await main();
+ env:
+ GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+ SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
+ SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
+ SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: Append agent step summary
+ if: always()
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh"
+ - name: Copy Safe Outputs
+ if: always()
+ env:
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ run: |
+ mkdir -p /tmp/gh-aw
+ cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true
+ - name: Ingest agent output
+ id: collect_output
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_API_URL: ${{ github.api_url }}
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs');
+ await main();
+ - name: Parse agent logs for step summary
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs');
+ await main();
+ - name: Parse MCP Gateway logs for step summary
+ if: always()
+ id: parse-mcp-gateway
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs');
+ await main();
+ - name: Print firewall logs
+ if: always()
+ continue-on-error: true
+ env:
+ AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
+ run: |
+ # Fix permissions on firewall logs/audit dirs so they can be uploaded as artifacts
+ # AWF runs with sudo, creating files owned by root
+ sudo chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
+ # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
+ if command -v awf &> /dev/null; then
+ awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
+ else
+ echo 'AWF binary not installed, skipping firewall log summary'
+ fi
+ - name: Parse token usage for step summary
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs');
+ await main();
+ - name: Print AWF reflect summary
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs');
+ await main();
+ - name: Write agent output placeholder if missing
+ if: always()
+ run: |
+ if [ ! -f /tmp/gh-aw/agent_output.json ]; then
+ echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
+ fi
+ - name: Upload agent artifacts
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: agent
+ path: |
+ /tmp/gh-aw/aw-prompts/prompt.txt
+ /tmp/gh-aw/sandbox/agent/logs/
+ /tmp/gh-aw/redacted-urls.log
+ /tmp/gh-aw/mcp-logs/
+ /tmp/gh-aw/proxy-logs/
+ !/tmp/gh-aw/proxy-logs/proxy-tls/
+ /tmp/gh-aw/agent_usage.json
+ /tmp/gh-aw/agent-stdio.log
+ /tmp/gh-aw/pre-agent-audit.txt
+ /tmp/gh-aw/agent/
+ /tmp/gh-aw/github_rate_limits.jsonl
+ /tmp/gh-aw/safeoutputs.jsonl
+ /tmp/gh-aw/agent_output.json
+ /tmp/gh-aw/aw-*.patch
+ /tmp/gh-aw/aw-*.bundle
+ /tmp/gh-aw/awf-config.json
+ /tmp/gh-aw/sandbox/firewall/logs/
+ /tmp/gh-aw/sandbox/firewall/audit/
+ /tmp/gh-aw/sandbox/firewall/awf-reflect.json
+ if-no-files-found: ignore
+
+ conclusion:
+ needs:
+ - activation
+ - agent
+ - detection
+ - safe_outputs
+ if: >
+ always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
+ needs.activation.outputs.stale_lock_file_failed == 'true')
+ runs-on: ubuntu-slim
+ permissions:
+ contents: read
+ discussions: write
+ issues: write
+ pull-requests: write
+ concurrency:
+ group: "gh-aw-conclusion-daily-issue-triage"
+ cancel-in-progress: false
+ queue: max
+ outputs:
+ incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }}
+ noop_message: ${{ steps.noop.outputs.noop_message }}
+ tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
+ total_count: ${{ steps.missing_tool.outputs.total_count }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Daily Issue Triage"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-issue-triage.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.52"
+ GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_BODY_MODIFIED: "false"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Download agent output artifact
+ id: download-agent-output
+ continue-on-error: true
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: agent
+ path: /tmp/gh-aw/
+ - name: Setup agent output environment variable
+ id: setup-agent-output-env
+ if: steps.download-agent-output.outcome == 'success'
+ run: |
+ mkdir -p /tmp/gh-aw/
+ find "/tmp/gh-aw/" -type f -print
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+ - name: Process no-op messages
+ id: noop
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_NOOP_MAX: "1"
+ GH_AW_WORKFLOW_NAME: "Daily Issue Triage"
+ GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/daily-issue-triage.md@d7c1dc4b72b00607a67caaffdcc216cb64379cf9"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/d7c1dc4b72b00607a67caaffdcc216cb64379cf9/workflows/daily-issue-triage.md"
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
+ GH_AW_NOOP_REPORT_AS_ISSUE: "true"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs');
+ await main();
+ - name: Log detection run
+ id: detection_runs
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_WORKFLOW_NAME: "Daily Issue Triage"
+ GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/daily-issue-triage.md@d7c1dc4b72b00607a67caaffdcc216cb64379cf9"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/d7c1dc4b72b00607a67caaffdcc216cb64379cf9/workflows/daily-issue-triage.md"
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
+ GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs');
+ await main();
+ - name: Record missing tool
+ id: missing_tool
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_MISSING_TOOL_CREATE_ISSUE: "true"
+ GH_AW_WORKFLOW_NAME: "Daily Issue Triage"
+ GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/daily-issue-triage.md@d7c1dc4b72b00607a67caaffdcc216cb64379cf9"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/d7c1dc4b72b00607a67caaffdcc216cb64379cf9/workflows/daily-issue-triage.md"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs');
+ await main();
+ - name: Record incomplete
+ id: report_incomplete
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true"
+ GH_AW_WORKFLOW_NAME: "Daily Issue Triage"
+ GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/daily-issue-triage.md@d7c1dc4b72b00607a67caaffdcc216cb64379cf9"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/d7c1dc4b72b00607a67caaffdcc216cb64379cf9/workflows/daily-issue-triage.md"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs');
+ await main();
+ - name: Handle agent failure
+ id: handle_agent_failure
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_WORKFLOW_NAME: "Daily Issue Triage"
+ GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/daily-issue-triage.md@d7c1dc4b72b00607a67caaffdcc216cb64379cf9"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/d7c1dc4b72b00607a67caaffdcc216cb64379cf9/workflows/daily-issue-triage.md"
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
+ GH_AW_WORKFLOW_ID: "daily-issue-triage"
+ GH_AW_ACTION_FAILURE_ISSUE_EXPIRES_HOURS: "168"
+ GH_AW_ENGINE_ID: "copilot"
+ GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
+ GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
+ GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens || '' }}
+ GH_AW_EFFECTIVE_TOKENS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.effective_tokens_rate_limit_error || 'false' }}
+ GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
+ GH_AW_MCP_POLICY_ERROR: ${{ needs.agent.outputs.mcp_policy_error }}
+ GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }}
+ GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }}
+ GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com"
+ GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
+ GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
+ GH_AW_GROUP_REPORTS: "false"
+ GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
+ GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
+ GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true"
+ GH_AW_TIMEOUT_MINUTES: "60"
+ GH_AW_MAX_EFFECTIVE_TOKENS: "25000000"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs');
+ await main();
+
+ detection:
+ needs:
+ - activation
+ - agent
+ if: >
+ always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ outputs:
+ detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
+ detection_reason: ${{ steps.detection_conclusion.outputs.reason }}
+ detection_success: ${{ steps.detection_conclusion.outputs.success }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Daily Issue Triage"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-issue-triage.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.52"
+ GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_BODY_MODIFIED: "false"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Download agent output artifact
+ id: download-agent-output
+ continue-on-error: true
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: agent
+ path: /tmp/gh-aw/
+ - name: Setup agent output environment variable
+ id: setup-agent-output-env
+ if: steps.download-agent-output.outcome == 'success'
+ run: |
+ mkdir -p /tmp/gh-aw/
+ find "/tmp/gh-aw/" -type f -print
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+ - name: Checkout repository for patch context
+ if: needs.agent.outputs.has_patch == 'true'
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+ # --- Threat Detection ---
+ - name: Clean stale firewall files from agent artifact
+ run: |
+ rm -rf /tmp/gh-aw/sandbox/firewall/logs
+ rm -rf /tmp/gh-aw/sandbox/firewall/audit
+ - name: Download container images
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.55@sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55@sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3 ghcr.io/github/gh-aw-firewall/squid:0.25.55@sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca
+ - name: Check if detection needed
+ id: detection_guard
+ if: always()
+ env:
+ OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
+ HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
+ run: |
+ if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
+ echo "run_detection=true" >> "$GITHUB_OUTPUT"
+ echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
+ else
+ echo "run_detection=false" >> "$GITHUB_OUTPUT"
+ echo "Detection skipped: no agent outputs or patches to analyze"
+ fi
+ - name: Clear MCP Config for detection
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ run: |
+ rm -f "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json"
+ rm -f /home/runner/.copilot/mcp-config.json
+ rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
+ - name: Prepare threat detection files
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ run: |
+ mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
+ cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
+ cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true
+ for f in /tmp/gh-aw/aw-*.patch; do
+ [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+ done
+ for f in /tmp/gh-aw/aw-*.bundle; do
+ [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+ done
+ echo "Prepared threat detection files:"
+ ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+ - name: Setup threat detection
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ WORKFLOW_NAME: "Daily Issue Triage"
+ WORKFLOW_DESCRIPTION: "Scheduled daily triage that processes untriaged CloudStack issues in batches.\nDetects duplicates, filters spam, and assigns CloudStack-specific labels\n(type:*, component:*, Severity:*, status:*), then posts a structured triage report."
+ HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs');
+ await main();
+ - name: Ensure threat-detection directory and log
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ run: |
+ mkdir -p /tmp/gh-aw/threat-detection
+ touch /tmp/gh-aw/threat-detection/detection.log
+ - name: Setup Node.js
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ with:
+ node-version: '24'
+ package-manager-cache: false
+ - name: Install GitHub Copilot CLI
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.52
+ env:
+ GH_HOST: github.com
+ - name: Install AWF binary
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55
+ - name: Execute GitHub Copilot CLI
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ continue-on-error: true
+ id: detection_agentic_execution
+ # Copilot CLI tool arguments (sorted):
+ timeout-minutes: 20
+ run: |
+ set -o pipefail
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
+ touch /tmp/gh-aw/agent-step-summary.md
+ GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
+ export GH_AW_NODE_BIN
+ export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
+ (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
+ printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/awf-config.schema.json","network":{"allowDomains":["api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","github.com","host.docker.internal","telemetry.enterprise.githubcopilot.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000},"container":{"imageTag":"0.25.55"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ fi
+ # shellcheck disable=SC1003
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ env:
+ AWF_REFLECT_ENABLED: 1
+ COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+ COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_PHASE: detection
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_VERSION: v0.76.1
+ GITHUB_API_URL: ${{ github.api_url }}
+ GITHUB_AW: true
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
+ GITHUB_HEAD_REF: ${{ github.head_ref }}
+ GITHUB_REF_NAME: ${{ github.ref_name }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
+ GITHUB_WORKSPACE: ${{ github.workspace }}
+ GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
+ GIT_AUTHOR_NAME: github-actions[bot]
+ GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
+ GIT_COMMITTER_NAME: github-actions[bot]
+ XDG_CONFIG_HOME: /home/runner
+ - name: Upload threat detection log
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: detection
+ path: /tmp/gh-aw/threat-detection/detection.log
+ if-no-files-found: ignore
+ - name: Parse and conclude threat detection
+ id: detection_conclusion
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
+ DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }}
+ GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
+ with:
+ script: |
+ try {
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
+ await main();
+ } catch (loadErr) {
+ const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false';
+ const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure';
+ const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr));
+ core.error(msg);
+ core.setOutput('reason', 'parse_error');
+ if (continueOnError && !detectionExecutionFailed) {
+ core.warning('\u26A0\uFE0F ' + msg);
+ core.setOutput('conclusion', 'warning');
+ core.setOutput('success', 'false');
+ } else {
+ core.setOutput('conclusion', 'failure');
+ core.setOutput('success', 'false');
+ core.setFailed(msg);
+ }
+ }
+
+ safe_outputs:
+ needs:
+ - activation
+ - agent
+ - detection
+ if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
+ runs-on: ubuntu-slim
+ permissions:
+ contents: read
+ discussions: write
+ issues: write
+ pull-requests: write
+ timeout-minutes: 15
+ env:
+ GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/daily-issue-triage"
+ GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
+ GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
+ GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
+ GH_AW_ENGINE_ID: "copilot"
+ GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
+ GH_AW_ENGINE_VERSION: "1.0.52"
+ GH_AW_WORKFLOW_ID: "daily-issue-triage"
+ GH_AW_WORKFLOW_NAME: "Daily Issue Triage"
+ GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/daily-issue-triage.md@d7c1dc4b72b00607a67caaffdcc216cb64379cf9"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/d7c1dc4b72b00607a67caaffdcc216cb64379cf9/workflows/daily-issue-triage.md"
+ outputs:
+ code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
+ code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
+ comment_id: ${{ steps.process_safe_outputs.outputs.comment_id }}
+ comment_url: ${{ steps.process_safe_outputs.outputs.comment_url }}
+ create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
+ create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
+ process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
+ process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Daily Issue Triage"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-issue-triage.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.52"
+ GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_BODY_MODIFIED: "false"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Download agent output artifact
+ id: download-agent-output
+ continue-on-error: true
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: agent
+ path: /tmp/gh-aw/
+ - name: Setup agent output environment variable
+ id: setup-agent-output-env
+ if: steps.download-agent-output.outcome == 'success'
+ run: |
+ mkdir -p /tmp/gh-aw/
+ find "/tmp/gh-aw/" -type f -print
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+ - name: Configure GH_HOST for enterprise compatibility
+ id: ghes-host-config
+ shell: bash
+ run: |
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
+ GH_HOST="${GH_HOST#http://}"
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+ - name: Process Safe Outputs
+ id: process_safe_outputs
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }}
+ GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_API_URL: ${{ github.api_url }}
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":10,\"target\":\"*\"},\"add_labels\":{\"max\":10,\"target\":\"*\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs');
+ await main();
+ - name: Upload Safe Outputs Items
+ if: always()
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: safe-outputs-items
+ path: |
+ /tmp/gh-aw/safe-output-items.jsonl
+ /tmp/gh-aw/temporary-id-map.json
+ if-no-files-found: ignore
diff --git a/.github/workflows/daily-issue-triage.md b/.github/workflows/daily-issue-triage.md
new file mode 100644
index 000000000000..719dca1f3c63
--- /dev/null
+++ b/.github/workflows/daily-issue-triage.md
@@ -0,0 +1,171 @@
+---
+description: |
+ Scheduled daily triage that processes untriaged CloudStack issues in batches.
+ Detects duplicates, filters spam, and assigns CloudStack-specific labels
+ (type:*, component:*, Severity:*, status:*), then posts a structured triage report.
+
+name: Daily Issue Triage
+
+on:
+ schedule: daily around 14:00 on weekdays
+ workflow_dispatch:
+
+permissions: read-all
+
+network: defaults
+
+safe-outputs:
+ add-labels:
+ target: "*"
+ max: 10
+ add-comment:
+ target: "*"
+ max: 10
+
+tools:
+ web-fetch:
+ github:
+ toolsets: [issues, labels]
+ min-integrity: none
+
+source: githubnext/agentics/workflows/daily-issue-triage.md@d7c1dc4b72b00607a67caaffdcc216cb64379cf9
+timeout-minutes: 60
+---
+
+# Daily Issue Triage
+
+
+
+You are a batch triage assistant for GitHub issues in **${{ github.repository }}** (Apache CloudStack). Your task is to find untriaged issues and triage them one by one. Your triage comments are written for maintainers reviewing the triage, not for the issue author.
+
+Do not make assumptions beyond what the issue content supports. Do not invent missing context.
+
+## Step 1: Find untriaged issues
+
+Use the `search_issues` tool to find open issues that need triage. An issue is considered untriaged if it has **no labels applied**.
+
+Query: `repo:${{ github.repository }} is:issue is:open no:label`
+
+Paginate through all results to find untriaged issues. Do not stop at the first page.
+
+From the results, filter out:
+- Issues that already have a triage comment (look for "🎯 Triage report" in comments). **Never retriage an issue that has already been triaged.**
+- Issues created by bots (unless they look like real user issues).
+- Issues that have any labels already applied (even if they weren't applied by this workflow).
+
+Process the **oldest untriaged issues first**. Note: this workflow is capped at 10 label-sets and 10 comments per run, so the backlog will drain over several daily runs — that is intentional.
+
+## Step 2: Fetch labels (once)
+
+Before triaging any issues, fetch the list of labels available in this repository using the `list_labels` tool. Use this live list for all issues in the batch — only apply labels that actually exist in the repository.
+
+CloudStack uses a prefixed label taxonomy. Choose from these families:
+
+- **Type** (pick the single best one): `type:bug`, `type:new-feature`, `type:enhancement`, `type:improvement`, `type:regression`, `type:security`, `type:question`, `type:config`, `type:cleanup`
+- **Component** (apply when clearly identifiable; more than one is allowed): e.g. `component:kvm`, `component:vmware`, `component:XenServer`, `component:api`, `component:UI`, `component:networking`, `component:virtual-router`, `component:management-server`, `component:primary-storage`, `component:secondary-storage`, `component:kubernetes`, `component:database`, and others — use the full list returned by `list_labels`.
+- **Severity** (bugs only, when assessable): `Severity:BLOCKER`, `Severity:Critical`, `Severity:Major`, `Severity:Minor`, `Severity:Trivial`
+- **Duplicate / invalid**: `status:duplicate`, `status:invalid`
+- **Help wanted / newcomer-friendly**: `status:Help-wanted`
+
+## Step 3: Triage each issue
+
+For each untriaged issue, perform the following steps:
+
+### 3a: Gather context
+
+1. Retrieve the full issue content using the `get_issue` tool.
+2. Fetch any comments on the issue using the `get_issue_comments` tool.
+3. Search for similar issues using the `search_issues` tool.
+
+### 3b: Spam and quality check
+
+**Spam and invalid issues:** If the issue is obviously spam, bot-generated, gibberish, or a test issue:
+- Apply the `status:invalid` label.
+- **Do not close the issue** — closing is a human decision. Note in the report that it looks like spam/invalid so a maintainer can act.
+- Move to the next issue.
+
+**Incomplete issues:** If the issue lacks enough detail for meaningful triage, add a comment that politely asks the author to provide the missing information:
+- For bugs: steps to reproduce, expected vs actual behavior, logs/errors, environment details (CloudStack version, hypervisor, etc.).
+- For other issue types: equivalent details that would make the report actionable.
+- Apply a `type:question` label if appropriate.
+- Be specific about what is missing and why it is needed.
+- Move to the next issue.
+
+### 3c: Select labels
+
+- Be cautious with labels; they can trigger automation.
+- Choose a single `type:*` label that best reflects the issue's nature.
+- Add `component:*` label(s) when the affected area is clear from the content.
+- Add a `Severity:*` label for bugs when severity can be reasonably assessed.
+- Do not apply labels that do not exist in the repository.
+- It is better to under-label than to speculatively add labels.
+
+### 3d: Detect duplicates and related issues
+
+- Review the similar issues found in Step 3a.
+- Classify matches as:
+ - **Duplicate** (high confidence): the issue describes the same problem as an existing open issue. Include up to 3.
+ - **Related**: similar domain or adjacent problem, but not a duplicate. Include up to 3.
+- If a high-confidence duplicate is found, apply the `status:duplicate` label.
+- If no similar issues are found, state that explicitly in your report.
+
+### 3e: Assess coding agent suitability
+
+Assess whether the issue is suitable for automated coding agent assignment:
+- **Suitable**: clear requirements, sufficient context, well-defined success criteria, self-contained scope.
+- **Needs more info**: potentially suitable but missing details needed to start.
+- **Not suitable**: requires investigation, design decisions, extensive coordination, or policy/architectural choices.
+
+### 3f: Additional analysis
+
+- Search the web for relevant documentation, error messages, or known solutions if applicable.
+- Write notes, debugging strategies, and/or reproduction steps relevant to the issue.
+- Suggest resources or links that might help resolve the issue.
+
+### 3g: Apply results and post comment
+
+Apply all triage results for this issue:
+- Use `update_issue` to apply the chosen labels.
+- Add an issue comment with the triage report using the format below.
+
+Then move to the next issue.
+
+## Processing order
+
+1. Fetch available labels (Step 2, once at the start).
+2. Find untriaged issues (Step 1).
+3. For each issue (oldest first), run Step 3 (gather, check, label, detect duplicates, comment).
+
+## Comment format
+
+Use this structure for each triage comment. Use collapsed sections to keep it tidy.
+
+```markdown
+## 🎯 Triage report
+
+{2-3 sentence summary to help a maintainer quickly grasp the issue.}
+
+### 📊 Assessment
+
+| Dimension | Value | Reasoning |
+|---|---|---|
+| **Type** | [type:* label or "none"] | [brief] |
+| **Component** | [component:* label(s) or "none"] | [brief] |
+| **Severity** | [Severity:* label or "n/a"] | [brief] |
+| **Labels** | [all labels applied or "none"] | [brief] |
+| **Coding agent** | [Suitable / Needs more info / Not suitable] | [brief] |
+
+### 🔗 Similar issues
+
+- issue-url (duplicate/related) — [brief explanation]
+
+💡 Notes and suggestions
+
+{Debugging strategies, reproduction steps, resource links, sub-task checklists, nudges for the team.}
+
+
+```
+
+If no similar issues were found, omit the "Similar issues" section. If there are no notes to add, omit the collapsed section.
+
+**Important**: Never close issues. Only apply labels and post comments.
diff --git a/.github/workflows/daily-repo-status.lock.yml b/.github/workflows/daily-repo-status.lock.yml
new file mode 100644
index 000000000000..0992d3b67de0
--- /dev/null
+++ b/.github/workflows/daily-repo-status.lock.yml
@@ -0,0 +1,1394 @@
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"bcecce6f1d9f8df2b3eca9eb7bb1fdbac13c396c240a2dc802a96546f435b969","compiler_version":"v0.76.1","strict":true,"agent_id":"copilot","agent_model":"claude-haiku-4.5"}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"46d564922b082d0db93244972e8005ea6904ee5f","version":"v0.76.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55","digest":"sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55@sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55","digest":"sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55@sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55","digest":"sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55@sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.19","digest":"sha256:a6c890d7c24d7190c9ef97b9c954cc4cffaae6b01c371ced1f959f1370b1f68f","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.19@sha256:a6c890d7c24d7190c9ef97b9c954cc4cffaae6b01c371ced1f959f1370b1f68f"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14","pinned_image":"node:lts-alpine@sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14"}]}
+# ___ _ _
+# / _ \ | | (_)
+# | |_| | __ _ ___ _ __ | |_ _ ___
+# | _ |/ _` |/ _ \ '_ \| __| |/ __|
+# | | | | (_| | __/ | | | |_| | (__
+# \_| |_/\__, |\___|_| |_|\__|_|\___|
+# __/ |
+# _ _ |___/
+# | | | | / _| |
+# | | | | ___ _ __ _ __| |_| | _____ ____
+# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___|
+# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
+# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
+#
+# This file was automatically generated by gh-aw (v0.76.1). DO NOT EDIT.
+#
+# To update this file, edit githubnext/agentics/workflows/repo-status.md@main and run:
+# gh aw compile
+# Not all edits will cause changes to this file.
+#
+# For more information: https://github.github.com/gh-aw/introduction/overview/
+#
+# This workflow creates daily repo status reports. It gathers recent repository
+# activity (issues, PRs, discussions, releases, code changes) and generates
+# engaging GitHub issues with productivity insights, community highlights,
+# and project recommendations.
+#
+# Source: githubnext/agentics/workflows/repo-status.md@main
+#
+# Secrets used:
+# - COPILOT_GITHUB_TOKEN
+# - GH_AW_GITHUB_MCP_SERVER_TOKEN
+# - GH_AW_GITHUB_TOKEN
+# - GITHUB_TOKEN
+#
+# Custom actions used:
+# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+# - github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+#
+# Container images used:
+# - ghcr.io/github/gh-aw-firewall/agent:0.25.55@sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55@sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3
+# - ghcr.io/github/gh-aw-firewall/squid:0.25.55@sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca
+# - ghcr.io/github/gh-aw-mcpg:v0.3.19@sha256:a6c890d7c24d7190c9ef97b9c954cc4cffaae6b01c371ced1f959f1370b1f68f
+# - ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4
+# - node:lts-alpine@sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14
+
+name: "Repo Status"
+on:
+ schedule:
+ - cron: "11 19 * * *"
+ # Friendly format: daily (scattered)
+ workflow_dispatch:
+ inputs:
+ aw_context:
+ default: ""
+ description: "Agent caller context (used internally by Agentic Workflows)."
+ required: false
+ type: string
+
+permissions: {}
+
+concurrency:
+ group: "gh-aw-${{ github.workflow }}"
+
+run-name: "Repo Status"
+
+jobs:
+ activation:
+ runs-on: ubuntu-slim
+ permissions:
+ actions: read
+ contents: read
+ outputs:
+ comment_id: ""
+ comment_repo: ""
+ engine_id: ${{ steps.generate_aw_info.outputs.engine_id }}
+ lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
+ model: ${{ steps.generate_aw_info.outputs.model }}
+ secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Repo Status"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-repo-status.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.52"
+ GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_BODY_MODIFIED: "false"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Generate agentic run info
+ id: generate_aw_info
+ env:
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
+ GH_AW_INFO_MODEL: "claude-haiku-4.5"
+ GH_AW_INFO_VERSION: "1.0.52"
+ GH_AW_INFO_AGENT_VERSION: "1.0.52"
+ GH_AW_INFO_CLI_VERSION: "v0.76.1"
+ GH_AW_INFO_WORKFLOW_NAME: "Repo Status"
+ GH_AW_INFO_EXPERIMENTAL: "false"
+ GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
+ GH_AW_INFO_STAGED: "false"
+ GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
+ GH_AW_INFO_FIREWALL_ENABLED: "true"
+ GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_AWMG_VERSION: ""
+ GH_AW_INFO_FIREWALL_TYPE: "squid"
+ GH_AW_INFO_FRONTMATTER_SOURCE: "githubnext/agentics/workflows/repo-status.md@main"
+ GH_AW_INFO_BODY_MODIFIED: "false"
+ GH_AW_COMPILED_STRICT: "true"
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
+ await main(core, context);
+ - name: Validate COPILOT_GITHUB_TOKEN secret
+ id: validate-secret
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh" COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
+ env:
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ - name: Checkout .github and .agents folders
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+ sparse-checkout: |
+ .github
+ .agents
+ .antigravity
+ .claude
+ .codex
+ .crush
+ .gemini
+ .opencode
+ .pi
+ sparse-checkout-cone-mode: true
+ fetch-depth: 1
+ - name: Save agent config folders for base branch restoration
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi"
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
+ # poutine:ignore untrusted_checkout_exec
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh"
+ - name: Check workflow lock file
+ id: check-lock-file
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_WORKFLOW_FILE: "daily-repo-status.lock.yml"
+ GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}"
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
+ await main();
+ - name: Check compile-agentic version
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_COMPILED_VERSION: "v0.76.1"
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs');
+ await main();
+ - name: Create prompt with built-in context
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl
+ GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+ # poutine:ignore untrusted_checkout_exec
+ run: |
+ bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
+ {
+ cat << 'GH_AW_PROMPT_eeb322738661ed58_EOF'
+
+ GH_AW_PROMPT_eeb322738661ed58_EOF
+ cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
+ cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
+ cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
+ cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
+ cat << 'GH_AW_PROMPT_eeb322738661ed58_EOF'
+
+ Tools: create_issue, missing_tool, missing_data, noop
+
+ GH_AW_PROMPT_eeb322738661ed58_EOF
+ cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
+ cat << 'GH_AW_PROMPT_eeb322738661ed58_EOF'
+
+ The following GitHub context information is available for this workflow:
+ {{#if github.actor}}
+ - **actor**: __GH_AW_GITHUB_ACTOR__
+ {{/if}}
+ {{#if github.repository}}
+ - **repository**: __GH_AW_GITHUB_REPOSITORY__
+ {{/if}}
+ {{#if github.workspace}}
+ - **workspace**: __GH_AW_GITHUB_WORKSPACE__
+ {{/if}}
+ {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}
+ - **issue-number**: #__GH_AW_EXPR_802A9F6A__
+ {{/if}}
+ {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}
+ - **discussion-number**: #__GH_AW_EXPR_1A3A194A__
+ {{/if}}
+ {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}
+ - **pull-request-number**: #__GH_AW_EXPR_463A214A__
+ {{/if}}
+ {{#if github.event.comment.id || github.aw.context.comment_id}}
+ - **comment-id**: __GH_AW_EXPR_FF1D34CE__
+ {{/if}}
+ {{#if github.run_id}}
+ - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
+ {{/if}}
+
+
+ GH_AW_PROMPT_eeb322738661ed58_EOF
+ cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
+ cat << 'GH_AW_PROMPT_eeb322738661ed58_EOF'
+
+ {{#runtime-import .github/workflows/daily-repo-status.md}}
+ GH_AW_PROMPT_eeb322738661ed58_EOF
+ } > "$GH_AW_PROMPT"
+ - name: Interpolate variables and render templates
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_ENGINE_ID: "copilot"
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs');
+ await main();
+ - name: Substitute placeholders
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+ GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+
+ const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs');
+
+ // Call the substitution function
+ return await substitutePlaceholders({
+ file: process.env.GH_AW_PROMPT,
+ substitutions: {
+ GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A,
+ GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A,
+ GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A,
+ GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE,
+ GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
+ GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
+ GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
+ GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
+ GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST
+ }
+ });
+ - name: Validate prompt placeholders
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ # poutine:ignore untrusted_checkout_exec
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh"
+ - name: Print prompt
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ # poutine:ignore untrusted_checkout_exec
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh"
+ - name: Upload activation artifact
+ if: success()
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: activation
+ include-hidden-files: true
+ path: |
+ /tmp/gh-aw/aw_info.json
+ /tmp/gh-aw/aw-prompts/prompt.txt
+ /tmp/gh-aw/aw-prompts/prompt-template.txt
+ /tmp/gh-aw/aw-prompts/prompt-import-tree.json
+ /tmp/gh-aw/github_rate_limits.jsonl
+ /tmp/gh-aw/base
+ /tmp/gh-aw/.github/agents
+ /tmp/gh-aw/.github/skills
+ if-no-files-found: ignore
+ retention-days: 1
+
+ agent:
+ needs: activation
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ issues: read
+ pull-requests: read
+ concurrency:
+ group: "gh-aw-copilot-${{ github.workflow }}"
+ env:
+ DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
+ GH_AW_ASSETS_ALLOWED_EXTS: ""
+ GH_AW_ASSETS_BRANCH: ""
+ GH_AW_ASSETS_MAX_SIZE_KB: 0
+ GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
+ GH_AW_WORKFLOW_ID_SANITIZED: dailyrepostatus
+ outputs:
+ agentic_engine_timeout: ${{ steps.detect-agent-errors.outputs.agentic_engine_timeout || 'false' }}
+ checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
+ effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }}
+ effective_tokens_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.effective_tokens_rate_limit_error || 'false' }}
+ has_patch: ${{ steps.collect_output.outputs.has_patch }}
+ inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }}
+ mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }}
+ model: ${{ needs.activation.outputs.model }}
+ model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }}
+ output: ${{ steps.collect_output.outputs.output }}
+ output_types: ${{ steps.collect_output.outputs.output_types }}
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Repo Status"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-repo-status.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.52"
+ GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_BODY_MODIFIED: "false"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Set runtime paths
+ id: set-runtime-paths
+ run: |
+ {
+ echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl"
+ echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json"
+ echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
+ } >> "$GITHUB_OUTPUT"
+ - name: Checkout repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+ - name: Create gh-aw temp directory
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh"
+ - name: Configure gh CLI for GitHub Enterprise
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh"
+ env:
+ GH_TOKEN: ${{ github.token }}
+ - name: Configure Git credentials
+ env:
+ REPO_NAME: ${{ github.repository }}
+ SERVER_URL: ${{ github.server_url }}
+ GITHUB_TOKEN: ${{ github.token }}
+ run: |
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
+ git config --global user.name "github-actions[bot]"
+ git config --global am.keepcr true
+ # Re-authenticate git with GitHub token
+ SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+ git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+ echo "Git configured with standard GitHub Actions identity"
+ - name: Checkout PR branch
+ id: checkout-pr
+ if: |
+ github.event.pull_request || github.event.issue.pull_request
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
+ await main();
+ - name: Install GitHub Copilot CLI
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.52
+ env:
+ GH_HOST: github.com
+ - name: Install AWF binary
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55
+ - name: Parse integrity filter lists
+ id: parse-guard-vars
+ env:
+ GH_AW_BLOCKED_USERS_VAR: ${{ vars.GH_AW_GITHUB_BLOCKED_USERS || '' }}
+ GH_AW_TRUSTED_USERS_VAR: ${{ vars.GH_AW_GITHUB_TRUSTED_USERS || '' }}
+ GH_AW_APPROVAL_LABELS_VAR: ${{ vars.GH_AW_GITHUB_APPROVAL_LABELS || '' }}
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/parse_guard_list.sh"
+ - name: Download activation artifact
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: activation
+ path: /tmp/gh-aw
+ - name: Restore agent config folders from base branch
+ if: steps.checkout-pr.outcome == 'success'
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi"
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh"
+ - name: Restore inline sub-agents from activation artifact
+ env:
+ GH_AW_SUB_AGENT_DIR: ".github/agents"
+ GH_AW_SUB_AGENT_EXT: ".agent.md"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh"
+ - name: Restore inline skills from activation artifact
+ env:
+ GH_AW_SKILL_DIR: ".github/skills"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh"
+ - name: Download container images
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.55@sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55@sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3 ghcr.io/github/gh-aw-firewall/squid:0.25.55@sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca ghcr.io/github/gh-aw-mcpg:v0.3.19@sha256:a6c890d7c24d7190c9ef97b9c954cc4cffaae6b01c371ced1f959f1370b1f68f ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14
+ - name: Generate Safe Outputs Config
+ run: |
+ mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
+ mkdir -p /tmp/gh-aw/safeoutputs
+ mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_51571b44da85874d_EOF'
+ {"create_issue":{"close_older_issues":true,"labels":["report","daily-status"],"max":1,"title_prefix":"[repo-status] "},"create_report_incomplete_issue":{},"mentions":{"enabled":false},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_51571b44da85874d_EOF
+ - name: Generate Safe Outputs Tools
+ env:
+ GH_AW_TOOLS_META_JSON: |
+ {
+ "description_suffixes": {
+ "create_issue": " CONSTRAINTS: Maximum 1 issue(s) can be created. Title will be prefixed with \"[repo-status] \". Labels [\"report\" \"daily-status\"] will be automatically added."
+ },
+ "repo_params": {},
+ "dynamic_tools": []
+ }
+ GH_AW_VALIDATION_JSON: |
+ {
+ "create_issue": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "fields": {
+ "type": "array"
+ },
+ "labels": {
+ "type": "array",
+ "itemType": "string",
+ "itemSanitize": true,
+ "itemMaxLength": 128
+ },
+ "parent": {
+ "issueOrPRNumber": true
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ },
+ "temporary_id": {
+ "type": "string"
+ },
+ "title": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 128
+ }
+ }
+ },
+ "missing_data": {
+ "defaultMax": 20,
+ "fields": {
+ "alternatives": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ },
+ "context": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ },
+ "data_type": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 128
+ },
+ "reason": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ }
+ }
+ },
+ "missing_tool": {
+ "defaultMax": 20,
+ "fields": {
+ "alternatives": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 512
+ },
+ "reason": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ },
+ "tool": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 128
+ }
+ }
+ },
+ "noop": {
+ "defaultMax": 1,
+ "fields": {
+ "message": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ }
+ }
+ },
+ "report_incomplete": {
+ "defaultMax": 5,
+ "fields": {
+ "details": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "reason": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 1024
+ }
+ }
+ }
+ }
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
+ await main();
+ - name: Generate Safe Outputs MCP Server Config
+ id: safe-outputs-config
+ run: |
+ # Generate a secure random API key (360 bits of entropy, 40+ chars)
+ # Mask immediately to prevent timing vulnerabilities
+ API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
+ echo "::add-mask::${API_KEY}"
+
+ PORT=3001
+
+ # Set outputs for next steps
+ {
+ echo "safe_outputs_api_key=${API_KEY}"
+ echo "safe_outputs_port=${PORT}"
+ } >> "$GITHUB_OUTPUT"
+
+ echo "Safe Outputs MCP server will run on port ${PORT}"
+
+ - name: Start Safe Outputs MCP HTTP Server
+ id: safe-outputs-start
+ env:
+ DEBUG: '*'
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
+ GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
+ GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
+ run: |
+ # Environment variables are set above to prevent template injection
+ export DEBUG
+ export GH_AW_SAFE_OUTPUTS
+ export GH_AW_SAFE_OUTPUTS_PORT
+ export GH_AW_SAFE_OUTPUTS_API_KEY
+ export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
+ export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
+ export GH_AW_MCP_LOG_DIR
+
+ bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh"
+
+ - name: Start MCP Gateway
+ id: start-mcp-gateway
+ env:
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
+ GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+ GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ run: |
+ set -eo pipefail
+ mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
+
+ # Export gateway environment variables for MCP config and gateway script
+ export MCP_GATEWAY_PORT="8080"
+ export MCP_GATEWAY_DOMAIN="host.docker.internal"
+ export MCP_GATEWAY_HOST_DOMAIN="localhost"
+ MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
+ echo "::add-mask::${MCP_GATEWAY_API_KEY}"
+ export MCP_GATEWAY_API_KEY
+ export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads"
+ mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}"
+ export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288"
+ export DEBUG="*"
+
+ export GH_AW_ENGINE="copilot"
+ MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
+ MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
+ case "${DOCKER_HOST:-}" in
+ unix://* ) DOCKER_SOCK_PATH="${DOCKER_HOST#unix://}" ;;
+ /* ) DOCKER_SOCK_PATH="$DOCKER_HOST" ;;
+ * ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
+ esac
+ DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.19'
+
+ mkdir -p /home/runner/.copilot
+ GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
+ cat << GH_AW_MCP_CONFIG_4b3a7789a6eea081_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ {
+ "mcpServers": {
+ "github": {
+ "type": "stdio",
+ "container": "ghcr.io/github/github-mcp-server:v1.0.4",
+ "env": {
+ "GITHUB_HOST": "\${GITHUB_SERVER_URL}",
+ "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
+ "GITHUB_READ_ONLY": "1",
+ "GITHUB_TOOLSETS": "context,repos,issues,pull_requests"
+ },
+ "guard-policies": {
+ "allow-only": {
+ "approval-labels": ${{ steps.parse-guard-vars.outputs.approval_labels }},
+ "blocked-users": ${{ steps.parse-guard-vars.outputs.blocked_users }},
+ "min-integrity": "none",
+ "repos": "all",
+ "trusted-users": ${{ steps.parse-guard-vars.outputs.trusted_users }}
+ }
+ }
+ },
+ "safeoutputs": {
+ "type": "http",
+ "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
+ "headers": {
+ "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+ },
+ "guard-policies": {
+ "write-sink": {
+ "accept": [
+ "*"
+ ]
+ }
+ }
+ }
+ },
+ "gateway": {
+ "port": $MCP_GATEWAY_PORT,
+ "domain": "${MCP_GATEWAY_DOMAIN}",
+ "apiKey": "${MCP_GATEWAY_API_KEY}",
+ "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
+ }
+ }
+ GH_AW_MCP_CONFIG_4b3a7789a6eea081_EOF
+ - name: Mount MCP servers as CLIs
+ id: mount-mcp-clis
+ continue-on-error: true
+ env:
+ MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
+ MCP_GATEWAY_DOMAIN: ${{ steps.start-mcp-gateway.outputs.gateway-domain }}
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs');
+ await main();
+ - name: Clean credentials
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh"
+ - name: Audit pre-agent workspace
+ id: pre_agent_audit
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/audit_pre_agent_workspace.sh"
+ - name: Execute GitHub Copilot CLI
+ id: agentic_execution
+ # Copilot CLI tool arguments (sorted):
+ timeout-minutes: 20
+ run: |
+ set -o pipefail
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
+ touch /tmp/gh-aw/agent-step-summary.md
+ GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
+ export GH_AW_NODE_BIN
+ export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
+ (umask 177 && touch /tmp/gh-aw/agent-stdio.log)
+ printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/awf-config.schema.json","network":{"allowDomains":["api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","api.snapcraft.io","archive.ubuntu.com","azure.archive.ubuntu.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","github.com","host.docker.internal","json-schema.org","json.schemastore.org","keyserver.ubuntu.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","ppa.launchpad.net","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"vision":["copilot/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.25.55,squid=sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca,agent=sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731,api-proxy=sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ fi
+ # shellcheck disable=SC1003
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ env:
+ AWF_REFLECT_ENABLED: 1
+ COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+ COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_MODEL: claude-haiku-4.5
+ GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
+ GH_AW_PHASE: agent
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ GH_AW_VERSION: v0.76.1
+ GITHUB_API_URL: ${{ github.api_url }}
+ GITHUB_AW: true
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
+ GITHUB_HEAD_REF: ${{ github.head_ref }}
+ GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ GITHUB_REF_NAME: ${{ github.ref_name }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
+ GITHUB_WORKSPACE: ${{ github.workspace }}
+ GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
+ GIT_AUTHOR_NAME: github-actions[bot]
+ GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
+ GIT_COMMITTER_NAME: github-actions[bot]
+ XDG_CONFIG_HOME: /home/runner
+ - name: Detect agent errors
+ if: always()
+ id: detect-agent-errors
+ continue-on-error: true
+ run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs"
+ - name: Configure Git credentials
+ env:
+ REPO_NAME: ${{ github.repository }}
+ SERVER_URL: ${{ github.server_url }}
+ GITHUB_TOKEN: ${{ github.token }}
+ run: |
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
+ git config --global user.name "github-actions[bot]"
+ git config --global am.keepcr true
+ # Re-authenticate git with GitHub token
+ SERVER_URL_STRIPPED="${SERVER_URL#https://}"
+ git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
+ echo "Git configured with standard GitHub Actions identity"
+ - name: Copy Copilot session state files to logs
+ if: always()
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh"
+ - name: Stop MCP Gateway
+ if: always()
+ continue-on-error: true
+ env:
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
+ MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
+ GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }}
+ run: |
+ bash "${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh" "$GATEWAY_PID"
+ - name: Redact secrets in logs
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
+ await main();
+ env:
+ GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+ SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
+ SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
+ SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: Append agent step summary
+ if: always()
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh"
+ - name: Copy Safe Outputs
+ if: always()
+ env:
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ run: |
+ mkdir -p /tmp/gh-aw
+ cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true
+ - name: Ingest agent output
+ id: collect_output
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
+ GH_AW_ALLOWED_GITHUB_REFS: ""
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_API_URL: ${{ github.api_url }}
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs');
+ await main();
+ - name: Parse agent logs for step summary
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs');
+ await main();
+ - name: Parse MCP Gateway logs for step summary
+ if: always()
+ id: parse-mcp-gateway
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs');
+ await main();
+ - name: Print firewall logs
+ if: always()
+ continue-on-error: true
+ env:
+ AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
+ run: |
+ # Fix permissions on firewall logs/audit dirs so they can be uploaded as artifacts
+ # AWF runs with sudo, creating files owned by root
+ sudo chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
+ # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
+ if command -v awf &> /dev/null; then
+ awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
+ else
+ echo 'AWF binary not installed, skipping firewall log summary'
+ fi
+ - name: Parse token usage for step summary
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs');
+ await main();
+ - name: Print AWF reflect summary
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs');
+ await main();
+ - name: Write agent output placeholder if missing
+ if: always()
+ run: |
+ if [ ! -f /tmp/gh-aw/agent_output.json ]; then
+ echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
+ fi
+ - name: Upload agent artifacts
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: agent
+ path: |
+ /tmp/gh-aw/aw-prompts/prompt.txt
+ /tmp/gh-aw/sandbox/agent/logs/
+ /tmp/gh-aw/redacted-urls.log
+ /tmp/gh-aw/mcp-logs/
+ /tmp/gh-aw/proxy-logs/
+ !/tmp/gh-aw/proxy-logs/proxy-tls/
+ /tmp/gh-aw/agent_usage.json
+ /tmp/gh-aw/agent-stdio.log
+ /tmp/gh-aw/pre-agent-audit.txt
+ /tmp/gh-aw/agent/
+ /tmp/gh-aw/github_rate_limits.jsonl
+ /tmp/gh-aw/safeoutputs.jsonl
+ /tmp/gh-aw/agent_output.json
+ /tmp/gh-aw/aw-*.patch
+ /tmp/gh-aw/aw-*.bundle
+ /tmp/gh-aw/awf-config.json
+ /tmp/gh-aw/sandbox/firewall/logs/
+ /tmp/gh-aw/sandbox/firewall/audit/
+ /tmp/gh-aw/sandbox/firewall/awf-reflect.json
+ if-no-files-found: ignore
+
+ conclusion:
+ needs:
+ - activation
+ - agent
+ - detection
+ - safe_outputs
+ if: >
+ always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
+ needs.activation.outputs.stale_lock_file_failed == 'true')
+ runs-on: ubuntu-slim
+ permissions:
+ contents: read
+ issues: write
+ concurrency:
+ group: "gh-aw-conclusion-daily-repo-status"
+ cancel-in-progress: false
+ queue: max
+ outputs:
+ incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }}
+ noop_message: ${{ steps.noop.outputs.noop_message }}
+ tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
+ total_count: ${{ steps.missing_tool.outputs.total_count }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Repo Status"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-repo-status.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.52"
+ GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_BODY_MODIFIED: "false"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Download agent output artifact
+ id: download-agent-output
+ continue-on-error: true
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: agent
+ path: /tmp/gh-aw/
+ - name: Setup agent output environment variable
+ id: setup-agent-output-env
+ if: steps.download-agent-output.outcome == 'success'
+ run: |
+ mkdir -p /tmp/gh-aw/
+ find "/tmp/gh-aw/" -type f -print
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+ - name: Process no-op messages
+ id: noop
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_NOOP_MAX: "1"
+ GH_AW_WORKFLOW_NAME: "Repo Status"
+ GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-status.md@main"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/main/workflows/repo-status.md"
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
+ GH_AW_NOOP_REPORT_AS_ISSUE: "true"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs');
+ await main();
+ - name: Log detection run
+ id: detection_runs
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_WORKFLOW_NAME: "Repo Status"
+ GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-status.md@main"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/main/workflows/repo-status.md"
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
+ GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs');
+ await main();
+ - name: Record missing tool
+ id: missing_tool
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_MISSING_TOOL_CREATE_ISSUE: "true"
+ GH_AW_WORKFLOW_NAME: "Repo Status"
+ GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-status.md@main"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/main/workflows/repo-status.md"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs');
+ await main();
+ - name: Record incomplete
+ id: report_incomplete
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true"
+ GH_AW_WORKFLOW_NAME: "Repo Status"
+ GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-status.md@main"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/main/workflows/repo-status.md"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs');
+ await main();
+ - name: Handle agent failure
+ id: handle_agent_failure
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_WORKFLOW_NAME: "Repo Status"
+ GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-status.md@main"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/main/workflows/repo-status.md"
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
+ GH_AW_WORKFLOW_ID: "daily-repo-status"
+ GH_AW_ACTION_FAILURE_ISSUE_EXPIRES_HOURS: "168"
+ GH_AW_ENGINE_ID: "copilot"
+ GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
+ GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
+ GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens || '' }}
+ GH_AW_EFFECTIVE_TOKENS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.effective_tokens_rate_limit_error || 'false' }}
+ GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
+ GH_AW_MCP_POLICY_ERROR: ${{ needs.agent.outputs.mcp_policy_error }}
+ GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }}
+ GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }}
+ GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com"
+ GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
+ GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
+ GH_AW_GROUP_REPORTS: "false"
+ GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
+ GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
+ GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true"
+ GH_AW_TIMEOUT_MINUTES: "20"
+ GH_AW_MAX_EFFECTIVE_TOKENS: "25000000"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs');
+ await main();
+
+ detection:
+ needs:
+ - activation
+ - agent
+ if: >
+ always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ outputs:
+ detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
+ detection_reason: ${{ steps.detection_conclusion.outputs.reason }}
+ detection_success: ${{ steps.detection_conclusion.outputs.success }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Repo Status"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-repo-status.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.52"
+ GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_BODY_MODIFIED: "false"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Download agent output artifact
+ id: download-agent-output
+ continue-on-error: true
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: agent
+ path: /tmp/gh-aw/
+ - name: Setup agent output environment variable
+ id: setup-agent-output-env
+ if: steps.download-agent-output.outcome == 'success'
+ run: |
+ mkdir -p /tmp/gh-aw/
+ find "/tmp/gh-aw/" -type f -print
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+ - name: Checkout repository for patch context
+ if: needs.agent.outputs.has_patch == 'true'
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+ # --- Threat Detection ---
+ - name: Clean stale firewall files from agent artifact
+ run: |
+ rm -rf /tmp/gh-aw/sandbox/firewall/logs
+ rm -rf /tmp/gh-aw/sandbox/firewall/audit
+ - name: Download container images
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.55@sha256:138c363411decc9a61a5af9b95e8d64c76648b00add0ba06fc7ba786f0e72731 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55@sha256:4142b873b678cd3279b98dcbe464857d56ea2f2348719b00379cdf35dd843ff3 ghcr.io/github/gh-aw-firewall/squid:0.25.55@sha256:74084b704d8d3664a363655986664d70bd9cdb4830532d0b35cd784d867aabca
+ - name: Check if detection needed
+ id: detection_guard
+ if: always()
+ env:
+ OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
+ HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
+ run: |
+ if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
+ echo "run_detection=true" >> "$GITHUB_OUTPUT"
+ echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
+ else
+ echo "run_detection=false" >> "$GITHUB_OUTPUT"
+ echo "Detection skipped: no agent outputs or patches to analyze"
+ fi
+ - name: Clear MCP Config for detection
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ run: |
+ rm -f "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json"
+ rm -f /home/runner/.copilot/mcp-config.json
+ rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
+ - name: Prepare threat detection files
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ run: |
+ mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
+ cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
+ cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true
+ for f in /tmp/gh-aw/aw-*.patch; do
+ [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+ done
+ for f in /tmp/gh-aw/aw-*.bundle; do
+ [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+ done
+ echo "Prepared threat detection files:"
+ ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
+ - name: Setup threat detection
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ WORKFLOW_NAME: "Repo Status"
+ WORKFLOW_DESCRIPTION: "This workflow creates daily repo status reports. It gathers recent repository\nactivity (issues, PRs, discussions, releases, code changes) and generates\nengaging GitHub issues with productivity insights, community highlights,\nand project recommendations."
+ HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs');
+ await main();
+ - name: Ensure threat-detection directory and log
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ run: |
+ mkdir -p /tmp/gh-aw/threat-detection
+ touch /tmp/gh-aw/threat-detection/detection.log
+ - name: Setup Node.js
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ with:
+ node-version: '24'
+ package-manager-cache: false
+ - name: Install GitHub Copilot CLI
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.52
+ env:
+ GH_HOST: github.com
+ - name: Install AWF binary
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55
+ - name: Execute GitHub Copilot CLI
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ continue-on-error: true
+ id: detection_agentic_execution
+ # Copilot CLI tool arguments (sorted):
+ timeout-minutes: 20
+ run: |
+ set -o pipefail
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
+ touch /tmp/gh-aw/agent-step-summary.md
+ GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
+ export GH_AW_NODE_BIN
+ export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
+ (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
+ printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/awf-config.schema.json","network":{"allowDomains":["api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","github.com","host.docker.internal","telemetry.enterprise.githubcopilot.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000},"container":{"imageTag":"0.25.55"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ fi
+ # shellcheck disable=SC1003
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ env:
+ AWF_REFLECT_ENABLED: 1
+ COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+ COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_MODEL: claude-haiku-4.5
+ GH_AW_PHASE: detection
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_VERSION: v0.76.1
+ GITHUB_API_URL: ${{ github.api_url }}
+ GITHUB_AW: true
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
+ GITHUB_HEAD_REF: ${{ github.head_ref }}
+ GITHUB_REF_NAME: ${{ github.ref_name }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
+ GITHUB_WORKSPACE: ${{ github.workspace }}
+ GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
+ GIT_AUTHOR_NAME: github-actions[bot]
+ GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
+ GIT_COMMITTER_NAME: github-actions[bot]
+ XDG_CONFIG_HOME: /home/runner
+ - name: Upload threat detection log
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: detection
+ path: /tmp/gh-aw/threat-detection/detection.log
+ if-no-files-found: ignore
+ - name: Parse and conclude threat detection
+ id: detection_conclusion
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
+ DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }}
+ GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
+ with:
+ script: |
+ try {
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
+ await main();
+ } catch (loadErr) {
+ const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false';
+ const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure';
+ const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr));
+ core.error(msg);
+ core.setOutput('reason', 'parse_error');
+ if (continueOnError && !detectionExecutionFailed) {
+ core.warning('\u26A0\uFE0F ' + msg);
+ core.setOutput('conclusion', 'warning');
+ core.setOutput('success', 'false');
+ } else {
+ core.setOutput('conclusion', 'failure');
+ core.setOutput('success', 'false');
+ core.setFailed(msg);
+ }
+ }
+
+ safe_outputs:
+ needs:
+ - activation
+ - agent
+ - detection
+ if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
+ runs-on: ubuntu-slim
+ permissions:
+ contents: read
+ issues: write
+ timeout-minutes: 15
+ env:
+ GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/daily-repo-status"
+ GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
+ GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
+ GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
+ GH_AW_ENGINE_ID: "copilot"
+ GH_AW_ENGINE_MODEL: "claude-haiku-4.5"
+ GH_AW_ENGINE_VERSION: "1.0.52"
+ GH_AW_WORKFLOW_ID: "daily-repo-status"
+ GH_AW_WORKFLOW_NAME: "Repo Status"
+ GH_AW_WORKFLOW_SOURCE: "githubnext/agentics/workflows/repo-status.md@main"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/githubnext/agentics/blob/main/workflows/repo-status.md"
+ outputs:
+ code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
+ code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
+ create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
+ create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
+ created_issue_number: ${{ steps.process_safe_outputs.outputs.created_issue_number }}
+ created_issue_url: ${{ steps.process_safe_outputs.outputs.created_issue_url }}
+ process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
+ process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Repo Status"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-repo-status.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.52"
+ GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_BODY_MODIFIED: "false"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Download agent output artifact
+ id: download-agent-output
+ continue-on-error: true
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: agent
+ path: /tmp/gh-aw/
+ - name: Setup agent output environment variable
+ id: setup-agent-output-env
+ if: steps.download-agent-output.outcome == 'success'
+ run: |
+ mkdir -p /tmp/gh-aw/
+ find "/tmp/gh-aw/" -type f -print
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+ - name: Configure GH_HOST for enterprise compatibility
+ id: ghes-host-config
+ shell: bash
+ run: |
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
+ GH_HOST="${GH_HOST#http://}"
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+ - name: Process Safe Outputs
+ id: process_safe_outputs
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }}
+ GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_API_URL: ${{ github.api_url }}
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"close_older_issues\":true,\"labels\":[\"report\",\"daily-status\"],\"max\":1,\"title_prefix\":\"[repo-status] \"},\"create_report_incomplete_issue\":{},\"mentions\":{\"enabled\":false},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs');
+ await main();
+ - name: Upload Safe Outputs Items
+ if: always()
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: safe-outputs-items
+ path: |
+ /tmp/gh-aw/safe-output-items.jsonl
+ /tmp/gh-aw/temporary-id-map.json
+ if-no-files-found: ignore
diff --git a/.github/workflows/daily-repo-status.md b/.github/workflows/daily-repo-status.md
new file mode 100644
index 000000000000..49b553940b8b
--- /dev/null
+++ b/.github/workflows/daily-repo-status.md
@@ -0,0 +1,62 @@
+---
+description: |
+ This workflow creates daily repo status reports. It gathers recent repository
+ activity (issues, PRs, discussions, releases, code changes) and generates
+ engaging GitHub issues with productivity insights, community highlights,
+ and project recommendations.
+
+on:
+ schedule: daily
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ issues: read
+ pull-requests: read
+
+network: defaults
+
+engine:
+ id: copilot
+ model: claude-haiku-4.5
+
+tools:
+ github:
+ # If in a public repo, setting `lockdown: false` allows
+ # reading issues, pull requests and comments from 3rd-parties
+ # If in a private repo this has no particular effect.
+ lockdown: false
+ min-integrity: none # This workflow is allowed to examine and comment on any issues
+
+safe-outputs:
+ mentions: false
+ allowed-github-references: []
+ create-issue:
+ title-prefix: "[repo-status] "
+ labels: [report, daily-status]
+ close-older-issues: true
+source: githubnext/agentics/workflows/repo-status.md@main
+---
+
+# Repo Status
+
+Create an upbeat daily status report for the repo as a GitHub issue.
+
+## What to include
+
+- Recent repository activity (issues, PRs, discussions, releases, code changes)
+- Progress tracking, goal reminders and highlights
+- Project status and recommendations
+- Actionable next steps for maintainers
+
+## Style
+
+- Be positive, encouraging, and helpful 🌟
+- Use emojis moderately for engagement
+- Keep it concise - adjust length based on actual activity
+
+## Process
+
+1. Gather recent activity from the repository
+2. Study the repository, its issues and its pull requests
+3. Create a new GitHub issue with your findings and insights
diff --git a/.github/workflows/docker-cloudstack-simulator.yml b/.github/workflows/docker-cloudstack-simulator.yml
index af6cbf49f5ef..ac778a48af54 100644
--- a/.github/workflows/docker-cloudstack-simulator.yml
+++ b/.github/workflows/docker-cloudstack-simulator.yml
@@ -35,10 +35,10 @@ concurrency:
jobs:
build:
if: github.repository == 'apache/cloudstack'
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
steps:
- name: Login to Docker Registry
- uses: docker/login-action@v2
+ uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ${{ secrets.DOCKER_REGISTRY }}
username: ${{ secrets.DOCKERHUB_USER }}
@@ -47,7 +47,9 @@ jobs:
- name: Set Docker repository name
run: echo "DOCKER_REPOSITORY=apache" >> $GITHUB_ENV
- - uses: actions/checkout@v5
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
- name: Set ACS version
run: echo "ACS_VERSION=$(grep '' pom.xml | head -2 | tail -1 | cut -d'>' -f2 |cut -d'<' -f1)" >> $GITHUB_ENV
diff --git a/.github/workflows/main-sonar-check.yml b/.github/workflows/main-sonar-check.yml
index 70cc3fbe19f3..f48409fbc0c3 100644
--- a/.github/workflows/main-sonar-check.yml
+++ b/.github/workflows/main-sonar-check.yml
@@ -15,54 +15,53 @@
# specific language governing permissions and limitations
# under the License.
-name: Main Branch Sonar Quality Check
-
+name: Sonar Quality Check (Main)
+permissions:
+ contents: read
on:
push:
branches:
- main
-
-permissions:
- contents: read # to fetch code (actions/checkout)
- pull-requests: write # for sonar to comment on pull-request
-
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
build:
if: github.repository == 'apache/cloudstack'
- name: Main Sonar JaCoCo Build
- runs-on: ubuntu-22.04
+ name: Sonar JaCoCo Coverage
+ runs-on: ubuntu-24.04
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
fetch-depth: 0
-
- - name: Set up JDK17
- uses: actions/setup-java@v5
+ persist-credentials: false
+ - name: Setup Environment
+ uses: ./.github/actions/setup-env
with:
- distribution: 'temurin'
- java-version: '17'
- cache: 'maven'
-
+ install-python: 'true'
+ install-apt-deps: 'true'
- name: Cache SonarCloud packages
- uses: actions/cache@v4
+ uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
-
- - name: Cache local Maven repository
- uses: actions/cache@v4
- with:
- path: ~/.m2/repository
- key: ${{ runner.os }}-m2-${{ hashFiles('pom.xml', '*/pom.xml', '*/*/pom.xml', '*/*/*/pom.xml') }}
- restore-keys: |
- ${{ runner.os }}-m2
-
- - name: Run Tests with Coverage
+ - name: Install Non-OSS
+ uses: ./.github/actions/install-nonoss
+ - name: Run Build and Tests with Coverage
+ run: mvn -B -T$(nproc) -P developer,systemvm,quality -Dsimulator -Dnoredist clean install
+ - name: Upload to SonarQube
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- run: |
- git clone https://github.com/shapeblue/cloudstack-nonoss.git nonoss
- cd nonoss && bash -x install-non-oss.sh && cd ..
- mvn -T$(nproc) -P quality -Dsimulator -Dnoredist clean install org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=apache_cloudstack
+ run: mvn -B -P quality org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=apache_cloudstack -Dsonar.branch.name=${{ github.ref_name }}
+ - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
+ with:
+ files: ./client/target/site/jacoco-aggregate/jacoco.xml
+ fail_ci_if_error: true
+ flags: unittests
+ verbose: true
+ name: codecov
+ token: ${{ secrets.CODECOV_TOKEN }}
+ - name: Compute Coverage Grade
+ run: bash scripts/coverage-grade.sh client/target/site/jacoco-aggregate/jacoco.xml
diff --git a/.github/workflows/merge-conflict-checker.yml b/.github/workflows/merge-conflict-checker.yml
index 860e1c1b5614..badf8c4b4c5b 100644
--- a/.github/workflows/merge-conflict-checker.yml
+++ b/.github/workflows/merge-conflict-checker.yml
@@ -17,28 +17,26 @@
name: "PR Merge Conflict Check"
on:
- push:
- pull_request_target:
- types: [synchronize]
+ schedule:
+ - cron: '*/10 * * * *'
+ workflow_dispatch:
-permissions: # added using https://github.com/step-security/secure-workflows
- contents: read
+permissions: {}
concurrency:
- group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
- cancel-in-progress: true
+ group: "gh-aw-${{ github.workflow }}"
jobs:
triage:
permissions:
- pull-requests: write # for eps1lon/actions-label-merge-conflict to label PRs
- runs-on: ubuntu-22.04
+ pull-requests: write # for eps1lon/actions-label-merge-conflict to label PRs
+ runs-on: ubuntu-24.04
steps:
- - name: Conflict Check
- uses: eps1lon/actions-label-merge-conflict@v2.0.0
- with:
- repoToken: "${{ secrets.GITHUB_TOKEN }}"
- dirtyLabel: "status:has-conflicts"
- removeOnDirtyLabel: "status:ready-for-review"
- continueOnMissingPermissions: true
- commentOnDirty: "This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch."
+ - name: Conflict Check
+ uses: eps1lon/actions-label-merge-conflict@0273be72a0bbd58fcd71d0d6c02c209b50d1e5e1 # v3.1.0
+ with:
+ repoToken: "${{ secrets.GITHUB_TOKEN }}"
+ dirtyLabel: "status:has-conflicts"
+ removeOnDirtyLabel: "status:ready-for-review"
+ continueOnMissingPermissions: true
+ commentOnDirty: "This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch."
diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml
index 1518cfec014a..4de995479c59 100644
--- a/.github/workflows/pre-commit.yml
+++ b/.github/workflows/pre-commit.yml
@@ -29,17 +29,23 @@ concurrency:
jobs:
pre-commit:
name: Run pre-commit
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
steps:
- name: Check Out
- uses: actions/checkout@v5
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+ - name: Set up Python
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ with:
+ python-version: '3.11'
+ cache: 'pip'
- name: Install
- run: |
- python -m pip install --upgrade pip
- pip install pre-commit
+ run: pip install pre-commit
- name: Set PY
run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV
- - uses: actions/cache@v4
+ - name: Cache pre-commit environments
+ uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
diff --git a/.github/workflows/rat.yml b/.github/workflows/rat.yml
index d71f4b0852d8..f8b0aa149324 100644
--- a/.github/workflows/rat.yml
+++ b/.github/workflows/rat.yml
@@ -16,32 +16,27 @@
# under the License.
name: License Check
-
-on: [push, pull_request]
-
+on:
+ - push
+ - pull_request
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
- cancel-in-progress: true
-
+ cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
permissions:
contents: read
-
jobs:
build:
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
steps:
- - uses: actions/checkout@v5
- - name: Set up JDK 17
- uses: actions/setup-java@v5
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
- java-version: '17'
- distribution: 'adopt'
- architecture: x64
- cache: maven
+ persist-credentials: false
+ - name: Setup Environment
+ uses: ./.github/actions/setup-env
+ - name: Install Non-OSS
+ uses: ./.github/actions/install-nonoss
- name: RAT licence checks
run: |
- git clone https://github.com/shapeblue/cloudstack-nonoss.git nonoss && cd nonoss && bash -x install-non-oss.sh && cd ..
- rm -fr nonoss
mvn -P developer,systemvm -Dsimulator -Dnoredist -pl . org.apache.rat:apache-rat-plugin:0.12:check
- name: Rat Report
if: always()
diff --git a/.github/workflows/sonar-check.yml b/.github/workflows/sonar-check.yml
index 46bfdd7d015c..fbb3cb9f540d 100644
--- a/.github/workflows/sonar-check.yml
+++ b/.github/workflows/sonar-check.yml
@@ -16,58 +16,100 @@
# under the License.
name: Sonar Quality Check
-
-on: [pull_request]
-
permissions:
- contents: read # to fetch code (actions/checkout)
- pull-requests: write # for sonar to comment on pull-request
-
+ contents: read
+ pull-requests: write
+on:
+ pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
- cancel-in-progress: true
-
+ cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
build:
- if: github.repository == 'apache/cloudstack' && github.event.pull_request.head.repo.full_name == github.repository
name: Sonar JaCoCo Coverage
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
- ref: "refs/pull/${{ github.event.number }}/merge"
fetch-depth: 0
-
- - name: Set up JDK17
- uses: actions/setup-java@v5
+ persist-credentials: false
+ - name: Setup Environment
+ uses: ./.github/actions/setup-env
with:
- distribution: 'temurin'
- java-version: '17'
- cache: 'maven'
-
+ install-python: 'true'
+ install-apt-deps: 'true'
- name: Cache SonarCloud packages
- uses: actions/cache@v4
+ uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
-
- - name: Cache local Maven repository
- uses: actions/cache@v4
- with:
- path: ~/.m2/repository
- key: ${{ runner.os }}-m2-${{ hashFiles('pom.xml', '*/pom.xml', '*/*/pom.xml', '*/*/*/pom.xml') }}
- restore-keys: |
- ${{ runner.os }}-m2
-
+ - name: Install Non-OSS
+ uses: ./.github/actions/install-nonoss
- name: Run Build and Tests with Coverage
- id: coverage
+ run: mvn -B -T$(nproc) -P developer,systemvm,quality -Dsimulator -Dnoredist clean install
+ - name: Upload to SonarQube
+ if: github.repository == 'apache/cloudstack' && github.event.pull_request.head.repo.full_name == github.repository
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
PR_ID: ${{ github.event.pull_request.number }}
HEADREF: ${{ github.event.pull_request.head.ref }}
run: |
- git clone https://github.com/shapeblue/cloudstack-nonoss.git nonoss
- cd nonoss && bash -x install-non-oss.sh && cd ..
- mvn -T$(nproc) -P quality -Dsimulator -Dnoredist clean install org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=apache_cloudstack -Dsonar.pullrequest.key="$PR_ID" -Dsonar.pullrequest.branch="$HEADREF" -Dsonar.pullrequest.github.repository=apache/cloudstack -Dsonar.pullrequest.provider=GitHub -Dsonar.pullrequest.github.summary_comment=true
+ mvn -B -P quality org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=apache_cloudstack -Dsonar.pullrequest.key="$PR_ID" -Dsonar.pullrequest.branch="$HEADREF" -Dsonar.pullrequest.github.repository=apache/cloudstack -Dsonar.pullrequest.provider=GitHub -Dsonar.pullrequest.github.summary_comment=true
+ - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
+ with:
+ files: ./client/target/site/jacoco-aggregate/jacoco.xml
+ fail_ci_if_error: true
+ flags: unittests
+ verbose: true
+ name: codecov
+ token: ${{ secrets.CODECOV_TOKEN }}
+ - name: Compute Coverage Grade
+ id: grade
+ run: bash scripts/coverage-grade.sh client/target/site/jacoco-aggregate/jacoco.xml
+ - name: Post Coverage Grade Comment on PR
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const grade = '${{ steps.grade.outputs.coverage_grade }}';
+ const label = '${{ steps.grade.outputs.coverage_grade_label }}';
+ const linePct = '${{ steps.grade.outputs.line_coverage }}';
+ const branchPct = '${{ steps.grade.outputs.branch_coverage }}';
+ const emojiMap = { A: '🟢', B: '🟡', C: '🟠', D: '🔴', F: '⛔' };
+ const emoji = emojiMap[grade] ?? '❓';
+ const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
+
+ const branchRow = branchPct !== 'N/A'
+ ? `| Branch coverage | **${branchPct}%** |`
+ : '';
+
+ const body = [
+ `## ${emoji} Test Coverage Grade: \`${grade}\` — ${label}`,
+ '',
+ '| Metric | Value |',
+ '|--------|-------|',
+ `| Line coverage | **${linePct}%** |`,
+ branchRow,
+ '',
+ '### Grade Scale',
+ '| Grade | Line Coverage | Meaning |',
+ '|-------|--------------|---------|',
+ '| 🟢 A | ≥ 80% | Excellent - this code sleeps well at night 😴 |',
+ '| 🟡 B | 60-79% | Good - almost there, don\'t stop now 😉 |',
+ '| 🟠 C | 40-59% | Acceptable - your code is wearing a seatbelt, but no airbags 😬 |',
+ '| 🔴 D | 20-39% | Marginal - boldly shipping where no test has gone before 🖖 |',
+ '| ⛔ F | < 20% | Failing - tests? what tests? 🔥 |',
+ '',
+ '> Branch coverage is shown as a secondary signal. Grade is determined by **line coverage**.',
+ `> [View full Actions run](${runUrl})`,
+ ].filter(l => l !== undefined).join('\n');
+
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ body: body,
+ });
+ console.log('Posted coverage grade comment');
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
new file mode 100644
index 000000000000..c0da5f98cc8e
--- /dev/null
+++ b/.github/workflows/stale.yml
@@ -0,0 +1,49 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: 'Close stale issues and PRs'
+on:
+ schedule:
+ - cron: '30 1 * * *'
+
+jobs:
+ stale:
+ runs-on: ubuntu-latest
+ permissions:
+ actions: write
+ issues: write
+ pull-requests: write
+ steps:
+ - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0
+ with:
+ stale-issue-message: 'This issue is stale because it has been open for 120 days with no activity. It may be removed by administrators of this project at any time. Remove the stale label or comment to request for removal of it to prevent this.'
+ stale-pr-message: 'This PR is stale because it has been open for 120 days with no activity. It may be removed by administrators of this project at any time. Remove the stale label or comment to request for removal of it to prevent this.'
+ close-issue-message: 'This issue was closed because it has been stale for 120 days with no activity.'
+ close-pr-message: 'This PR was closed because it has been stale for 240 days with no activity.'
+ stale-issue-label: 'no-issue-activity'
+ stale-pr-label: 'no-pr-activity'
+ days-before-stale: 120
+ days-before-close: -1
+ days-before-pr-close: 240
+ exempt-issue-labels: 'gsoc,good-first-issue,long-term-plan'
+ exempt-pr-labels: 'status:ready-for-merge,status:needs-testing,status:on-hold'
+ - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0
+ with:
+ stale-issue-label: 'archive'
+ days-before-stale: 240
+ exempt-issue-labels: 'gsoc,good-first-issue,long-term-plan'
+ days-before-close: -1
diff --git a/.github/workflows/ui.yml b/.github/workflows/ui.yml
index 56b04a6f9c96..aeccb5624f72 100644
--- a/.github/workflows/ui.yml
+++ b/.github/workflows/ui.yml
@@ -28,15 +28,19 @@ permissions:
jobs:
build:
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
- name: Set up Node
- uses: actions/setup-node@v5
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 16
+ cache: 'npm'
+ cache-dependency-path: 'ui/package-lock.json'
- name: Env details
run: |
@@ -55,7 +59,7 @@ jobs:
npm run lint
npm run test:unit
- - uses: codecov/codecov-action@v4
+ - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
if: github.repository == 'apache/cloudstack'
with:
working-directory: ui
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 107bd8b94cd3..91537e25267e 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -52,6 +52,16 @@ repos:
args: ['644']
files: \.md$
stages: [manual]
+ - id: insert-license
+ name: add license for all cfg files
+ description: automatically adds a licence header to all cfg files that don't have a license header
+ files: \.cfg$
+ args:
+ - --comment-style
+ - '|#|'
+ - --license-filepath
+ - .github/workflows/license-templates/LICENSE.txt
+ - --fuzzy-match-generates-todo
- id: insert-license
name: add license for all Markdown files
files: \.md$
@@ -61,7 +71,17 @@ repos:
- --license-filepath
- .github/workflows/license-templates/LICENSE.txt
- --fuzzy-match-generates-todo
- exclude: ^(CHANGES|ISSUE_TEMPLATE|PULL_REQUEST_TEMPLATE)\.md$|^ui/docs/(full|smoke)-test-plan\.template\.md$
+ exclude: ^(CHANGES|ISSUE_TEMPLATE|PULL_REQUEST_TEMPLATE)\.md$|^ui/docs/(full|smoke)-test-plan\.template\.md$|^\.github/workflows/.*\.md$|^\.github/aw/.*\.md$
+ - id: insert-license
+ name: add license for all properties files
+ description: automatically adds a licence header to all properties files that don't have a license header
+ files: \.properties$
+ args:
+ - --comment-style
+ - '|#|'
+ - --license-filepath
+ - .github/workflows/license-templates/LICENSE.txt
+ - --fuzzy-match-generates-todo
- id: insert-license
name: add license for all Shell files
description: automatically adds a licence header to all Shell files that don't have a license header
@@ -81,6 +101,15 @@ repos:
- --license-filepath
- .github/workflows/license-templates/LICENSE.txt
- --fuzzy-match-generates-todo
+ - id: insert-license
+ name: add license for all Vue files
+ files: \.vue$
+ args:
+ - --comment-style
+ - '|//|'
+ - --license-filepath
+ - .github/workflows/license-templates/LICENSE.txt
+ - --fuzzy-match-generates-todo
- id: insert-license
name: add license for all YAML files
description: automatically adds a licence header to all YAML files that don't have a license header
@@ -91,6 +120,7 @@ repos:
- --license-filepath
- .github/workflows/license-templates/LICENSE.txt
- --fuzzy-match-generates-todo
+ exclude: ^\.github/workflows/.*\.lock\.yml$
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
@@ -121,7 +151,7 @@ repos:
^server/src/test/resources/certs/rsa_self_signed\.key$|
^services/console-proxy/rdpconsole/src/test/doc/rdp-key\.pem$|
^systemvm/agent/certs/localhost\.key$|
- ^systemvm/agent/certs/realhostip\.key$|
+ ^systemvm/agent/certs/systemvm\.key$|
^test/integration/smoke/test_ssl_offloading\.py$
- id: end-of-file-fixer
exclude: \.vhd$|\.svg$
@@ -132,17 +162,15 @@ repos:
- id: forbid-submodules
- id: mixed-line-ending
- id: trailing-whitespace
- files: \.(bat|cfg|cs|css|gitignore|header|in|install|java|md|properties|py|rb|rc|sh|sql|te|template|txt|ucls|vue|xml|xsl|yaml|yml)$|^cloud-cli/bindir/cloud-tool$|^debian/changelog$
+ files: ^(LICENSE|NOTICE)$|README$|\.(bat|cfg|config|cs|css|erb|gitignore|header|in|install|java|md|properties|py|rb|rc|sh|sql|svg|te|template|txt|ucls|vue|xml|xsl|yaml|yml)$|^cloud-cli/bindir/cloud-tool$|^debian/changelog$
args: [--markdown-linebreak-ext=md]
exclude: ^services/console-proxy/rdpconsole/src/test/doc/freerdp-debug-log\.txt$
- repo: https://github.com/codespell-project/codespell
- rev: v2.4.1
+ rev: v2.4.2
hooks:
- id: codespell
name: run codespell
description: Check spelling with codespell
- args: [--ignore-words=.github/linters/codespell.txt]
- exclude: ^systemvm/agent/noVNC/|^ui/package\.json$|^ui/package-lock\.json$|^ui/public/js/less\.min\.js$|^ui/public/locales/.*[^n].*\.json$|^server/src/test/java/org/apache/cloudstack/network/ssl/CertServiceTest.java$|^test/integration/smoke/test_ssl_offloading.py$
- repo: https://github.com/pycqa/flake8
rev: 7.0.0
hooks:
@@ -156,7 +184,7 @@ repos:
description: check Markdown files with markdownlint
args: [--config=.github/linters/.markdown-lint.yml]
types: [markdown]
- files: \.(md|mdown|markdown)$
+ files: \.md$
- repo: https://github.com/adrienverge/yamllint
rev: v1.37.1
hooks:
@@ -166,4 +194,4 @@ repos:
args: [--config-file=.github/linters/.yamllint.yml]
types: [yaml]
files: \.ya?ml$
- exclude: ^.*k8s-.*\.ya?ml$
+ exclude: ^.*k8s-.*\.ya?ml$|^.github/workflows/.*\.lock\.ya?ml$
diff --git a/LICENSE b/LICENSE
index 8be7d8083a5e..e61c431f5fad 100644
--- a/LICENSE
+++ b/LICENSE
@@ -177,14 +177,14 @@ Copyright (c) 2014 The Apache Software Foundation
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
-
+
This distribution contains third party resources.
Within the console-proxy/js directory
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
- Copyright (c) 2009, John Resig
-
+ Copyright (c) 2009, John Resig
+
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
@@ -192,10 +192,10 @@ Within the console-proxy/js directory
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
-
+
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
-
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -203,43 +203,43 @@ Within the console-proxy/js directory
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- from John Resig
- jquery.js
+
+ from John Resig
+ jquery.js
Within the systemvm/debian/etc directory
placed in the public domain
- by Adiscon GmbH http://www.adiscon.com/
- rsyslog.conf
- by Simon Kelley
- dnsmasq.conf
- vpcdnsmasq.conf
+ by Adiscon GmbH http://www.adiscon.com/
+ rsyslog.conf
+ by Simon Kelley
+ dnsmasq.conf
+ vpcdnsmasq.conf
Within the systemvm/debian/etc/apache2 directory
licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above)
Copyright (c) 2012 The Apache Software Foundation
- from The Apache Software Foundation http://www.apache.org/
- httpd.conf
+ from The Apache Software Foundation http://www.apache.org/
+ httpd.conf
vhost.template
Within the systemvm/debian/etc/ssh/ directory
licensed under the BSD (2-clause) http://www.opensource.org/licenses/BSD-2-Clause (as follows)
-
-
+
+
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
-
+
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer. Redistributions in binary form must
reproduce the above copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided with the
distribution.
-
+
Neither the name of the author nor the names of contributors may be used to
endorse or promote products derived from this software without specific prior
written permission.
-
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -250,55 +250,55 @@ Within the systemvm/debian/etc/ssh/ directory
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- from OpenSSH Project http://www.openssh.org/
- sshd_config
+
+ from OpenSSH Project http://www.openssh.org/
+ sshd_config
Within the systemvm/debian/root/redundant_router directory
placed in the public domain
- by The netfilter.org project http://www.netfilter.org/
- conntrackd.conf.templ
+ by The netfilter.org project http://www.netfilter.org/
+ conntrackd.conf.templ
Within the scripts/storage/secondary directory
licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above)
Copyright (c) 2010-2011 OpenStack, LLC.
- from OpenStack, LLC http://www.openstack.org
- swift
+ from OpenStack, LLC http://www.openstack.org
+ swift
Within the scripts/vm/hypervisor/xenserver directory
licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above)
Copyright (c) 2010-2011 OpenStack, LLC.
- from OpenStack, LLC http://www.openstack.org
- swift
+ from OpenStack, LLC http://www.openstack.org
+ swift
Within the ui/lib directory
placed in the public domain
- by Eric Meyer http://meyerweb.com/eric/
+ by Eric Meyer http://meyerweb.com/eric/
reset.css from http://meyerweb.com/eric/tools/css/reset/
licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above)
Copyright (c) 2006 Google Inc.
- from Google Inc. http://google.com
+ from Google Inc. http://google.com
excanvas.js from http://code.google.com/p/explorercanvas/
licensed under the BSD (2-clause) http://www.opensource.org/licenses/BSD-2-Clause (as follows)
Copyright (c) 2008 George McGinley Smith
- All rights reserved.
-
+ All rights reserved.
+
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
-
+
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer. Redistributions in binary form must
reproduce the above copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided with the
distribution.
-
+
Neither the name of the author nor the names of contributors may be used to
endorse or promote products derived from this software without specific prior
written permission.
-
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -309,13 +309,13 @@ Within the ui/lib directory
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- from George McGinley Smith
- jquery.easing.js
+
+ from George McGinley Smith
+ jquery.easing.js
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
-
-
+
+
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
@@ -323,10 +323,10 @@ Within the ui/lib directory
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
-
+
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
-
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -334,14 +334,14 @@ Within the ui/lib directory
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- from The Dojo Foundation http://dojofoundation.org/
+
+ from The Dojo Foundation http://dojofoundation.org/
require.js from http://github.com/jrburke/requirejs
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
- Copyright (c) 2011, John Resig
-
+ Copyright (c) 2011, John Resig
+
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
@@ -349,10 +349,10 @@ Within the ui/lib directory
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
-
+
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
-
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -360,14 +360,14 @@ Within the ui/lib directory
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- from John Resig
- jquery.js
+
+ from John Resig
+ jquery.js
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
Copyright (c) 2014 Jörn Zaefferer
-
+
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
@@ -375,10 +375,10 @@ Within the ui/lib directory
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
-
+
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
-
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -386,9 +386,9 @@ Within the ui/lib directory
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- from Jorn Zaefferer
- jquery.validate.js
+
+ from Jorn Zaefferer
+ jquery.validate.js
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
@@ -418,8 +418,8 @@ Within the ui/lib directory
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
- Copyright (c) 2010, Sebastian Tschan
-
+ Copyright (c) 2010, Sebastian Tschan
+
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
@@ -427,10 +427,10 @@ Within the ui/lib directory
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
-
+
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
-
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -438,14 +438,14 @@ Within the ui/lib directory
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- from Sebastian Tschan https://blueimp.net
- jquery.md5.js
+
+ from Sebastian Tschan https://blueimp.net
+ jquery.md5.js
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
- Copyright (c) 2006 Klaus Hartl (stilbuero.de)
-
+ Copyright (c) 2006 Klaus Hartl (stilbuero.de)
+
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
@@ -453,10 +453,10 @@ Within the ui/lib directory
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
-
+
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
-
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -464,15 +464,15 @@ Within the ui/lib directory
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- from Klaus Hartl http://stilbuero.de
- jquery.cookies.js
+
+ from Klaus Hartl http://stilbuero.de
+ jquery.cookies.js
Within the ui/lib/flot directory
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
- Released under the MIT license by IOLA, December 2007.
-
+ Released under the MIT license by IOLA, December 2007.
+
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
@@ -480,10 +480,10 @@ Within the ui/lib/flot directory
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
-
+
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
-
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -491,24 +491,24 @@ Within the ui/lib/flot directory
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- from IOLA http://www.iola.dk/
- jquery.flot.crosshair.js
- jquery.flot.fillbetween.js
- jquery.flot.image.js
- jquery.flot.js
- jquery.flot.navigate.js
- jquery.flot.resize.js
- jquery.flot.selection.js
- jquery.flot.stack.js
- jquery.flot.symbol.js
- jquery.flot.threshold.js
+
+ from IOLA http://www.iola.dk/
+ jquery.flot.crosshair.js
+ jquery.flot.fillbetween.js
+ jquery.flot.image.js
+ jquery.flot.js
+ jquery.flot.navigate.js
+ jquery.flot.resize.js
+ jquery.flot.selection.js
+ jquery.flot.stack.js
+ jquery.flot.symbol.js
+ jquery.flot.threshold.js
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
Created by Brian Medendorp, June 2009
- Updated November 2009 with contributions from: btburnett3, Anthony Aragues and Xavi Ivars
-
+ Updated November 2009 with contributions from: btburnett3, Anthony Aragues and Xavi Ivars
+
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
@@ -516,10 +516,10 @@ Within the ui/lib/flot directory
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
-
+
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
-
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -527,13 +527,13 @@ Within the ui/lib/flot directory
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- from Brian Medendorp
- jquery.pie.js
+
+ from Brian Medendorp
+ jquery.pie.js
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
-
-
+
+
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
@@ -541,10 +541,10 @@ Within the ui/lib/flot directory
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
-
+
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
-
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -552,14 +552,14 @@ Within the ui/lib/flot directory
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- from Ole Laursen
- jquery.colorhelpers.js
+
+ from Ole Laursen
+ jquery.colorhelpers.js
Within the ui/lib/jquery-ui directory
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
-
-
+
+
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
@@ -567,10 +567,10 @@ Within the ui/lib/jquery-ui directory
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
-
+
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
-
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -578,17 +578,17 @@ Within the ui/lib/jquery-ui directory
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- from jQuery UI Developers http://jqueryui.com/about
- css/jquery-ui.css
- index.html
- js/jquery-ui.js
+
+ from jQuery UI Developers http://jqueryui.com/about
+ css/jquery-ui.css
+ index.html
+ js/jquery-ui.js
Within the ui/lib/qunit directory
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
- Copyright (c) 2012 John Resig, Jörn Zaefferer
-
+ Copyright (c) 2012 John Resig, Jörn Zaefferer
+
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
@@ -596,10 +596,10 @@ Within the ui/lib/qunit directory
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
-
+
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
-
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -607,20 +607,20 @@ Within the ui/lib/qunit directory
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- from Jorn Zaefferer
+
+ from Jorn Zaefferer
qunit.css from http://docs.jquery.com/QUnit
qunit.js from http://docs.jquery.com/QUnit
Within the utils/src/main/java/com/cloud/utils/db directory
licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above)
Copyright (c) 2004 Clinton Begin
- from Clinton Begin http://code.google.com/p/mybatis/
+ from Clinton Begin http://code.google.com/p/mybatis/
ScriptRunner.java from http://code.google.com/p/mybatis/
Within the utils/src/main/java/org/apache/commons/httpclient/contrib/ssl directory
licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above)
Copyright (c) 2007 The Apache Software Foundation
- from The Apache Software Foundation http://www.apache.org/
- EasySSLProtocolSocketFactory.java
- EasyX509TrustManager.java
+ from The Apache Software Foundation http://www.apache.org/
+ EasySSLProtocolSocketFactory.java
+ EasyX509TrustManager.java
diff --git a/NOTICE b/NOTICE
index b19e4a428530..8666be264b51 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,62 +1,62 @@
Apache CloudStack
Copyright 2014 The Apache Software Foundation
-
+
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
-
-
+
+
This distribution contains third party resources requiring the following notices:
-
- For
+
+ For
jquery.js
-
+
jQuery JavaScript Library v1.3.2
http://jquery.com/
-
+
Copyright (c) 2009 John Resig
Dual licensed under the MIT and GPL licenses.
http://docs.jquery.com/License
-
+
Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
Revision: 6246
-
- For
+
+ For
jquery.js
-
+
jQuery JavaScript Library v1.6.4
http://jquery.com/
-
+
Copyright 2011, John Resig
Dual licensed under the MIT or GPL Version 2 licenses.
http://jquery.org/license
-
+
Includes Sizzle.js
http://sizzlejs.com/
Copyright 2011, The Dojo Foundation
Released under the MIT, BSD, and GPL Licenses.
-
+
Date: Mon Sep 12 18:54:48 2011 -0400
-
- For
+
+ For
jquery.md5.js
-
+
jQuery MD5 Plugin 1.2.1
https://github.com/blueimp/jQuery-MD5
-
+
Copyright 2010, Sebastian Tschan
https://blueimp.net
-
+
Licensed under the MIT license:
http://creativecommons.org/licenses/MIT/
-
+
Based on
A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
Digest Algorithm, as defined in RFC 1321.
@@ -65,15 +65,15 @@ Copyright 2014 The Apache Software Foundation
Distributed under the BSD License
See http://pajhome.org.uk/crypt/md5 for more info.
-
- For
+
+ For
jquery.colorhelpers.js
-
+
Plugin for jQuery for working with colors.
-
+
Version 1.1.
-
+
Inspiration from jQuery color animation plugin by John Resig.
-
+
Released under the MIT license by Ole Laursen, October 2009.
diff --git a/PRE-COMMIT.md b/PRE_COMMIT.md
similarity index 97%
rename from PRE-COMMIT.md
rename to PRE_COMMIT.md
index 9b76929d4223..62dc296c99e4 100644
--- a/PRE-COMMIT.md
+++ b/PRE_COMMIT.md
@@ -20,7 +20,7 @@
# pre-commit
We run [pre-commit](https://pre-commit.com/) with
-[GitHub Actions](https://github.com/apache/cloudstack/blob/main/.github/workflows/linter.yml) so installation on your
+[GitHub Actions](https://github.com/apache/cloudstack/blob/main/.github/workflows/pre-commit.yml) so installation on your
local machine is currently optional.
The `pre-commit` [configuration file](https://github.com/apache/cloudstack/blob/main/.pre-commit-config.yaml)
diff --git a/README.md b/README.md
index a5aacb49f6b5..852674ab7b1f 100644
--- a/README.md
+++ b/README.md
@@ -203,7 +203,7 @@ Unrestricted (TSU) exception (see the BIS Export Administration Regulations, Sec
The following provides more details on the included cryptographic software:
* CloudStack makes use of JaSypt cryptographic libraries.
-* CloudStack has a system requirement of MySQL, and uses native database encryption functionality.
+* CloudStack requires a MySQL-compatible database (MariaDB or MySQL), and uses native database encryption functionality.
* CloudStack makes use of the Bouncy Castle general-purpose encryption library.
* CloudStack can optionally interact with and control OpenSwan-based VPNs.
* CloudStack has a dependency on and makes use of JSch - a java SSH2 implementation.
diff --git a/agent/conf/agent.properties b/agent/conf/agent.properties
index 0dc5b8211e0d..0a459d8d4fc5 100644
--- a/agent/conf/agent.properties
+++ b/agent/conf/agent.properties
@@ -78,6 +78,14 @@ zone=default
# Generated with "uuidgen".
local.storage.uuid=
+# Enable TLS for image server transfers. The keys are read from:
+# cert file = /etc/cloudstack/agent/cloud.crt
+# key file = /etc/cloudstack/agent/cloud.key
+image.server.tls.enabled=true
+
+# The Address for the network interface that the image server listens on. If not specified, it will listen on the Management network.
+#image.server.listen.address=
+
# Location for KVM virtual router scripts.
# The path defined in this property is relative to the directory "/usr/share/cloudstack-common/".
domr.scripts.dir=scripts/network/domr/kvm
@@ -457,3 +465,18 @@ iscsi.session.cleanup.enabled=false
# Instance conversion VIRT_V2V_TMPDIR env var
#convert.instance.env.virtv2v.tmpdir=
+
+# Time, in seconds, to wait before retrying to rebase during the incremental snapshot process.
+# incremental.snapshot.retry.rebase.wait=60
+
+# Path to the VDDK library directory for VMware to KVM conversion via VDDK,
+# passed to virt-v2v as -io vddk-libdir=
+#vddk.lib.dir=
+
+# Ordered VDDK transport preference for VMware to KVM conversion via VDDK, passed as
+# -io vddk-transports= to virt-v2v. Example: nbd:nbdssl
+#vddk.transports=
+
+# Optional vCenter SHA1 thumbprint for VMware to KVM conversion via VDDK, passed as
+# -io vddk-thumbprint=. If unset, CloudStack computes it on the KVM host via openssl.
+#vddk.thumbprint=
diff --git a/agent/conf/uefi.properties.in b/agent/conf/uefi.properties.in
new file mode 100644
index 000000000000..3c8866f634bc
--- /dev/null
+++ b/agent/conf/uefi.properties.in
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Configuration file for UEFI
+
+guest.nvram.template.legacy=@GUESTNVRAMTEMPLATELEGACY@
+guest.loader.legacy=@GUESTLOADERLEGACY@
+guest.nvram.template.secure=@GUESTNVRAMTEMPLATESECURE@
+guest.loader.secure=@GUESTLOADERSECURE@
+guest.nvram.path=@GUESTNVRAMPATH@
diff --git a/agent/src/main/java/com/cloud/agent/Agent.java b/agent/src/main/java/com/cloud/agent/Agent.java
index 0d63f6690284..275fd41edc34 100644
--- a/agent/src/main/java/com/cloud/agent/Agent.java
+++ b/agent/src/main/java/com/cloud/agent/Agent.java
@@ -1322,7 +1322,6 @@ public void doTask(final Task task) throws TaskExecutionException {
processResponse((Response)request, task.getLink());
} else {
//put the requests from mgt server into another thread pool, as the request may take a longer time to finish. Don't block the NIO main thread pool
- //processRequest(request, task.getLink());
requestHandler.submit(new AgentRequestHandler(getType(), getLink(), request));
}
} catch (final ClassNotFoundException e) {
@@ -1332,13 +1331,14 @@ public void doTask(final Task task) throws TaskExecutionException {
}
} else if (task.getType() == Task.Type.DISCONNECT) {
try {
- // an issue has been found if reconnect immediately after disconnecting. please refer to https://github.com/apache/cloudstack/issues/8517
+ // an issue has been found if reconnect immediately after disconnecting.
// wait 5 seconds before reconnecting
+ logger.debug("Wait for 5 secs before reconnecting, disconnect task - {}", () -> getLinkLog(task.getLink()));
Thread.sleep(5000);
} catch (InterruptedException e) {
}
shell.setConnectionTransfer(false);
- logger.debug("Executing disconnect task - {}", () -> getLinkLog(task.getLink()));
+ logger.debug("Executing disconnect task - {} and reconnecting", () -> getLinkLog(task.getLink()));
reconnect(task.getLink());
} else if (task.getType() == Task.Type.OTHER) {
processOtherTask(task);
diff --git a/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java b/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java
index 3364f9708cf5..18a6b6df1006 100644
--- a/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java
+++ b/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java
@@ -123,6 +123,20 @@ public class AgentProperties{
*/
public static final Property LOCAL_STORAGE_PATH = new Property<>("local.storage.path", "/var/lib/libvirt/images/");
+ /**
+ * Enables TLS on the KVM image server transfer endpoint.
+ * Data type: Boolean.
+ * Default value: true
+ */
+ public static final Property IMAGE_SERVER_TLS_ENABLED = new Property<>("image.server.tls.enabled", true);
+
+ /**
+ * The IP address that the KVM image server listens on.
+ * Data type: String.
+ * Default value: null
+ */
+ public static final Property IMAGE_SERVER_LISTEN_ADDRESS = new Property<>("image.server.listen.address", null, String.class);
+
/**
* Directory where Qemu sockets are placed.
* These sockets are for the Qemu Guest Agent and SSVM provisioning.
@@ -808,6 +822,30 @@ public Property getWorkers() {
*/
public static final Property CONVERT_ENV_VIRTV2V_TMPDIR = new Property<>("convert.instance.env.virtv2v.tmpdir", null, String.class);
+ /**
+ * Path to the VDDK library directory on the KVM conversion host, used when converting VMs from VMware to KVM via VDDK.
+ * This directory is passed to virt-v2v as -io vddk-libdir=<path>.
+ * Data type: String.
+ * Default value: null
+ */
+ public static final Property VDDK_LIB_DIR = new Property<>("vddk.lib.dir", null, String.class);
+
+ /**
+ * Ordered list of VDDK transports for virt-v2v, passed as -io vddk-transports=<value>.
+ * Example: nbd:nbdssl.
+ * Data type: String.
+ * Default value: null
+ */
+ public static final Property VDDK_TRANSPORTS = new Property<>("vddk.transports", null, String.class);
+
+ /**
+ * vCenter TLS certificate thumbprint used by virt-v2v VDDK mode, passed as -io vddk-thumbprint=<value>.
+ * If unset, the KVM host computes it at runtime from the vCenter endpoint.
+ * Data type: String.
+ * Default value: null
+ */
+ public static final Property VDDK_THUMBPRINT = new Property<>("vddk.thumbprint", null, String.class);
+
/**
* BGP controll CIDR
* Data type: String.
@@ -885,6 +923,11 @@ public Property getWorkers() {
*/
public static final Property CREATE_FULL_CLONE = new Property<>("create.full.clone", false);
+ /**
+ * Time, in seconds, to wait before retrying to rebase during the incremental snapshot process.
+ * */
+ public static final Property INCREMENTAL_SNAPSHOT_RETRY_REBASE_WAIT = new Property<>("incremental.snapshot.retry.rebase.wait", 60);
+
public static class Property {
private String name;
diff --git a/agent/src/main/java/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java b/agent/src/main/java/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
index 26f9d4b3d732..ef98fa532ecb 100644
--- a/agent/src/main/java/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
+++ b/agent/src/main/java/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
@@ -175,12 +175,12 @@ private Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, fin
try {
is.close();
} catch (final IOException e) {
- logger.warn("Exception when closing , console proxy address : {}", proxyManagementIp);
+ logger.warn("Exception when closing , console proxy address: {}", proxyManagementIp);
success = false;
}
}
} catch (final IOException e) {
- logger.warn("Unable to open console proxy command port url, console proxy address : {}", proxyManagementIp);
+ logger.warn("Unable to open console proxy command port url, console proxy address: {}", proxyManagementIp);
success = false;
}
@@ -331,7 +331,7 @@ private void launchConsoleProxy(final byte[] ksBits, final String ksPassword, fi
final Object resource = this;
logger.info("Building class loader for com.cloud.consoleproxy.ConsoleProxy");
if (consoleProxyMain == null) {
- logger.info("Running com.cloud.consoleproxy.ConsoleProxy with encryptor password={}", encryptorPassword);
+ logger.info("Running com.cloud.consoleproxy.ConsoleProxy");
consoleProxyMain = new Thread(new ManagedContextRunnable() {
@Override
protected void runInContext() {
diff --git a/api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java b/api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java
index 6396e3deb723..23167c5c53b0 100644
--- a/api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java
+++ b/api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java
@@ -119,8 +119,7 @@ protected OVFPropertyTO createOVFPropertyFromNode(Node node, int index, String c
boolean password = StringUtils.isNotBlank(passStr) && passStr.equalsIgnoreCase("true");
String label = ovfParser.getChildNodeValue(node, "Label");
String description = ovfParser.getChildNodeValue(node, "Description");
- logger.debug("Creating OVF property index " + index + (category == null ? "" : " for category " + category)
- + " with key = " + key);
+ logger.debug("Creating OVF property index {} {} with key = {}", index, (category == null ? "" : " for category " + category), key);
return new OVFPropertyTO(key, type, value, qualifiers, userConfigurable,
label, description, password, index, category);
}
@@ -152,7 +151,7 @@ public List getConfigurableOVFPropertiesFromDocument(Document doc
if (child.getNodeName().equalsIgnoreCase("Category") ||
child.getNodeName().endsWith(":Category")) {
lastCategoryFound = child.getTextContent();
- logger.info("Category found " + lastCategoryFound);
+ logger.info("Category found {}", lastCategoryFound);
} else if (child.getNodeName().equalsIgnoreCase("Property") ||
child.getNodeName().endsWith(":Property")) {
OVFPropertyTO prop = createOVFPropertyFromNode(child, propertyIndex, lastCategoryFound);
@@ -250,13 +249,13 @@ private List matchHardwareItemsToDiskAndFilesInformation(List extractDisksFromOvfDocumentTree(Document doc) {
od._controller = getControllerType(items, od._diskId);
vd.add(od);
}
- if (logger.isTraceEnabled()) {
- logger.trace(String.format("found %d disk definitions",vd.size()));
- }
+ logger.trace("Found {} disk definitions", vd.size());
return vd;
}
@@ -366,9 +363,7 @@ protected List extractFilesFromOvfDocumentTree(File ovfFile, Document d
vf.add(of);
}
}
- if (logger.isTraceEnabled()) {
- logger.trace(String.format("found %d file definitions in %s",vf.size(), ovfFile.getPath()));
- }
+ logger.trace("Found {} file definitions in {}", vf.size(), ovfFile.getPath());
return vf;
}
@@ -506,7 +501,7 @@ private void writeDocumentToFile(String newOvfFilePath, Document doc) {
outfile.write(writer.toString());
outfile.close();
} catch (IOException | TransformerException e) {
- logger.info("Unexpected exception caught while rewriting OVF:" + e.getMessage(), e);
+ logger.info("Unexpected exception caught while rewriting OVF: {}", e.getMessage(), e);
throw new CloudRuntimeException(e);
}
}
@@ -522,9 +517,7 @@ OVFFile getFileDefinitionFromDiskDefinition(String fileRef, List files)
public List getNetPrerequisitesFromDocument(Document doc) throws InternalErrorException {
if (doc == null) {
- if (logger.isTraceEnabled()) {
- logger.trace("no document to parse; returning no prerequisite networks");
- }
+ logger.trace("No document to parse; returning no prerequisite networks");
return Collections.emptyList();
}
@@ -540,9 +533,7 @@ public List getNetPrerequisitesFromDocument(Document doc) throws I
private void matchNicsToNets(Map nets, Node systemElement) {
final DocumentTraversal traversal = (DocumentTraversal) systemElement;
final NodeIterator iterator = traversal.createNodeIterator(systemElement, NodeFilter.SHOW_ELEMENT, null, true);
- if (logger.isTraceEnabled()) {
- logger.trace(String.format("starting out with %d network-prerequisites, parsing hardware",nets.size()));
- }
+ logger.trace("Starting out with {} network-prerequisites, parsing hardware", nets.size());
int nicCount = 0;
for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) {
final Element e = (Element) n;
@@ -550,9 +541,7 @@ private void matchNicsToNets(Map nets, Node systemElement)
nicCount++;
String name = e.getTextContent(); // should be in our nets
if(nets.get(name) == null) {
- if(logger.isInfoEnabled()) {
- logger.info(String.format("found a nic definition without a network definition byname %s, adding it to the list.", name));
- }
+ logger.info("Found a NIC definition without a Network definition by name {}, adding it to the list.", name);
nets.put(name, new OVFNetworkTO());
}
OVFNetworkTO thisNet = nets.get(name);
@@ -561,9 +550,7 @@ private void matchNicsToNets(Map nets, Node systemElement)
}
}
}
- if (logger.isTraceEnabled()) {
- logger.trace(String.format("ending up with %d network-prerequisites, parsed %d nics", nets.size(), nicCount));
- }
+ logger.trace("Ending up with {} network-prerequisites, parsed {} nics", nets.size(), nicCount);
}
/**
@@ -585,7 +572,7 @@ private void fillNicPrerequisites(OVFNetworkTO nic, Node parentNode) {
int addressOnParent = Integer.parseInt(addressOnParentStr);
nic.setAddressOnParent(addressOnParent);
} catch (NumberFormatException e) {
- logger.warn("Encountered element of type \"AddressOnParent\", that could not be parse to an integer number: " + addressOnParentStr);
+ logger.warn("Encountered element of type \"AddressOnParent\", that could not be parse to an integer number: {}", addressOnParentStr);
}
boolean automaticAllocation = StringUtils.isNotBlank(automaticAllocationStr) && Boolean.parseBoolean(automaticAllocationStr);
@@ -597,7 +584,7 @@ private void fillNicPrerequisites(OVFNetworkTO nic, Node parentNode) {
int instanceId = Integer.parseInt(instanceIdStr);
nic.setInstanceID(instanceId);
} catch (NumberFormatException e) {
- logger.warn("Encountered element of type \"InstanceID\", that could not be parse to an integer number: " + instanceIdStr);
+ logger.warn("Encountered element of type \"InstanceID\", that could not be parse to an integer number: {}", instanceIdStr);
}
nic.setResourceSubType(resourceSubType);
@@ -630,9 +617,7 @@ private Map getNetworksFromDocumentTree(Document doc) {
nets.put(networkName,network);
}
- if (logger.isTraceEnabled()) {
- logger.trace(String.format("found %d networks in template", nets.size()));
- }
+ logger.trace("Found {} Networks in Template", nets.size());
return nets;
}
@@ -771,7 +756,7 @@ private Long getLongValueFromString(String value) {
try {
return Long.parseLong(value);
} catch (NumberFormatException e) {
- logger.debug("Could not parse the value: " + value + ", ignoring it");
+ logger.debug("Could not parse the value: {}, ignoring it", value);
}
}
return null;
@@ -782,7 +767,7 @@ private Integer getIntValueFromString(String value) {
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
- logger.debug("Could not parse the value: " + value + ", ignoring it");
+ logger.debug("Could not parse the value: {}, ignoring it", value);
}
}
return null;
@@ -820,7 +805,7 @@ public List getEulaSectionsFromDocument(Document doc) {
try {
compressedLicense = compressOVFEula(eulaLicense);
} catch (IOException e) {
- logger.error("Could not compress the license for info " + eulaInfo);
+ logger.error("Could not compress the license for info {}", eulaInfo);
continue;
}
OVFEulaSectionTO eula = new OVFEulaSectionTO(eulaInfo, compressedLicense, eulaIndex);
diff --git a/api/src/main/java/com/cloud/agent/api/storage/OVFParser.java b/api/src/main/java/com/cloud/agent/api/storage/OVFParser.java
index 38f478d63cf8..316ab4ea87b9 100644
--- a/api/src/main/java/com/cloud/agent/api/storage/OVFParser.java
+++ b/api/src/main/java/com/cloud/agent/api/storage/OVFParser.java
@@ -54,7 +54,7 @@ public OVFParser() {
documentBuilderFactory.setNamespaceAware(true);
documentBuilder = documentBuilderFactory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
- logger.error("Cannot start the OVF parser: " + e.getMessage(), e);
+ logger.error("Cannot start the OVF parser: {}", e.getMessage(), e);
}
}
@@ -70,7 +70,7 @@ public Document parseOVFFile(String ovfFilePath) {
try {
return documentBuilder.parse(new File(ovfFilePath));
} catch (SAXException | IOException e) {
- logger.error("Error parsing " + ovfFilePath + " " + e.getMessage(), e);
+ logger.error("Error parsing {} {}", ovfFilePath, e.getMessage(), e);
return null;
}
}
diff --git a/api/src/main/java/com/cloud/agent/api/to/BucketTO.java b/api/src/main/java/com/cloud/agent/api/to/BucketTO.java
index f7e4bfea80fb..fd8237998a74 100644
--- a/api/src/main/java/com/cloud/agent/api/to/BucketTO.java
+++ b/api/src/main/java/com/cloud/agent/api/to/BucketTO.java
@@ -26,10 +26,13 @@ public final class BucketTO {
private String secretKey;
+ private long accountId;
+
public BucketTO(Bucket bucket) {
this.name = bucket.getName();
this.accessKey = bucket.getAccessKey();
this.secretKey = bucket.getSecretKey();
+ this.accountId = bucket.getAccountId();
}
public BucketTO(String name) {
@@ -47,4 +50,8 @@ public String getAccessKey() {
public String getSecretKey() {
return this.secretKey;
}
+
+ public long getAccountId() {
+ return this.accountId;
+ }
}
diff --git a/api/src/main/java/com/cloud/agent/api/to/NicTO.java b/api/src/main/java/com/cloud/agent/api/to/NicTO.java
index ca95fcfd6790..2ed7d9f9a201 100644
--- a/api/src/main/java/com/cloud/agent/api/to/NicTO.java
+++ b/api/src/main/java/com/cloud/agent/api/to/NicTO.java
@@ -33,6 +33,7 @@ public class NicTO extends NetworkTO {
boolean dpdkEnabled;
Integer mtu;
Long networkId;
+ boolean enabled;
String networkSegmentName;
@@ -154,4 +155,12 @@ public String getNetworkSegmentName() {
public void setNetworkSegmentName(String networkSegmentName) {
this.networkSegmentName = networkSegmentName;
}
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
}
diff --git a/api/src/main/java/com/cloud/agent/api/to/RemoteInstanceTO.java b/api/src/main/java/com/cloud/agent/api/to/RemoteInstanceTO.java
index 18737c584b34..7daeb9649177 100644
--- a/api/src/main/java/com/cloud/agent/api/to/RemoteInstanceTO.java
+++ b/api/src/main/java/com/cloud/agent/api/to/RemoteInstanceTO.java
@@ -36,13 +36,17 @@ public class RemoteInstanceTO implements Serializable {
private String vcenterPassword;
private String vcenterHost;
private String datacenterName;
+ private String clusterName;
+ private String hostName;
public RemoteInstanceTO() {
}
- public RemoteInstanceTO(String instanceName) {
+ public RemoteInstanceTO(String instanceName, String clusterName, String hostName) {
this.hypervisorType = Hypervisor.HypervisorType.VMware;
this.instanceName = instanceName;
+ this.clusterName = clusterName;
+ this.hostName = hostName;
}
public RemoteInstanceTO(String instanceName, String instancePath, String vcenterHost, String vcenterUsername, String vcenterPassword, String datacenterName) {
@@ -55,6 +59,12 @@ public RemoteInstanceTO(String instanceName, String instancePath, String vcenter
this.datacenterName = datacenterName;
}
+ public RemoteInstanceTO(String instanceName, String instancePath, String vcenterHost, String vcenterUsername, String vcenterPassword, String datacenterName, String clusterName, String hostName) {
+ this(instanceName, instancePath, vcenterHost, vcenterUsername, vcenterPassword, datacenterName);
+ this.clusterName = clusterName;
+ this.hostName = hostName;
+ }
+
public Hypervisor.HypervisorType getHypervisorType() {
return this.hypervisorType;
}
@@ -82,4 +92,12 @@ public String getVcenterHost() {
public String getDatacenterName() {
return datacenterName;
}
+
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ public String getHostName() {
+ return hostName;
+ }
}
diff --git a/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java
index e26cc1e9f029..9af6c731fd24 100644
--- a/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java
+++ b/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java
@@ -51,6 +51,7 @@ public class VirtualMachineTO {
private long minRam;
private long maxRam;
+ private long requestedRam;
private String hostName;
private String arch;
private String os;
@@ -207,15 +208,20 @@ public long getMinRam() {
return minRam;
}
- public void setRam(long minRam, long maxRam) {
+ public void setRam(long minRam, long maxRam, long requestedRam) {
this.minRam = minRam;
this.maxRam = maxRam;
+ this.requestedRam = requestedRam;
}
public long getMaxRam() {
return maxRam;
}
+ public long getRequestedRam() {
+ return requestedRam;
+ }
+
public String getHostName() {
return hostName;
}
diff --git a/api/src/main/java/com/cloud/agent/manager/allocator/HostAllocator.java b/api/src/main/java/com/cloud/agent/manager/allocator/HostAllocator.java
index 604720aaa290..5d028d31d5b6 100644
--- a/api/src/main/java/com/cloud/agent/manager/allocator/HostAllocator.java
+++ b/api/src/main/java/com/cloud/agent/manager/allocator/HostAllocator.java
@@ -22,19 +22,11 @@
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
-import com.cloud.offering.ServiceOffering;
import com.cloud.utils.component.Adapter;
-import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
public interface HostAllocator extends Adapter {
- /**
- * @param UserVm vm
- * @param ServiceOffering offering
- **/
- boolean isVirtualMachineUpgradable(final VirtualMachine vm, final ServiceOffering offering);
-
/**
* Determines which physical hosts are suitable to
* allocate the guest virtual machines on
@@ -49,31 +41,6 @@ public interface HostAllocator extends Adapter {
public List allocateTo(VirtualMachineProfile vmProfile, DeploymentPlan plan, Type type, ExcludeList avoid, int returnUpTo);
- /**
- * Determines which physical hosts are suitable to allocate the guest
- * virtual machines on
- *
- * Allocators must set any other hosts not considered for allocation in the
- * ExcludeList avoid. Thus the avoid set and the list of hosts suitable,
- * together must cover the entire host set in the cluster.
- *
- * @param VirtualMachineProfile
- * vmProfile
- * @param DeploymentPlan
- * plan
- * @param GuestType
- * type
- * @param ExcludeList
- * avoid
- * @param int returnUpTo (use -1 to return all possible hosts)
- * @param boolean considerReservedCapacity (default should be true, set to
- * false if host capacity calculation should not look at reserved
- * capacity)
- * @return List List of hosts that are suitable for VM allocation
- **/
-
- public List allocateTo(VirtualMachineProfile vmProfile, DeploymentPlan plan, Type type, ExcludeList avoid, int returnUpTo, boolean considerReservedCapacity);
-
/**
* Determines which physical hosts are suitable to allocate the guest
* virtual machines on
diff --git a/api/src/main/java/com/cloud/api/commands/ListRecurringSnapshotScheduleCmd.java b/api/src/main/java/com/cloud/api/commands/ListRecurringSnapshotScheduleCmd.java
index d34c09c94fde..d8aa13710e23 100644
--- a/api/src/main/java/com/cloud/api/commands/ListRecurringSnapshotScheduleCmd.java
+++ b/api/src/main/java/com/cloud/api/commands/ListRecurringSnapshotScheduleCmd.java
@@ -35,10 +35,10 @@ public class ListRecurringSnapshotScheduleCmd extends BaseListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.SNAPSHOT_POLICY_ID, type = CommandType.LONG, description = "lists recurring snapshots by snapshot policy ID")
+ @Parameter(name = ApiConstants.SNAPSHOT_POLICY_ID, type = CommandType.LONG, description = "Lists recurring Snapshots by Snapshot policy ID")
private Long snapshotPolicyId;
- @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.LONG, required = true, description = "list recurring snapshots by volume ID")
+ @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.LONG, required = true, description = "List recurring Snapshots by volume ID")
private Long volumeId;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/com/cloud/configuration/ConfigurationService.java b/api/src/main/java/com/cloud/configuration/ConfigurationService.java
index 438283136d2c..729f72b23ca2 100644
--- a/api/src/main/java/com/cloud/configuration/ConfigurationService.java
+++ b/api/src/main/java/com/cloud/configuration/ConfigurationService.java
@@ -24,15 +24,18 @@
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.command.admin.config.ResetCfgCmd;
import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
+import org.apache.cloudstack.api.command.admin.network.CloneNetworkOfferingCmd;
import org.apache.cloudstack.api.command.admin.network.CreateGuestNetworkIpv6PrefixCmd;
import org.apache.cloudstack.api.command.admin.network.CreateManagementNetworkIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
import org.apache.cloudstack.api.command.admin.network.DeleteGuestNetworkIpv6PrefixCmd;
import org.apache.cloudstack.api.command.admin.network.DeleteManagementNetworkIpRangeCmd;
import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
import org.apache.cloudstack.api.command.admin.network.ListGuestNetworkIpv6PrefixesCmd;
+import org.apache.cloudstack.api.command.admin.network.NetworkOfferingBaseCmd;
import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd;
import org.apache.cloudstack.api.command.admin.network.UpdatePodManagementNetworkIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.offering.CloneDiskOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.CloneServiceOfferingCmd;
import org.apache.cloudstack.api.command.admin.offering.CreateDiskOfferingCmd;
import org.apache.cloudstack.api.command.admin.offering.CreateServiceOfferingCmd;
import org.apache.cloudstack.api.command.admin.offering.DeleteDiskOfferingCmd;
@@ -105,6 +108,33 @@ public interface ConfigurationService {
*/
ServiceOffering createServiceOffering(CreateServiceOfferingCmd cmd);
+ /**
+ * Clones a service offering with optional parameter overrides
+ *
+ * @param cmd
+ * the command object that specifies the source offering ID and optional parameter overrides
+ * @return the newly created service offering cloned from source, null otherwise
+ */
+ ServiceOffering cloneServiceOffering(CloneServiceOfferingCmd cmd);
+
+ /**
+ * Clones a disk offering with optional parameter overrides
+ *
+ * @param cmd
+ * the command object that specifies the source offering ID and optional parameter overrides
+ * @return the newly created disk offering cloned from source, null otherwise
+ */
+ DiskOffering cloneDiskOffering(CloneDiskOfferingCmd cmd);
+
+ /**
+ * Clones a network offering with optional parameter overrides
+ *
+ * @param cmd
+ * the command object that specifies the source offering ID and optional parameter overrides
+ * @return the newly created network offering cloned from source, null otherwise
+ */
+ NetworkOffering cloneNetworkOffering(CloneNetworkOfferingCmd cmd);
+
/**
* Updates a service offering
*
@@ -282,7 +312,7 @@ Vlan updateVlanAndPublicIpRange(UpdateVlanIpRangeCmd cmd) throws ConcurrentOpera
boolean releasePublicIpRange(ReleasePublicIpRangeCmd cmd);
- NetworkOffering createNetworkOffering(CreateNetworkOfferingCmd cmd);
+ NetworkOffering createNetworkOffering(NetworkOfferingBaseCmd cmd);
NetworkOffering updateNetworkOffering(UpdateNetworkOfferingCmd cmd);
diff --git a/api/src/main/java/com/cloud/cpu/CPU.java b/api/src/main/java/com/cloud/cpu/CPU.java
index 3016e542db65..11b38b73da53 100644
--- a/api/src/main/java/com/cloud/cpu/CPU.java
+++ b/api/src/main/java/com/cloud/cpu/CPU.java
@@ -22,7 +22,8 @@ public class CPU {
public enum CPUArch {
x86("i686", 32),
amd64("x86_64", 64),
- arm64("aarch64", 64);
+ arm64("aarch64", 64),
+ s390x("s390x", 64);
private final String type;
private final int bits;
diff --git a/api/src/main/java/com/cloud/deploy/DeploymentClusterPlanner.java b/api/src/main/java/com/cloud/deploy/DeploymentClusterPlanner.java
index d127e4bdd660..9471c3d5c84c 100644
--- a/api/src/main/java/com/cloud/deploy/DeploymentClusterPlanner.java
+++ b/api/src/main/java/com/cloud/deploy/DeploymentClusterPlanner.java
@@ -62,11 +62,11 @@ public interface DeploymentClusterPlanner extends DeploymentPlanner {
"vm.allocation.algorithm",
"Advanced",
"random",
- "Order in which hosts within a cluster will be considered for VM allocation. The value can be 'random', 'firstfit', 'userdispersing', 'userconcentratedpod_random', 'userconcentratedpod_firstfit', or 'firstfitleastconsumed'.",
+ "Order in which hosts within a cluster will be considered for VM allocation. The value can be 'random', 'firstfit', 'userdispersing', or 'firstfitleastconsumed'.",
true,
ConfigKey.Scope.Global, null, null, null, null, null,
ConfigKey.Kind.Select,
- "random,firstfit,userdispersing,userconcentratedpod_random,userconcentratedpod_firstfit,firstfitleastconsumed");
+ "random,firstfit,userdispersing,firstfitleastconsumed");
/**
* This is called to determine list of possible clusters where a virtual
diff --git a/api/src/main/java/com/cloud/deploy/DeploymentPlanner.java b/api/src/main/java/com/cloud/deploy/DeploymentPlanner.java
index 354f9cfaac53..22d796d4a775 100644
--- a/api/src/main/java/com/cloud/deploy/DeploymentPlanner.java
+++ b/api/src/main/java/com/cloud/deploy/DeploymentPlanner.java
@@ -70,7 +70,7 @@ public interface DeploymentPlanner extends Adapter {
boolean canHandle(VirtualMachineProfile vm, DeploymentPlan plan, ExcludeList avoid);
public enum AllocationAlgorithm {
- random, firstfit, userdispersing, userconcentratedpod_random, userconcentratedpod_firstfit;
+ random, firstfit, userdispersing, firstfitleastconsumed;
}
public enum PlannerResourceUsage {
diff --git a/api/src/main/java/com/cloud/event/EventTypes.java b/api/src/main/java/com/cloud/event/EventTypes.java
index 38e601c790a7..42395bf89992 100644
--- a/api/src/main/java/com/cloud/event/EventTypes.java
+++ b/api/src/main/java/com/cloud/event/EventTypes.java
@@ -298,8 +298,9 @@ public class EventTypes {
public static final String EVENT_REGISTER_CNI_CONFIG = "REGISTER.CNI.CONFIG";
public static final String EVENT_DELETE_CNI_CONFIG = "DELETE.CNI.CONFIG";
- //register for user API and secret keys
+ //user API and secret keys
public static final String EVENT_REGISTER_FOR_SECRET_API_KEY = "REGISTER.USER.KEY";
+ public static final String EVENT_DELETE_SECRET_API_KEY = "DELETE.USER.KEY";
public static final String API_KEY_ACCESS_UPDATE = "API.KEY.ACCESS.UPDATE";
// Template Events
@@ -374,11 +375,13 @@ public class EventTypes {
// Service Offerings
public static final String EVENT_SERVICE_OFFERING_CREATE = "SERVICE.OFFERING.CREATE";
+ public static final String EVENT_SERVICE_OFFERING_CLONE = "SERVICE.OFFERING.CLONE";
public static final String EVENT_SERVICE_OFFERING_EDIT = "SERVICE.OFFERING.EDIT";
public static final String EVENT_SERVICE_OFFERING_DELETE = "SERVICE.OFFERING.DELETE";
// Disk Offerings
public static final String EVENT_DISK_OFFERING_CREATE = "DISK.OFFERING.CREATE";
+ public static final String EVENT_DISK_OFFERING_CLONE = "DISK.OFFERING.CLONE";
public static final String EVENT_DISK_OFFERING_EDIT = "DISK.OFFERING.EDIT";
public static final String EVENT_DISK_OFFERING_DELETE = "DISK.OFFERING.DELETE";
@@ -399,6 +402,7 @@ public class EventTypes {
// Network offerings
public static final String EVENT_NETWORK_OFFERING_CREATE = "NETWORK.OFFERING.CREATE";
+ public static final String EVENT_NETWORK_OFFERING_CLONE = "NETWORK.OFFERING.CLONE";
public static final String EVENT_NETWORK_OFFERING_ASSIGN = "NETWORK.OFFERING.ASSIGN";
public static final String EVENT_NETWORK_OFFERING_EDIT = "NETWORK.OFFERING.EDIT";
public static final String EVENT_NETWORK_OFFERING_REMOVE = "NETWORK.OFFERING.REMOVE";
@@ -503,6 +507,7 @@ public class EventTypes {
public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE = "VPN.S2S.CUSTOMER.GATEWAY.CREATE";
public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE = "VPN.S2S.CUSTOMER.GATEWAY.DELETE";
public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE = "VPN.S2S.CUSTOMER.GATEWAY.UPDATE";
+ public static final String EVENT_S2S_VPN_GATEWAY_OBSOLETE_PARAMS = "VPN.S2S.GATEWAY.OBSOLETE.PARAMS";
public static final String EVENT_S2S_VPN_CONNECTION_CREATE = "VPN.S2S.CONNECTION.CREATE";
public static final String EVENT_S2S_VPN_CONNECTION_DELETE = "VPN.S2S.CONNECTION.DELETE";
public static final String EVENT_S2S_VPN_CONNECTION_RESET = "VPN.S2S.CONNECTION.RESET";
@@ -582,6 +587,7 @@ public class EventTypes {
// Network ACL
public static final String EVENT_NETWORK_ACL_CREATE = "NETWORK.ACL.CREATE";
+ public static final String EVENT_NETWORK_ACL_IMPORT = "NETWORK.ACL.IMPORT";
public static final String EVENT_NETWORK_ACL_DELETE = "NETWORK.ACL.DELETE";
public static final String EVENT_NETWORK_ACL_REPLACE = "NETWORK.ACL.REPLACE";
public static final String EVENT_NETWORK_ACL_UPDATE = "NETWORK.ACL.UPDATE";
@@ -596,6 +602,7 @@ public class EventTypes {
// VPC offerings
public static final String EVENT_VPC_OFFERING_CREATE = "VPC.OFFERING.CREATE";
+ public static final String EVENT_VPC_OFFERING_CLONE = "VPC.OFFERING.CLONE";
public static final String EVENT_VPC_OFFERING_UPDATE = "VPC.OFFERING.UPDATE";
public static final String EVENT_VPC_OFFERING_DELETE = "VPC.OFFERING.DELETE";
@@ -628,6 +635,7 @@ public class EventTypes {
// Backup and Recovery events
public static final String EVENT_VM_BACKUP_IMPORT_OFFERING = "BACKUP.IMPORT.OFFERING";
+ public static final String EVENT_VM_BACKUP_OFFERING_CLONE = "BACKUP.OFFERING.CLONE";
public static final String EVENT_VM_BACKUP_OFFERING_ASSIGN = "BACKUP.OFFERING.ASSIGN";
public static final String EVENT_VM_BACKUP_OFFERING_REMOVE = "BACKUP.OFFERING.REMOVE";
public static final String EVENT_VM_BACKUP_CREATE = "BACKUP.CREATE";
@@ -1043,11 +1051,13 @@ public class EventTypes {
// Service Offerings
entityEventDetails.put(EVENT_SERVICE_OFFERING_CREATE, ServiceOffering.class);
+ entityEventDetails.put(EVENT_SERVICE_OFFERING_CLONE, ServiceOffering.class);
entityEventDetails.put(EVENT_SERVICE_OFFERING_EDIT, ServiceOffering.class);
entityEventDetails.put(EVENT_SERVICE_OFFERING_DELETE, ServiceOffering.class);
// Disk Offerings
entityEventDetails.put(EVENT_DISK_OFFERING_CREATE, DiskOffering.class);
+ entityEventDetails.put(EVENT_DISK_OFFERING_CLONE, DiskOffering.class);
entityEventDetails.put(EVENT_DISK_OFFERING_EDIT, DiskOffering.class);
entityEventDetails.put(EVENT_DISK_OFFERING_DELETE, DiskOffering.class);
@@ -1068,6 +1078,7 @@ public class EventTypes {
// Network offerings
entityEventDetails.put(EVENT_NETWORK_OFFERING_CREATE, NetworkOffering.class);
+ entityEventDetails.put(EVENT_NETWORK_OFFERING_CLONE, NetworkOffering.class);
entityEventDetails.put(EVENT_NETWORK_OFFERING_ASSIGN, NetworkOffering.class);
entityEventDetails.put(EVENT_NETWORK_OFFERING_EDIT, NetworkOffering.class);
entityEventDetails.put(EVENT_NETWORK_OFFERING_REMOVE, NetworkOffering.class);
@@ -1151,6 +1162,7 @@ public class EventTypes {
entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE, Site2SiteCustomerGateway.class);
entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE, Site2SiteCustomerGateway.class);
entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE, Site2SiteCustomerGateway.class);
+ entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_OBSOLETE_PARAMS, Site2SiteCustomerGateway.class);
entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_CREATE, Site2SiteVpnConnection.class);
entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_DELETE, Site2SiteVpnConnection.class);
entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_RESET, Site2SiteVpnConnection.class);
diff --git a/api/src/main/java/com/cloud/ha/Investigator.java b/api/src/main/java/com/cloud/ha/Investigator.java
index 88d802a1ce44..00371d395f5a 100644
--- a/api/src/main/java/com/cloud/ha/Investigator.java
+++ b/api/src/main/java/com/cloud/ha/Investigator.java
@@ -26,17 +26,19 @@ public interface Investigator extends Adapter {
* Returns if the vm is still alive.
*
* @param vm to work on.
+ * @return true if vm is alive, otherwise false
*/
- public boolean isVmAlive(VirtualMachine vm, Host host) throws UnknownVM;
+ boolean isVmAlive(VirtualMachine vm, Host host) throws UnknownVM;
- public Status isAgentAlive(Host agent);
+ /**
+ * Returns the agent status of the host.
+ *
+ * @param host
+ * @return status of the host agent
+ */
+ Status getHostAgentStatus(Host host);
class UnknownVM extends Exception {
-
- /**
- *
- */
private static final long serialVersionUID = 1L;
-
};
}
diff --git a/api/src/main/java/com/cloud/host/Host.java b/api/src/main/java/com/cloud/host/Host.java
index 07a0dfce0419..8b14cfd3a390 100644
--- a/api/src/main/java/com/cloud/host/Host.java
+++ b/api/src/main/java/com/cloud/host/Host.java
@@ -57,8 +57,16 @@ public static String[] toStrings(Host.Type... types) {
String HOST_UEFI_ENABLE = "host.uefi.enable";
String HOST_VOLUME_ENCRYPTION = "host.volume.encryption";
String HOST_INSTANCE_CONVERSION = "host.instance.conversion";
+ String HOST_VDDK_SUPPORT = "host.vddk.support";
+ String HOST_VDDK_LIB_DIR = "vddk.lib.dir";
+ String HOST_VDDK_VERSION = "host.vddk.version";
String HOST_OVFTOOL_VERSION = "host.ovftool.version";
String HOST_VIRTV2V_VERSION = "host.virtv2v.version";
+ String HOST_SSH_PORT = "host.ssh.port";
+ String GUEST_OS_CATEGORY_ID = "guest.os.category.id";
+ String GUEST_OS_RULE = "guest.os.rule";
+
+ int DEFAULT_SSH_PORT = 22;
/**
* @return name of the machine.
diff --git a/api/src/main/java/com/cloud/host/HostStats.java b/api/src/main/java/com/cloud/host/HostStats.java
index d14794401fa3..0e72b5f2d9d0 100644
--- a/api/src/main/java/com/cloud/host/HostStats.java
+++ b/api/src/main/java/com/cloud/host/HostStats.java
@@ -36,5 +36,4 @@ public interface HostStats {
public HostStats getHostStats();
public double getLoadAverage();
- // public double getXapiMemoryUsageKBs();
}
diff --git a/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesCluster.java b/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesCluster.java
index ce905b293ff3..80f6a6045c72 100644
--- a/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesCluster.java
+++ b/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesCluster.java
@@ -98,7 +98,7 @@ enum State {
s_fsm.addTransition(State.Running, Event.ScaleDownRequested, State.Scaling);
s_fsm.addTransition(State.Stopped, Event.ScaleUpRequested, State.ScalingStoppedCluster);
s_fsm.addTransition(State.Scaling, Event.OperationSucceeded, State.Running);
- s_fsm.addTransition(State.Scaling, Event.OperationFailed, State.Alert);
+ s_fsm.addTransition(State.Scaling, Event.OperationFailed, State.Running);
s_fsm.addTransition(State.ScalingStoppedCluster, Event.OperationSucceeded, State.Stopped);
s_fsm.addTransition(State.ScalingStoppedCluster, Event.OperationFailed, State.Alert);
diff --git a/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java b/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java
index 37b8907b454a..5a6eaa3f7b9a 100644
--- a/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java
+++ b/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java
@@ -18,6 +18,7 @@
import org.apache.cloudstack.acl.ControlledEntity;
+import java.util.List;
import java.util.Map;
import com.cloud.user.Account;
@@ -33,8 +34,10 @@ enum KubernetesClusterNodeType {
ControlledEntity findByUuid(String uuid);
ControlledEntity findByVmId(long vmId);
void checkVmCanBeDestroyed(UserVm userVm);
+ void checkVmAffinityGroupsCanBeUpdated(UserVm userVm);
boolean isValidNodeType(String nodeType);
Map getServiceOfferingNodeTypeMap(Map> serviceOfferingNodeTypeMap);
Map getTemplateNodeTypeMap(Map> templateNodeTypeMap);
+ Map> getAffinityGroupNodeTypeMap(Map> affinityGroupNodeTypeMap);
void cleanupForAccount(Account account);
}
diff --git a/api/src/main/java/com/cloud/network/Ipv6Service.java b/api/src/main/java/com/cloud/network/Ipv6Service.java
index 4ef5f98c38d8..e6c3b9250a7a 100644
--- a/api/src/main/java/com/cloud/network/Ipv6Service.java
+++ b/api/src/main/java/com/cloud/network/Ipv6Service.java
@@ -45,7 +45,7 @@ public interface Ipv6Service extends PluggableService, Configurable {
static final ConfigKey Ipv6OfferingCreationEnabled = new ConfigKey("Advanced", Boolean.class,
"ipv6.offering.enabled",
"false",
- "Indicates whether creation of IPv6 network/VPC offering is enabled or not.",
+ "Indicates whether creation of IPv6 Network/VPC offering is enabled or not.",
true);
static final ConfigKey Ipv6PrefixSubnetCleanupInterval = new ConfigKey("Advanced", Integer.class,
diff --git a/api/src/main/java/com/cloud/network/Network.java b/api/src/main/java/com/cloud/network/Network.java
index dc94932e31f5..e41eb880ffd5 100644
--- a/api/src/main/java/com/cloud/network/Network.java
+++ b/api/src/main/java/com/cloud/network/Network.java
@@ -325,9 +325,9 @@ enum Event {
public enum State {
- Allocated("Indicates the network configuration is in allocated but not setup"), Setup("Indicates the network configuration is setup"), Implementing(
- "Indicates the network configuration is being implemented"), Implemented("Indicates the network configuration is in use"), Shutdown(
- "Indicates the network configuration is being destroyed"), Destroy("Indicates that the network is destroyed");
+ Allocated("Indicates the Network configuration is in allocated but not setup"), Setup("Indicates the Network configuration is setup"), Implementing(
+ "Indicates the Network configuration is being implemented"), Implemented("Indicates the Network configuration is in use"), Shutdown(
+ "Indicates the Network configuration is being destroyed"), Destroy("Indicates that the Network is destroyed");
protected static final StateMachine2 s_fsm = new StateMachine2();
@@ -510,4 +510,6 @@ public void setIp6Address(String ip6Address) {
Integer getPrivateMtu();
Integer getNetworkCidrSize();
+
+ boolean getKeepMacAddressOnPublicNic();
}
diff --git a/api/src/main/java/com/cloud/network/NetworkModel.java b/api/src/main/java/com/cloud/network/NetworkModel.java
index eb496ac4e0b9..c212e6319eb4 100644
--- a/api/src/main/java/com/cloud/network/NetworkModel.java
+++ b/api/src/main/java/com/cloud/network/NetworkModel.java
@@ -125,6 +125,10 @@ public interface NetworkModel {
*/
String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException;
+ String getUniqueMacAddress(long macAddress, long networkId, long datacenterId) throws InsufficientAddressCapacityException;
+
+ boolean isMACUnique(String mac, long networkId);
+
PublicIpAddress getPublicIpAddress(long ipAddressId);
List extends Vlan> listPodVlans(long podId);
@@ -364,4 +368,8 @@ List generateVmData(String userData, String userDataDetails, String se
boolean checkSecurityGroupSupportForNetwork(Account account, DataCenter zone, List networkIds,
List securityGroupsIds);
+
+ default long getMacIdentifier(Long dataCenterId) {
+ return 0;
+ }
}
diff --git a/api/src/main/java/com/cloud/network/NetworkProfile.java b/api/src/main/java/com/cloud/network/NetworkProfile.java
index 2e8efb489308..d690344a0e38 100644
--- a/api/src/main/java/com/cloud/network/NetworkProfile.java
+++ b/api/src/main/java/com/cloud/network/NetworkProfile.java
@@ -385,6 +385,11 @@ public Integer getNetworkCidrSize() {
return networkCidrSize;
}
+ @Override
+ public boolean getKeepMacAddressOnPublicNic() {
+ return true;
+ }
+
@Override
public String toString() {
return String.format("NetworkProfile %s",
diff --git a/api/src/main/java/com/cloud/network/NetworkService.java b/api/src/main/java/com/cloud/network/NetworkService.java
index 196e1f9aab86..c32bb711c0f2 100644
--- a/api/src/main/java/com/cloud/network/NetworkService.java
+++ b/api/src/main/java/com/cloud/network/NetworkService.java
@@ -81,7 +81,7 @@ public interface NetworkService {
true, ConfigKey.Scope.Zone);
public static final ConfigKey AllowUsersToSpecifyVRMtu = new ConfigKey<>("Advanced", Boolean.class,
- "allow.end.users.to.specify.vr.mtu", "false", "Allow end users to specify VR MTU",
+ "allow.end.users.to.specify.vr.mtu", "false", "Allow end Users to specify VR MTU",
true, ConfigKey.Scope.Zone);
List extends Network> getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner);
@@ -108,6 +108,10 @@ Network createGuestNetwork(long networkOfferingId, String name, String displayTe
PhysicalNetwork physicalNetwork, long zoneId, ControlledEntity.ACLType aclType) throws
InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException;
+ Network createGuestNetwork(long networkOfferingId, String name, String displayText, Account owner,
+ PhysicalNetwork physicalNetwork, long zoneId, ControlledEntity.ACLType aclType, Pair vrIfaceMTUs) throws
+ InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException;
+
Pair, Integer> searchForNetworks(ListNetworksCmd cmd);
boolean deleteNetwork(long networkId, boolean forced);
@@ -228,7 +232,7 @@ Network createPrivateNetwork(String networkName, String displayText, long physic
/**
* Requests an IP address for the guest NIC
*/
- NicSecondaryIp allocateSecondaryGuestIP(long nicId, IpAddresses requestedIpPair) throws InsufficientAddressCapacityException;
+ NicSecondaryIp allocateSecondaryGuestIP(long nicId, IpAddresses requestedIpPair, String description) throws InsufficientAddressCapacityException;
boolean releaseSecondaryIpFromNic(long ipAddressId);
@@ -275,4 +279,6 @@ Network createPrivateNetwork(String networkName, String displayText, long physic
IpAddresses getIpAddressesFromIps(String ipAddress, String ip6Address, String macAddress);
String getNicVlanValueForExternalVm(NicTO nic);
+
+ Long getPreferredNetworkIdForPublicIpRuleAssignment(IpAddress ip, Long networkId);
}
diff --git a/api/src/main/java/com/cloud/network/Networks.java b/api/src/main/java/com/cloud/network/Networks.java
index 9f06a0441118..5f767686dc97 100644
--- a/api/src/main/java/com/cloud/network/Networks.java
+++ b/api/src/main/java/com/cloud/network/Networks.java
@@ -78,7 +78,7 @@ public URI toUri(T value) {
}
@Override
public String getValueFrom(URI uri) {
- return uri.getAuthority();
+ return uri == null ? null : uri.getAuthority();
}
},
Vswitch("vs", String.class), LinkLocal(null, null), Vnet("vnet", Long.class), Storage("storage", Integer.class), Lswitch("lswitch", String.class) {
@@ -96,7 +96,7 @@ public URI toUri(T value) {
*/
@Override
public String getValueFrom(URI uri) {
- return uri.getSchemeSpecificPart();
+ return uri == null ? null : uri.getSchemeSpecificPart();
}
},
Mido("mido", String.class), Pvlan("pvlan", String.class),
@@ -177,7 +177,7 @@ public URI toUri(T value) {
* @return the scheme as BroadcastDomainType
*/
public static BroadcastDomainType getSchemeValue(URI uri) {
- return toEnumValue(uri.getScheme());
+ return toEnumValue(uri == null ? null : uri.getScheme());
}
/**
@@ -191,7 +191,7 @@ public static BroadcastDomainType getTypeOf(String str) throws URISyntaxExceptio
if (com.cloud.dc.Vlan.UNTAGGED.equalsIgnoreCase(str)) {
return Native;
}
- return getSchemeValue(new URI(str));
+ return getSchemeValue(str == null ? null : new URI(str));
}
/**
@@ -220,7 +220,7 @@ public static BroadcastDomainType toEnumValue(String scheme) {
* @return the host part as String
*/
public String getValueFrom(URI uri) {
- return uri.getHost();
+ return uri == null ? null : uri.getHost();
}
/**
@@ -243,7 +243,7 @@ public static String getValue(URI uri) {
* @throws URISyntaxException the string is not even an uri
*/
public static String getValue(String uriString) throws URISyntaxException {
- return getValue(new URI(uriString));
+ return getValue(uriString == null ? null : new URI(uriString));
}
/**
diff --git a/api/src/main/java/com/cloud/network/as/AutoScaleVmGroup.java b/api/src/main/java/com/cloud/network/as/AutoScaleVmGroup.java
index c265c1f36a0a..c05b3bda3db5 100644
--- a/api/src/main/java/com/cloud/network/as/AutoScaleVmGroup.java
+++ b/api/src/main/java/com/cloud/network/as/AutoScaleVmGroup.java
@@ -43,7 +43,7 @@ public static State fromValue(String state) {
} else if (state.equalsIgnoreCase("scaling")) {
return SCALING;
} else {
- throw new IllegalArgumentException("Unexpected AutoScale VM group state : " + state);
+ throw new IllegalArgumentException("Unexpected AutoScale Instance group state : " + state);
}
}
}
diff --git a/api/src/main/java/com/cloud/network/lb/LoadBalancingRulesService.java b/api/src/main/java/com/cloud/network/lb/LoadBalancingRulesService.java
index 0bf06be15d87..b7fe3b26761c 100644
--- a/api/src/main/java/com/cloud/network/lb/LoadBalancingRulesService.java
+++ b/api/src/main/java/com/cloud/network/lb/LoadBalancingRulesService.java
@@ -108,7 +108,7 @@ LoadBalancer createPublicLoadBalancerRule(String xId, String name, String descri
/**
* Assign a virtual machine or list of virtual machines, or Map of to a load balancer.
*/
- boolean assignToLoadBalancer(long lbRuleId, List vmIds, Map> vmIdIpMap, boolean isAutoScaleVM);
+ boolean assignToLoadBalancer(long lbRuleId, List vmIds, Map> vmIdIpMap, Map vmIdNetworkMap, boolean isAutoScaleVM);
boolean assignSSLCertToLoadBalancerRule(Long lbRuleId, String certName, String publicCert, String privateKey);
diff --git a/api/src/main/java/com/cloud/network/rules/LbStickinessMethod.java b/api/src/main/java/com/cloud/network/rules/LbStickinessMethod.java
index 56a0622a52ba..5143611ee828 100644
--- a/api/src/main/java/com/cloud/network/rules/LbStickinessMethod.java
+++ b/api/src/main/java/com/cloud/network/rules/LbStickinessMethod.java
@@ -108,8 +108,7 @@ public LbStickinessMethod(StickinessMethodType methodType, String description) {
}
public void addParam(String name, Boolean required, String description, Boolean isFlag) {
- /* FIXME : UI is breaking if the capability string length is larger , temporarily description is commented out */
- // LbStickinessMethodParam param = new LbStickinessMethodParam(name, required, description);
+ /* is this still a valid comment: FIXME : UI is breaking if the capability string length is larger , temporarily description is commented out */
LbStickinessMethodParam param = new LbStickinessMethodParam(name, required, " ", isFlag);
_paramList.add(param);
return;
@@ -133,7 +132,6 @@ public String getDescription() {
public void setDescription(String description) {
/* FIXME : UI is breaking if the capability string length is larger , temporarily description is commented out */
- //this.description = description;
this._description = " ";
}
}
diff --git a/api/src/main/java/com/cloud/network/vpc/NetworkACLService.java b/api/src/main/java/com/cloud/network/vpc/NetworkACLService.java
index 40aee1f08f1d..84e48d5d5b8a 100644
--- a/api/src/main/java/com/cloud/network/vpc/NetworkACLService.java
+++ b/api/src/main/java/com/cloud/network/vpc/NetworkACLService.java
@@ -19,6 +19,7 @@
import java.util.List;
import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
+import org.apache.cloudstack.api.command.user.network.ImportNetworkACLCmd;
import org.apache.cloudstack.api.command.user.network.ListNetworkACLListsCmd;
import org.apache.cloudstack.api.command.user.network.ListNetworkACLsCmd;
import org.apache.cloudstack.api.command.user.network.MoveNetworkAclItemCmd;
@@ -98,4 +99,6 @@ public interface NetworkACLService {
NetworkACLItem moveNetworkAclRuleToNewPosition(MoveNetworkAclItemCmd moveNetworkAclItemCmd);
NetworkACLItem moveRuleToTheTopInACLList(NetworkACLItem ruleBeingMoved);
+
+ List importNetworkACLRules(ImportNetworkACLCmd cmd) throws ResourceUnavailableException;
}
diff --git a/api/src/main/java/com/cloud/network/vpc/Vpc.java b/api/src/main/java/com/cloud/network/vpc/Vpc.java
index b94089d2d433..a0686e2bf7d0 100644
--- a/api/src/main/java/com/cloud/network/vpc/Vpc.java
+++ b/api/src/main/java/com/cloud/network/vpc/Vpc.java
@@ -107,4 +107,6 @@ public enum State {
String getIp6Dns2();
boolean useRouterIpAsResolver();
+
+ boolean getKeepMacAddressOnPublicNic();
}
diff --git a/api/src/main/java/com/cloud/network/vpc/VpcOffering.java b/api/src/main/java/com/cloud/network/vpc/VpcOffering.java
index 17f49bb36521..f84602232159 100644
--- a/api/src/main/java/com/cloud/network/vpc/VpcOffering.java
+++ b/api/src/main/java/com/cloud/network/vpc/VpcOffering.java
@@ -84,4 +84,6 @@ public enum State {
NetworkOffering.RoutingMode getRoutingMode();
Boolean isSpecifyAsNumber();
+
+ boolean isConserveMode();
}
diff --git a/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java b/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java
index 97b95339ecf3..891cfb02d9df 100644
--- a/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java
+++ b/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java
@@ -20,6 +20,7 @@
import java.util.List;
import java.util.Map;
+import org.apache.cloudstack.api.command.admin.vpc.CloneVPCOfferingCmd;
import org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd;
import org.apache.cloudstack.api.command.admin.vpc.UpdateVPCOfferingCmd;
import org.apache.cloudstack.api.command.user.vpc.ListVPCOfferingsCmd;
@@ -34,12 +35,14 @@ public interface VpcProvisioningService {
VpcOffering createVpcOffering(CreateVPCOfferingCmd cmd);
+ VpcOffering cloneVPCOffering(CloneVPCOfferingCmd cmd);
+
VpcOffering createVpcOffering(String name, String displayText, List supportedServices,
Map> serviceProviders,
Map serviceCapabilitystList, NetUtils.InternetProtocol internetProtocol,
Long serviceOfferingId, String externalProvider, NetworkOffering.NetworkMode networkMode,
List domainIds, List zoneIds, VpcOffering.State state,
- NetworkOffering.RoutingMode routingMode, boolean specifyAsNumber);
+ NetworkOffering.RoutingMode routingMode, boolean specifyAsNumber, boolean conserveMode);
Pair,Integer> listVpcOfferings(ListVPCOfferingsCmd cmd);
diff --git a/api/src/main/java/com/cloud/network/vpc/VpcService.java b/api/src/main/java/com/cloud/network/vpc/VpcService.java
index c1546609d2b7..3d0ba43263f5 100644
--- a/api/src/main/java/com/cloud/network/vpc/VpcService.java
+++ b/api/src/main/java/com/cloud/network/vpc/VpcService.java
@@ -58,7 +58,7 @@ public interface VpcService {
*/
Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr, String networkDomain,
String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2, Boolean displayVpc, Integer publicMtu, Integer cidrSize,
- Long asNumber, List bgpPeerIds, Boolean useVrIpResolver) throws ResourceAllocationException;
+ Long asNumber, List bgpPeerIds, Boolean useVrIpResolver, boolean keepMacAddressOnPublicNic) throws ResourceAllocationException;
/**
* Persists VPC record in the database
@@ -104,7 +104,7 @@ Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, Strin
* @throws ResourceUnavailableException if during restart some resources may not be available
* @throws InsufficientCapacityException if for instance no address space, compute or storage is sufficiently available
*/
- Vpc updateVpc(long vpcId, String vpcName, String displayText, String customId, Boolean displayVpc, Integer mtu, String sourceNatIp) throws ResourceUnavailableException, InsufficientCapacityException;
+ Vpc updateVpc(long vpcId, String vpcName, String displayText, String customId, Boolean displayVpc, Integer mtu, String sourceNatIp, Boolean keepMacAddressOnPublicNic) throws ResourceUnavailableException, InsufficientCapacityException;
/**
* Lists VPC(s) based on the parameters passed to the API call
diff --git a/api/src/main/java/com/cloud/projects/ProjectService.java b/api/src/main/java/com/cloud/projects/ProjectService.java
index 5080cb5a7812..d11e9ae0446d 100644
--- a/api/src/main/java/com/cloud/projects/ProjectService.java
+++ b/api/src/main/java/com/cloud/projects/ProjectService.java
@@ -82,7 +82,7 @@ public interface ProjectService {
Project updateProject(long id, String name, String displayText, String newOwnerName, Long userId, Role newRole) throws ResourceAllocationException;
- boolean addAccountToProject(long projectId, String accountName, String email, Long projectRoleId, Role projectRoleType);
+ boolean addAccountToProject(long projectId, String accountName, String email, Long projectRoleId, Role projectRoleType) throws ResourceAllocationException;
boolean deleteAccountFromProject(long projectId, String accountName);
@@ -100,6 +100,6 @@ public interface ProjectService {
Project findByProjectAccountIdIncludingRemoved(long projectAccountId);
- boolean addUserToProject(Long projectId, String username, String email, Long projectRoleId, Role projectRole);
+ boolean addUserToProject(Long projectId, String username, String email, Long projectRoleId, Role projectRole) throws ResourceAllocationException;
}
diff --git a/api/src/main/java/com/cloud/server/ManagementService.java b/api/src/main/java/com/cloud/server/ManagementService.java
index d2a987bb0787..bcca229c06bc 100644
--- a/api/src/main/java/com/cloud/server/ManagementService.java
+++ b/api/src/main/java/com/cloud/server/ManagementService.java
@@ -71,12 +71,13 @@
import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd;
import org.apache.cloudstack.config.Configuration;
import org.apache.cloudstack.config.ConfigurationGroup;
-import org.apache.cloudstack.framework.config.ConfigKey;
import com.cloud.alert.Alert;
import com.cloud.capacity.Capacity;
import com.cloud.dc.Pod;
import com.cloud.dc.Vlan;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.ManagementServerException;
import com.cloud.exception.ResourceUnavailableException;
@@ -97,6 +98,7 @@
import com.cloud.vm.InstanceGroup;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.VirtualMachineProfile;
/**
* Hopefully this is temporary.
@@ -105,14 +107,6 @@
public interface ManagementService {
static final String Name = "management-server";
- ConfigKey JsInterpretationEnabled = new ConfigKey<>("Hidden"
- , Boolean.class
- , "js.interpretation.enabled"
- , "false"
- , "Enable/Disable all JavaScript interpretation related functionalities to create or update Javascript rules."
- , false
- , ConfigKey.Scope.Global);
-
/**
* returns the a map of the names/values in the configuration table
*
@@ -478,6 +472,19 @@ public interface ManagementService {
Ternary, Integer>, List extends Host>, Map> listHostsForMigrationOfVM(VirtualMachine vm, Long startIndex, Long pageSize, String keyword, List vmList);
+ /**
+ * Apply affinity group constraints and other exclusion rules for VM migration.
+ * This is a helper method that can be used independently for per-iteration affinity checks in DRS.
+ *
+ * @param vm The virtual machine to migrate
+ * @param vmProfile The VM profile
+ * @param plan The deployment plan
+ * @param vmList List of VMs with current/simulated placements for affinity processing
+ * @return ExcludeList containing hosts to avoid
+ */
+ ExcludeList applyAffinityConstraints(VirtualMachine vm, VirtualMachineProfile vmProfile,
+ DeploymentPlan plan, List vmList);
+
/**
* List storage pools for live migrating of a volume. The API returns list of all pools in the cluster to which the
* volume can be migrated. Current pool is not included in the list. In case of vSphere datastore cluster storage pools,
@@ -518,6 +525,4 @@ VirtualMachine upgradeSystemVM(ScaleSystemVMCmd cmd) throws ResourceUnavailableE
boolean removeManagementServer(RemoveManagementServerCmd cmd);
- void checkJsInterpretationAllowedIfNeededForParameterValue(String paramName, boolean paramValue);
-
}
diff --git a/api/src/main/java/com/cloud/server/ResourceTag.java b/api/src/main/java/com/cloud/server/ResourceTag.java
index b3026deceff8..32305753f1ae 100644
--- a/api/src/main/java/com/cloud/server/ResourceTag.java
+++ b/api/src/main/java/com/cloud/server/ResourceTag.java
@@ -16,14 +16,14 @@
// under the License.
package com.cloud.server;
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
public interface ResourceTag extends ControlledEntity, Identity, InternalIdentity {
// FIXME - extract enum to another interface as its used both by resourceTags and resourceMetaData code
@@ -70,7 +70,7 @@ public enum ResourceObjectType {
GuestOs(false, true),
NetworkOffering(false, true),
VpcOffering(true, false),
- Domain(false, false, true),
+ Domain(true, false, true),
ObjectStore(false, false, true);
diff --git a/api/src/main/java/com/cloud/storage/Storage.java b/api/src/main/java/com/cloud/storage/Storage.java
index 5b3e97698fda..ddf5978497ba 100644
--- a/api/src/main/java/com/cloud/storage/Storage.java
+++ b/api/src/main/java/com/cloud/storage/Storage.java
@@ -170,6 +170,7 @@ public static enum StoragePoolType {
ISO(false, false, EncryptionSupport.Unsupported), // for iso image
LVM(false, false, EncryptionSupport.Unsupported), // XenServer local LVM SR
CLVM(true, false, EncryptionSupport.Unsupported),
+ CLVM_NG(true, false, EncryptionSupport.Hypervisor),
RBD(true, true, EncryptionSupport.Unsupported), // http://libvirt.org/storage.html#StorageBackendRBD
SharedMountPoint(true, true, EncryptionSupport.Hypervisor),
VMFS(true, true, EncryptionSupport.Unsupported), // VMware VMFS storage
diff --git a/api/src/main/java/com/cloud/storage/VMTemplateStorageResourceAssoc.java b/api/src/main/java/com/cloud/storage/VMTemplateStorageResourceAssoc.java
index db702a61f2bc..7d5b2d7c57d7 100644
--- a/api/src/main/java/com/cloud/storage/VMTemplateStorageResourceAssoc.java
+++ b/api/src/main/java/com/cloud/storage/VMTemplateStorageResourceAssoc.java
@@ -23,9 +23,10 @@
public interface VMTemplateStorageResourceAssoc extends InternalIdentity {
public static enum Status {
- UNKNOWN, DOWNLOAD_ERROR, NOT_DOWNLOADED, DOWNLOAD_IN_PROGRESS, DOWNLOADED, ABANDONED, UPLOADED, NOT_UPLOADED, UPLOAD_ERROR, UPLOAD_IN_PROGRESS, CREATING, CREATED, BYPASSED
+ UNKNOWN, DOWNLOAD_ERROR, NOT_DOWNLOADED, DOWNLOAD_IN_PROGRESS, DOWNLOADED, ABANDONED, LIMIT_REACHED, UPLOADED, NOT_UPLOADED, UPLOAD_ERROR, UPLOAD_IN_PROGRESS, CREATING, CREATED, BYPASSED
}
+ List ERROR_DOWNLOAD_STATES = List.of(Status.DOWNLOAD_ERROR, Status.ABANDONED, Status.LIMIT_REACHED, Status.UNKNOWN);
List PENDING_DOWNLOAD_STATES = List.of(Status.NOT_DOWNLOADED, Status.DOWNLOAD_IN_PROGRESS);
String getInstallPath();
diff --git a/api/src/main/java/com/cloud/storage/VolumeApiService.java b/api/src/main/java/com/cloud/storage/VolumeApiService.java
index 19c2ebe455a5..43ead8d287b9 100644
--- a/api/src/main/java/com/cloud/storage/VolumeApiService.java
+++ b/api/src/main/java/com/cloud/storage/VolumeApiService.java
@@ -22,6 +22,7 @@
import java.util.List;
import java.util.Map;
+import com.cloud.dc.DataCenter;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.offering.DiskOffering;
import com.cloud.user.Account;
@@ -56,9 +57,9 @@ public interface VolumeApiService {
Boolean.class,
"use.https.to.upload",
"true",
- "Determines the protocol (HTTPS or HTTP) ACS will use to generate links to upload ISOs, volumes, and templates. When set as 'true', ACS will use protocol HTTPS, otherwise, it will use protocol HTTP. Default value is 'true'.",
+ "Controls whether upload links for ISOs, volumes, and templates use HTTPS (true, default) or HTTP (false). After changing this setting, the Secondary Storage VM (SSVM) must be recreated",
true,
- ConfigKey.Scope.StoragePool);
+ ConfigKey.Scope.Zone);
/**
* Creates the database object for a volume based on the given criteria
@@ -70,6 +71,10 @@ public interface VolumeApiService {
*/
Volume allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException;
+ Volume allocVolume(long ownerId, Long zoneId, Long diskOfferingId, Long vmId, Long snapshotId, String name,
+ Long cmdSize, Boolean displayVolume, Long cmdMinIops, Long cmdMaxIops, String customId)
+ throws ResourceAllocationException;
+
/**
* Creates the volume based on the given criteria
*
@@ -80,6 +85,8 @@ public interface VolumeApiService {
*/
Volume createVolume(CreateVolumeCmd cmd);
+ Volume createVolume(long volumeId, Long vmId, Long snapshotId, Long storageId, Boolean display);
+
/**
* Resizes the volume based on the given criteria
*
@@ -203,4 +210,6 @@ Volume updateVolume(long volumeId, String path, String state, Long storageId,
Pair checkAndRepairVolume(CheckAndRepairVolumeCmd cmd) throws ResourceAllocationException;
Long getVolumePhysicalSize(Storage.ImageFormat format, String path, String chainInfo);
+
+ Long getCustomDiskOfferingIdForVolumeUpload(Account owner, DataCenter zone, boolean encryptEnabledOnly);
}
diff --git a/api/src/main/java/com/cloud/user/AccountService.java b/api/src/main/java/com/cloud/user/AccountService.java
index c0ebcf09f59b..fc450e9179c5 100644
--- a/api/src/main/java/com/cloud/user/AccountService.java
+++ b/api/src/main/java/com/cloud/user/AccountService.java
@@ -21,12 +21,13 @@
import com.cloud.utils.Pair;
import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.RolePermissionEntity;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.acl.apikeypair.ApiKeyPair;
+import org.apache.cloudstack.acl.apikeypair.ApiKeyPairPermission;
+import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.command.admin.account.CreateAccountCmd;
-import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
-import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
-import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
import com.cloud.dc.DataCenter;
import com.cloud.domain.Domain;
@@ -35,7 +36,16 @@
import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering;
+import org.apache.cloudstack.api.command.admin.user.DeleteUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.ListUserKeyRulesCmd;
+import org.apache.cloudstack.api.command.admin.user.ListUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.RegisterUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
+import org.apache.cloudstack.api.response.ApiKeyPairResponse;
+import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.auth.UserTwoFactorAuthenticator;
+import org.apache.cloudstack.backup.BackupOffering;
public interface AccountService {
@@ -58,7 +68,8 @@ UserAccount createUserAccount(String userName, String password, String firstName
User getSystemUser();
- User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID);
+ User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone,
+ String accountName, Long domainId, String userUUID, boolean isPasswordChangeRequired);
User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID,
User.Source source);
@@ -77,10 +88,16 @@ User createUser(String userName, String password, String firstName, String lastN
Account getActiveAccountById(long accountId);
+ Account getActiveAccountByUuid(String accountUuid);
+
Account getAccount(long accountId);
+ Account getAccountByUuid(String accountUuid);
+
User getActiveUser(long userId);
+ User getOneActiveUserForAccount(Account account);
+
User getUserIncludingRemoved(long userId);
boolean isRootAdmin(Long accountId);
@@ -95,7 +112,7 @@ User createUser(String userName, String password, String firstName, String lastN
void markUserRegistered(long userId);
- public String[] createApiKeyAndSecretKey(RegisterCmd cmd);
+ ApiKeyPair createApiKeyAndSecretKey(RegisterUserKeysCmd cmd);
public String[] createApiKeyAndSecretKey(final long userId);
@@ -115,13 +132,19 @@ User createUser(String userName, String password, String firstName, String lastN
void checkAccess(Account account, VpcOffering vof, DataCenter zone) throws PermissionDeniedException;
+ void checkAccess(Account account, BackupOffering bof) throws PermissionDeniedException;
+
void checkAccess(User user, ControlledEntity entity);
void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) throws PermissionDeniedException;
void validateAccountHasAccessToResource(Account account, AccessType accessType, Object resource);
- Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly);
+ void validateCallingUserHasAccessToDesiredUser(Long userId);
+
+ Long finalizeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly);
+
+ Long finalizeAccountId(Long accountId, String accountName, Long domainId, Long projectId);
/**
* returns the user account object for a given user id
@@ -130,9 +153,15 @@ User createUser(String userName, String password, String firstName, String lastN
*/
UserAccount getUserAccountById(Long userId);
- public Pair> getKeys(GetUserKeysCmd cmd);
+ Pair> getKeys(GetUserKeysCmd cmd);
+
+ ListResponse listKeys(ListUserKeysCmd cmd);
+
+ List listKeyRules(ListUserKeyRulesCmd cmd);
+
+ void deleteApiKey(DeleteUserKeysCmd cmd);
- public Pair> getKeys(Long userId);
+ void deleteApiKey(ApiKeyPair id);
/**
* Lists user two-factor authentication provider plugins
@@ -147,4 +176,13 @@ User createUser(String userName, String password, String firstName, String lastN
*/
UserTwoFactorAuthenticator getUserTwoFactorAuthenticationProvider(final Long domainId);
+ ApiKeyPair getLatestUserKeyPair(Long userId);
+
+ ApiKeyPair getKeyPairById(Long id);
+
+ ApiKeyPair getKeyPairByApiKey(String apiKey);
+
+ String getAccessingApiKey(BaseCmd cmd);
+
+ List getAllKeypairPermissions(String apiKey);
}
diff --git a/api/src/main/java/com/cloud/user/ApiKeyPairState.java b/api/src/main/java/com/cloud/user/ApiKeyPairState.java
new file mode 100644
index 000000000000..63405c62e320
--- /dev/null
+++ b/api/src/main/java/com/cloud/user/ApiKeyPairState.java
@@ -0,0 +1,21 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.user;
+
+public enum ApiKeyPairState {
+ ENABLED, REMOVED, EXPIRED
+}
diff --git a/api/src/main/java/com/cloud/user/ResourceLimitService.java b/api/src/main/java/com/cloud/user/ResourceLimitService.java
index 49b20fe2fefc..9c493fb383c9 100644
--- a/api/src/main/java/com/cloud/user/ResourceLimitService.java
+++ b/api/src/main/java/com/cloud/user/ResourceLimitService.java
@@ -30,11 +30,12 @@
import com.cloud.offering.DiskOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.template.VirtualMachineTemplate;
+import org.apache.cloudstack.resourcelimit.Reserver;
public interface ResourceLimitService {
static final ConfigKey MaxAccountSecondaryStorage = new ConfigKey<>("Account Defaults", Long.class, "max.account.secondary.storage", "400",
- "The default maximum secondary storage space (in GiB) that can be used for an account", false);
+ "The default maximum secondary storage space (in GiB) that can be used for an Account", false);
static final ConfigKey MaxProjectSecondaryStorage = new ConfigKey<>("Project Defaults", Long.class, "max.project.secondary.storage", "400",
"The default maximum secondary storage space (in GiB) that can be used for a project", false);
static final ConfigKey ResourceCountCheckInterval = new ConfigKey<>("Advanced", Long.class, "resourcecount.check.interval", "300",
@@ -191,6 +192,7 @@ public interface ResourceLimitService {
*/
public void checkResourceLimit(Account account, ResourceCount.ResourceType type, long... count) throws ResourceAllocationException;
public void checkResourceLimitWithTag(Account account, ResourceCount.ResourceType type, String tag, long... count) throws ResourceAllocationException;
+ public void checkResourceLimitWithTag(Account account, Long domainId, boolean considerSystemAccount, ResourceCount.ResourceType type, String tag, long... count) throws ResourceAllocationException;
/**
* Gets the count of resources for a resource type and account
@@ -251,12 +253,12 @@ public interface ResourceLimitService {
List getResourceLimitStorageTags(DiskOffering diskOffering);
void updateTaggedResourceLimitsAndCountsForAccounts(List responses, String tag);
void updateTaggedResourceLimitsAndCountsForDomains(List responses, String tag);
- void checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering) throws ResourceAllocationException;
-
+ void checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering, List reservations) throws ResourceAllocationException;
+ List getResourceLimitStorageTagsForResourceCountOperation(Boolean display, DiskOffering diskOffering);
void checkVolumeResourceLimitForDiskOfferingChange(Account owner, Boolean display, Long currentSize, Long newSize,
- DiskOffering currentOffering, DiskOffering newOffering) throws ResourceAllocationException;
+ DiskOffering currentOffering, DiskOffering newOffering, List reservations) throws ResourceAllocationException;
- void checkPrimaryStorageResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering) throws ResourceAllocationException;
+ void checkPrimaryStorageResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering, List reservations) throws ResourceAllocationException;
void incrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
void decrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
@@ -273,25 +275,23 @@ void updateVolumeResourceCountForDiskOfferingChange(long accountId, Boolean disp
void incrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
void decrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
- void checkVmResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template) throws ResourceAllocationException;
+ void checkVmResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, List reservations) throws ResourceAllocationException;
void incrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template);
void decrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template);
void checkVmResourceLimitsForServiceOfferingChange(Account owner, Boolean display, Long currentCpu, Long newCpu,
- Long currentMemory, Long newMemory, ServiceOffering currentOffering, ServiceOffering newOffering, VirtualMachineTemplate template) throws ResourceAllocationException;
+ Long currentMemory, Long newMemory, ServiceOffering currentOffering, ServiceOffering newOffering, VirtualMachineTemplate template, List reservations) throws ResourceAllocationException;
void checkVmResourceLimitsForTemplateChange(Account owner, Boolean display, ServiceOffering offering,
- VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate) throws ResourceAllocationException;
+ VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate, List reservations) throws ResourceAllocationException;
- void checkVmCpuResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu) throws ResourceAllocationException;
void incrementVmCpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu);
void decrementVmCpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long cpu);
- void checkVmMemoryResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory) throws ResourceAllocationException;
void incrementVmMemoryResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory);
void decrementVmMemoryResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long memory);
- void checkVmGpuResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long gpu) throws ResourceAllocationException;
void incrementVmGpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long gpu);
void decrementVmGpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long gpu);
+ long recalculateDomainResourceCount(final long domainId, final ResourceType type, String tag);
}
diff --git a/api/src/main/java/com/cloud/user/User.java b/api/src/main/java/com/cloud/user/User.java
index 041b39ad2729..da7245a47980 100644
--- a/api/src/main/java/com/cloud/user/User.java
+++ b/api/src/main/java/com/cloud/user/User.java
@@ -65,14 +65,6 @@ public enum Source {
public void setState(Account.State state);
- public String getApiKey();
-
- public void setApiKey(String apiKey);
-
- public String getSecretKey();
-
- public void setSecretKey(String secretKey);
-
public String getTimezone();
public void setTimezone(String timezone);
diff --git a/api/src/main/java/com/cloud/user/UserAccount.java b/api/src/main/java/com/cloud/user/UserAccount.java
index e6b07fb371eb..5736244e3259 100644
--- a/api/src/main/java/com/cloud/user/UserAccount.java
+++ b/api/src/main/java/com/cloud/user/UserAccount.java
@@ -39,10 +39,6 @@ public interface UserAccount extends InternalIdentity {
String getState();
- String getApiKey();
-
- String getSecretKey();
-
Date getCreated();
Date getRemoved();
diff --git a/api/src/main/java/com/cloud/vm/Nic.java b/api/src/main/java/com/cloud/vm/Nic.java
index afc44b8d39fa..cc0b294205ca 100644
--- a/api/src/main/java/com/cloud/vm/Nic.java
+++ b/api/src/main/java/com/cloud/vm/Nic.java
@@ -162,4 +162,6 @@ public enum ReservationStrategy {
String getIPv6Address();
Integer getMtu();
+
+ boolean isEnabled();
}
diff --git a/api/src/main/java/com/cloud/vm/NicProfile.java b/api/src/main/java/com/cloud/vm/NicProfile.java
index a0c80ceb1bfb..d3ed7b4b87d2 100644
--- a/api/src/main/java/com/cloud/vm/NicProfile.java
+++ b/api/src/main/java/com/cloud/vm/NicProfile.java
@@ -52,6 +52,7 @@ public class NicProfile implements InternalIdentity, Serializable {
boolean defaultNic;
Integer networkRate;
boolean isSecurityGroupEnabled;
+ boolean enabled;
Integer orderIndex;
@@ -87,6 +88,7 @@ public NicProfile(Nic nic, Network network, URI broadcastUri, URI isolationUri,
broadcastType = network.getBroadcastDomainType();
trafficType = network.getTrafficType();
format = nic.getAddressFormat();
+ enabled = nic.isEnabled();
iPv4Address = nic.getIPv4Address();
iPv4Netmask = nic.getIPv4Netmask();
@@ -414,6 +416,14 @@ public void setIpv4AllocationRaceCheck(boolean ipv4AllocationRaceCheck) {
this.ipv4AllocationRaceCheck = ipv4AllocationRaceCheck;
}
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
//
// OTHER METHODS
//
diff --git a/api/src/main/java/com/cloud/vm/NicSecondaryIp.java b/api/src/main/java/com/cloud/vm/NicSecondaryIp.java
index 2856e0aea756..d25627c1782d 100644
--- a/api/src/main/java/com/cloud/vm/NicSecondaryIp.java
+++ b/api/src/main/java/com/cloud/vm/NicSecondaryIp.java
@@ -38,6 +38,8 @@ public interface NicSecondaryIp extends ControlledEntity, Identity, InternalIden
String getIp6Address();
+ String getDescription();
+
long getNetworkId();
long getVmId();
diff --git a/api/src/main/java/com/cloud/vm/UserVmService.java b/api/src/main/java/com/cloud/vm/UserVmService.java
index 01f11b73cd41..67aa0534a5f3 100644
--- a/api/src/main/java/com/cloud/vm/UserVmService.java
+++ b/api/src/main/java/com/cloud/vm/UserVmService.java
@@ -40,6 +40,7 @@
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
+import org.apache.cloudstack.api.command.user.vm.UpdateVmNicCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateVmNicIpCmd;
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
@@ -152,6 +153,8 @@ void startVirtualMachineForHA(VirtualMachine vm, Map customParameters,
final VirtualMachine.PowerState powerState, final LinkedHashMap> networkNicMap) throws InsufficientCapacityException;
diff --git a/api/src/main/java/com/cloud/vm/VirtualMachine.java b/api/src/main/java/com/cloud/vm/VirtualMachine.java
index d244de7115e8..41c9a864c9d0 100644
--- a/api/src/main/java/com/cloud/vm/VirtualMachine.java
+++ b/api/src/main/java/com/cloud/vm/VirtualMachine.java
@@ -124,6 +124,9 @@ public static StateMachine2 getStat
s_fsm.addTransition(new Transition(State.Stopping, VirtualMachine.Event.StopRequested, State.Stopping, null));
s_fsm.addTransition(new Transition(State.Stopping, VirtualMachine.Event.AgentReportShutdowned, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
s_fsm.addTransition(new Transition(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging,null));
+ // Note: In addition to the Stopped -> Error transition for failed VM creation,
+ // a VM can also transition from Expunging to Error on OperationFailedToError.
+ s_fsm.addTransition(new Transition(State.Expunging, VirtualMachine.Event.OperationFailedToError, State.Error, null));
s_fsm.addTransition(new Transition(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging,null));
s_fsm.addTransition(new Transition(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging, null));
s_fsm.addTransition(new Transition(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging, null));
diff --git a/api/src/main/java/com/cloud/vm/VmDetailConstants.java b/api/src/main/java/com/cloud/vm/VmDetailConstants.java
index 596c861218f0..33cc6da70812 100644
--- a/api/src/main/java/com/cloud/vm/VmDetailConstants.java
+++ b/api/src/main/java/com/cloud/vm/VmDetailConstants.java
@@ -55,6 +55,9 @@ public interface VmDetailConstants {
String NIC_MULTIQUEUE_NUMBER = "nic.multiqueue.number";
String NIC_PACKED_VIRTQUEUES_ENABLED = "nic.packed.virtqueues.enabled";
+ // KVM specific, disk controllers
+ String KVM_SKIP_FORCE_DISK_CONTROLLER = "skip.force.disk.controller";
+
// Mac OSX guest specific (internal)
String SMC_PRESENT = "smc.present";
String FIRMWARE = "firmware";
@@ -93,6 +96,7 @@ public interface VmDetailConstants {
String CKS_NODE_TYPE = "node";
String OFFERING = "offering";
String TEMPLATE = "template";
+ String AFFINITY_GROUP = "affinitygroup";
// VMware to KVM VM migrations specific
String VMWARE_TO_KVM_PREFIX = "vmware-to-kvm";
@@ -126,4 +130,10 @@ public interface VmDetailConstants {
String EXTERNAL_DETAIL_PREFIX = "External:";
String CLOUDSTACK_VM_DETAILS = "cloudstack.vm.details";
String CLOUDSTACK_VLAN = "cloudstack.vlan";
+
+ // KVM Checkpoints related
+ String ACTIVE_CHECKPOINT_ID = "active.checkpoint.id";
+ String ACTIVE_CHECKPOINT_CREATE_TIME = "active.checkpoint.create.time";
+ String LAST_CHECKPOINT_ID = "last.checkpoint.id";
+ String LAST_CHECKPOINT_CREATE_TIME = "last.checkpoint.create.time";
}
diff --git a/api/src/main/java/com/cloud/vm/snapshot/VMSnapshot.java b/api/src/main/java/com/cloud/vm/snapshot/VMSnapshot.java
index 24e93af15621..b4b144e2f8af 100644
--- a/api/src/main/java/com/cloud/vm/snapshot/VMSnapshot.java
+++ b/api/src/main/java/com/cloud/vm/snapshot/VMSnapshot.java
@@ -29,10 +29,10 @@
public interface VMSnapshot extends ControlledEntity, Identity, InternalIdentity, StateObject {
enum State {
- Allocated("The VM snapshot is allocated but has not been created yet."), Creating("The VM snapshot is being created."), Ready(
- "The VM snapshot is ready to be used."), Reverting("The VM snapshot is being used to revert"), Expunging("The volume is being expunging"), Removed(
+ Allocated("The Instance Snapshot is allocated but has not been created yet."), Creating("The Instance Snapshot is being created."), Ready(
+ "The Instance Snapshot is ready to be used."), Reverting("The Instance Snapshot is being used to revert"), Expunging("The volume is being expunging"), Removed(
"The volume is destroyed, and can't be recovered."), Error("The volume is in error state, and can't be recovered"),
- Hidden("The VM snapshot is hidden from the user and cannot be recovered.");
+ Hidden("The Instance snapshot is hidden from the user and cannot be recovered.");
String _description;
diff --git a/api/src/main/java/org/apache/cloudstack/acl/APIChecker.java b/api/src/main/java/org/apache/cloudstack/acl/APIChecker.java
index 660f64f43ef2..286a3598e4fb 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/APIChecker.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/APIChecker.java
@@ -20,6 +20,7 @@
import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.utils.component.Adapter;
+import org.apache.cloudstack.acl.apikeypair.ApiKeyPairPermission;
import java.util.List;
@@ -31,8 +32,8 @@ public interface APIChecker extends Adapter {
// If true, apiChecker has checked the operation
// If false, apiChecker is unable to handle the operation or not implemented
// On exception, checkAccess failed don't allow
- boolean checkAccess(User user, String apiCommandName) throws PermissionDeniedException;
- boolean checkAccess(Account account, String apiCommandName) throws PermissionDeniedException;
+ boolean checkAccess(User user, String apiCommandName, ApiKeyPairPermission... apiKeyPairPermissions) throws PermissionDeniedException;
+ boolean checkAccess(Account account, String apiCommandName, ApiKeyPairPermission... apiKeyPairPermissions) throws PermissionDeniedException;
/**
* Verifies if the account has permission for the given list of APIs and returns only the allowed ones.
*
@@ -43,4 +44,5 @@ public interface APIChecker extends Adapter {
*/
List getApisAllowedToUser(Role role, User user, List apiNames) throws PermissionDeniedException;
boolean isEnabled();
+ List getImplicitRolePermissions(RoleType roleType);
}
diff --git a/api/src/main/java/org/apache/cloudstack/acl/RolePermissionEntity.java b/api/src/main/java/org/apache/cloudstack/acl/RolePermissionEntity.java
index 251c6b6d3f9e..f382b1c6964f 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/RolePermissionEntity.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/RolePermissionEntity.java
@@ -21,7 +21,7 @@
import org.apache.cloudstack.api.InternalIdentity;
public interface RolePermissionEntity extends InternalIdentity, Identity {
- public enum Permission {
+ enum Permission {
ALLOW, DENY
}
Rule getRule();
diff --git a/api/src/main/java/org/apache/cloudstack/acl/RoleService.java b/api/src/main/java/org/apache/cloudstack/acl/RoleService.java
index f041c8342aec..14e0a608a925 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/RoleService.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/RoleService.java
@@ -104,5 +104,26 @@ public interface RoleService {
List findAllPermissionsBy(Long roleId);
+ List findAllRolePermissionsEntityBy(Long roleId, boolean considerImplicitRules);
+
Permission getRolePermission(String permission);
+
+ int removeRolesIfNeeded(List extends Role> roles);
+
+ /**
+ * Checks if the role of the caller account has compatible permissions of the specified role permissions.
+ * For each permission of the {@param rolePermissionsToAccess}, the role of the caller needs to contain the same permission.
+ *
+ * @param rolePermissions the permissions of the caller role.
+ * @param rolePermissionsToAccess the permissions for the role that the caller role wants to access.
+ * @return True if the role can be accessed with the given permissions; false otherwise.
+ */
+ boolean roleHasPermission(Map rolePermissions, List rolePermissionsToAccess);
+
+ /**
+ * Given a list of role permissions, returns a {@link Map} containing the API name as the key and the {@link RolePermissionEntity} for the API as the value.
+ *
+ * @param rolePermissions Permissions for the role from role.
+ */
+ Map getRoleRulesAndPermissions(List rolePermissions);
}
diff --git a/api/src/main/java/org/apache/cloudstack/acl/RoleType.java b/api/src/main/java/org/apache/cloudstack/acl/RoleType.java
index 46e4f1bc510d..c33488cd9239 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/RoleType.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/RoleType.java
@@ -132,10 +132,10 @@ public static Set fromCombinedMask(int combinedMask) {
* */
public static Account.Type getAccountTypeByRole(final Role role, final Account.Type defautAccountType) {
if (role != null) {
- LOGGER.debug(String.format("Role [%s] is not null; therefore, we use its account type [%s].", role, defautAccountType));
+ LOGGER.debug("Role [{}] is not null; therefore, we use its Account type [{}].", role, defautAccountType);
return role.getRoleType().getAccountType();
}
- LOGGER.debug(String.format("Role is null; therefore, we use the default account type [%s] value.", defautAccountType));
+ LOGGER.debug("Role is null; therefore, we use the default Account type [{}] value.", defautAccountType);
return defautAccountType;
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/acl/Rule.java b/api/src/main/java/org/apache/cloudstack/acl/Rule.java
index a4ef7773f67b..ad01825a95f1 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/Rule.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/Rule.java
@@ -25,16 +25,18 @@
public final class Rule {
private final String rule;
+ private final Pattern matchingPattern;
private final static Pattern ALLOWED_PATTERN = Pattern.compile("^[a-zA-Z0-9*]+$");
public Rule(final String rule) {
validate(rule);
this.rule = rule;
+ matchingPattern = Pattern.compile(rule.toLowerCase().replace("*", "(\\w*\\*?)+"));
}
public boolean matches(final String commandName) {
- return StringUtils.isNotEmpty(commandName)
- && commandName.toLowerCase().matches(rule.toLowerCase().replace("*", "\\w*"));
+ return StringUtils.isNotEmpty(commandName) &&
+ matchingPattern.matcher(commandName.toLowerCase()).matches();
}
public String getRuleString() {
diff --git a/api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java b/api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java
index 82a8ec5fe932..fa17df7c6ed4 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java
@@ -27,6 +27,8 @@
import com.cloud.user.User;
import com.cloud.utils.component.Adapter;
+import org.apache.cloudstack.backup.BackupOffering;
+
/**
* SecurityChecker checks the ownership and access control to objects within
*/
@@ -145,4 +147,6 @@ boolean checkAccess(Account caller, AccessType accessType, String action, Contro
boolean checkAccess(Account account, NetworkOffering nof, DataCenter zone) throws PermissionDeniedException;
boolean checkAccess(Account account, VpcOffering vof, DataCenter zone) throws PermissionDeniedException;
+
+ boolean checkAccess(Account account, BackupOffering bof) throws PermissionDeniedException;
}
diff --git a/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPair.java b/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPair.java
new file mode 100644
index 000000000000..ecce0ae50824
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPair.java
@@ -0,0 +1,38 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.acl.apikeypair;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+import java.util.Date;
+
+public interface ApiKeyPair extends ControlledEntity, InternalIdentity, Identity {
+ Long getUserId();
+ Date getStartDate();
+ Date getEndDate();
+ Date getCreated();
+ String getDescription();
+ String getApiKey();
+ String getSecretKey();
+ String getName();
+ Date getRemoved();
+ void setRemoved(Date date);
+ void validateDate();
+ boolean hasEndDatePassed();
+}
diff --git a/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPairPermission.java b/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPairPermission.java
new file mode 100644
index 000000000000..60b3834cc073
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPairPermission.java
@@ -0,0 +1,23 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.acl.apikeypair;
+
+import org.apache.cloudstack.acl.RolePermissionEntity;
+
+public interface ApiKeyPairPermission extends RolePermissionEntity {
+ long getApiKeyPairId();
+}
diff --git a/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPairService.java b/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPairService.java
new file mode 100644
index 000000000000..de9c829b17dc
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPairService.java
@@ -0,0 +1,27 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.acl.apikeypair;
+
+import java.util.List;
+
+public interface ApiKeyPairService {
+ List findAllPermissionsByKeyPairId(Long apiKeyPairId, Long roleId);
+
+ ApiKeyPair findByApiKey(String apiKey);
+
+ ApiKeyPair findById(Long id);
+}
diff --git a/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupResponse.java b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupResponse.java
index 69f391a5656a..f5a71b994525 100644
--- a/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupResponse.java
@@ -34,27 +34,27 @@
public class AffinityGroupResponse extends BaseResponse implements ControlledViewEntityResponse {
@SerializedName(ApiConstants.ID)
- @Param(description = "the ID of the affinity group")
+ @Param(description = "The ID of the affinity group")
private String id;
@SerializedName(ApiConstants.NAME)
- @Param(description = "the name of the affinity group")
+ @Param(description = "The name of the affinity group")
private String name;
@SerializedName(ApiConstants.DESCRIPTION)
- @Param(description = "the description of the affinity group")
+ @Param(description = "The description of the affinity group")
private String description;
@SerializedName(ApiConstants.ACCOUNT)
- @Param(description = "the account owning the affinity group")
+ @Param(description = "The account owning the affinity group")
private String accountName;
@SerializedName(ApiConstants.DOMAIN_ID)
- @Param(description = "the domain ID of the affinity group")
+ @Param(description = "The domain ID of the affinity group")
private String domainId;
@SerializedName(ApiConstants.DOMAIN)
- @Param(description = "the domain name of the affinity group")
+ @Param(description = "The domain name of the affinity group")
private String domainName;
@SerializedName(ApiConstants.DOMAIN_PATH)
@@ -62,19 +62,19 @@ public class AffinityGroupResponse extends BaseResponse implements ControlledVie
private String domainPath;
@SerializedName(ApiConstants.PROJECT_ID)
- @Param(description = "the project ID of the affinity group")
+ @Param(description = "The project ID of the affinity group")
private String projectId;
@SerializedName(ApiConstants.PROJECT)
- @Param(description = "the project name of the affinity group")
+ @Param(description = "The project name of the affinity group")
private String projectName;
@SerializedName(ApiConstants.TYPE)
- @Param(description = "the type of the affinity group")
+ @Param(description = "The type of the affinity group")
private String type;
@SerializedName("virtualmachineIds")
- @Param(description = "virtual machine IDs associated with this affinity group")
+ @Param(description = "Instance IDs associated with this affinity group")
private List vmIdList;
@SerializedName("dedicatedresources")
diff --git a/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupService.java b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupService.java
index 018e5f5bab5a..03992c0c1c7c 100644
--- a/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupService.java
+++ b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupService.java
@@ -66,5 +66,4 @@ public interface AffinityGroupService {
boolean isAffinityGroupAvailableInDomain(long affinityGroupId, long domainId);
-
}
diff --git a/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupTypeResponse.java b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupTypeResponse.java
index 6f5fb23d159e..7ddf6dd9f73f 100644
--- a/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupTypeResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupTypeResponse.java
@@ -29,7 +29,7 @@
public class AffinityGroupTypeResponse extends BaseResponse {
@SerializedName(ApiConstants.TYPE)
- @Param(description = "the type of the affinity group")
+ @Param(description = "The type of the affinity group")
private String type;
public AffinityGroupTypeResponse() {
diff --git a/api/src/main/java/org/apache/cloudstack/affinity/AffinityProcessorBase.java b/api/src/main/java/org/apache/cloudstack/affinity/AffinityProcessorBase.java
index 9995d8039e1f..96ca35f264ca 100644
--- a/api/src/main/java/org/apache/cloudstack/affinity/AffinityProcessorBase.java
+++ b/api/src/main/java/org/apache/cloudstack/affinity/AffinityProcessorBase.java
@@ -29,6 +29,9 @@
public class AffinityProcessorBase extends AdapterBase implements AffinityGroupProcessor {
+ public static final String AFFINITY_TYPE_HOST = "host affinity";
+ public static final String AFFINITY_TYPE_HOST_ANTI = "host anti-affinity";
+
protected String _type;
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/alert/AlertService.java b/api/src/main/java/org/apache/cloudstack/alert/AlertService.java
index d8e471756a02..fcc87908bd5d 100644
--- a/api/src/main/java/org/apache/cloudstack/alert/AlertService.java
+++ b/api/src/main/java/org/apache/cloudstack/alert/AlertService.java
@@ -24,18 +24,24 @@
public interface AlertService {
public static class AlertType {
- private static Set defaultAlertTypes = new HashSet();
+ private static final Set defaultAlertTypes = new HashSet<>();
private final String name;
private final short type;
+ private final boolean repetitionAllowed;
- private AlertType(short type, String name, boolean isDefault) {
+ private AlertType(short type, String name, boolean isDefault, boolean repetitionAllowed) {
this.name = name;
this.type = type;
+ this.repetitionAllowed = repetitionAllowed;
if (isDefault) {
defaultAlertTypes.add(this);
}
}
+ private AlertType(short type, String name, boolean isDefault) {
+ this(type, name, isDefault, false);
+ }
+
public static final AlertType ALERT_TYPE_MEMORY = new AlertType(Capacity.CAPACITY_TYPE_MEMORY, "ALERT.MEMORY", true);
public static final AlertType ALERT_TYPE_CPU = new AlertType(Capacity.CAPACITY_TYPE_CPU, "ALERT.CPU", true);
public static final AlertType ALERT_TYPE_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_STORAGE, "ALERT.STORAGE", true);
@@ -45,35 +51,36 @@ private AlertType(short type, String name, boolean isDefault) {
public static final AlertType ALERT_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET = new AlertType(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET, "ALERT.NETWORK.IPV6SUBNET", true);
public static final AlertType ALERT_TYPE_PRIVATE_IP = new AlertType(Capacity.CAPACITY_TYPE_PRIVATE_IP, "ALERT.NETWORK.PRIVATEIP", true);
public static final AlertType ALERT_TYPE_SECONDARY_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_SECONDARY_STORAGE, "ALERT.STORAGE.SECONDARY", true);
- public static final AlertType ALERT_TYPE_HOST = new AlertType((short)7, "ALERT.COMPUTE.HOST", true);
- public static final AlertType ALERT_TYPE_USERVM = new AlertType((short)8, "ALERT.USERVM", true);
- public static final AlertType ALERT_TYPE_DOMAIN_ROUTER = new AlertType((short)9, "ALERT.SERVICE.DOMAINROUTER", true);
- public static final AlertType ALERT_TYPE_CONSOLE_PROXY = new AlertType((short)10, "ALERT.SERVICE.CONSOLEPROXY", true);
+ public static final AlertType ALERT_TYPE_HOST = new AlertType((short)7, "ALERT.COMPUTE.HOST", true, true);
+ public static final AlertType ALERT_TYPE_USERVM = new AlertType((short)8, "ALERT.USERVM", true, true);
+ public static final AlertType ALERT_TYPE_DOMAIN_ROUTER = new AlertType((short)9, "ALERT.SERVICE.DOMAINROUTER", true, true);
+ public static final AlertType ALERT_TYPE_CONSOLE_PROXY = new AlertType((short)10, "ALERT.SERVICE.CONSOLEPROXY", true, true);
public static final AlertType ALERT_TYPE_ROUTING = new AlertType((short)11, "ALERT.NETWORK.ROUTING", true);
- public static final AlertType ALERT_TYPE_STORAGE_MISC = new AlertType((short)12, "ALERT.STORAGE.MISC", true);
+ public static final AlertType ALERT_TYPE_STORAGE_MISC = new AlertType((short)12, "ALERT.STORAGE.MISC", true, true);
public static final AlertType ALERT_TYPE_USAGE_SERVER = new AlertType((short)13, "ALERT.USAGE", true);
- public static final AlertType ALERT_TYPE_MANAGEMENT_NODE = new AlertType((short)14, "ALERT.MANAGEMENT", true);
+ public static final AlertType ALERT_TYPE_MANAGEMENT_NODE = new AlertType((short)14, "ALERT.MANAGEMENT", true, true);
public static final AlertType ALERT_TYPE_DOMAIN_ROUTER_MIGRATE = new AlertType((short)15, "ALERT.NETWORK.DOMAINROUTERMIGRATE", true);
public static final AlertType ALERT_TYPE_CONSOLE_PROXY_MIGRATE = new AlertType((short)16, "ALERT.SERVICE.CONSOLEPROXYMIGRATE", true);
public static final AlertType ALERT_TYPE_USERVM_MIGRATE = new AlertType((short)17, "ALERT.USERVM.MIGRATE", true);
public static final AlertType ALERT_TYPE_VLAN = new AlertType((short)18, "ALERT.NETWORK.VLAN", true);
- public static final AlertType ALERT_TYPE_SSVM = new AlertType((short)19, "ALERT.SERVICE.SSVM", true);
+ public static final AlertType ALERT_TYPE_SSVM = new AlertType((short)19, "ALERT.SERVICE.SSVM", true, true);
public static final AlertType ALERT_TYPE_USAGE_SERVER_RESULT = new AlertType((short)20, "ALERT.USAGE.RESULT", true);
public static final AlertType ALERT_TYPE_STORAGE_DELETE = new AlertType((short)21, "ALERT.STORAGE.DELETE", true);
public static final AlertType ALERT_TYPE_UPDATE_RESOURCE_COUNT = new AlertType((short)22, "ALERT.RESOURCE.COUNT", true);
public static final AlertType ALERT_TYPE_USAGE_SANITY_RESULT = new AlertType((short)23, "ALERT.USAGE.SANITY", true);
public static final AlertType ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP = new AlertType((short)24, "ALERT.NETWORK.DIRECTPUBLICIP", true);
public static final AlertType ALERT_TYPE_LOCAL_STORAGE = new AlertType((short)25, "ALERT.STORAGE.LOCAL", true);
- public static final AlertType ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED = new AlertType((short)26, "ALERT.RESOURCE.EXCEED", true);
+ public static final AlertType ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED = new AlertType((short)26, "ALERT.RESOURCE.EXCEED", true, true);
public static final AlertType ALERT_TYPE_SYNC = new AlertType((short)27, "ALERT.TYPE.SYNC", true);
- public static final AlertType ALERT_TYPE_UPLOAD_FAILED = new AlertType((short)28, "ALERT.UPLOAD.FAILED", true);
- public static final AlertType ALERT_TYPE_OOBM_AUTH_ERROR = new AlertType((short)29, "ALERT.OOBM.AUTHERROR", true);
- public static final AlertType ALERT_TYPE_HA_ACTION = new AlertType((short)30, "ALERT.HA.ACTION", true);
- public static final AlertType ALERT_TYPE_CA_CERT = new AlertType((short)31, "ALERT.CA.CERT", true);
+ public static final AlertType ALERT_TYPE_UPLOAD_FAILED = new AlertType((short)28, "ALERT.UPLOAD.FAILED", true, true);
+ public static final AlertType ALERT_TYPE_OOBM_AUTH_ERROR = new AlertType((short)29, "ALERT.OOBM.AUTHERROR", true, true);
+ public static final AlertType ALERT_TYPE_HA_ACTION = new AlertType((short)30, "ALERT.HA.ACTION", true, true);
+ public static final AlertType ALERT_TYPE_CA_CERT = new AlertType((short)31, "ALERT.CA.CERT", true, true);
public static final AlertType ALERT_TYPE_VM_SNAPSHOT = new AlertType((short)32, "ALERT.VM.SNAPSHOT", true);
- public static final AlertType ALERT_TYPE_VR_PUBLIC_IFACE_MTU = new AlertType((short)32, "ALERT.VR.PUBLIC.IFACE.MTU", true);
- public static final AlertType ALERT_TYPE_VR_PRIVATE_IFACE_MTU = new AlertType((short)32, "ALERT.VR.PRIVATE.IFACE.MTU", true);
- public static final AlertType ALERT_TYPE_EXTENSION_PATH_NOT_READY = new AlertType((short)33, "ALERT.TYPE.EXTENSION.PATH.NOT.READY", true);
+ public static final AlertType ALERT_TYPE_VR_PUBLIC_IFACE_MTU = new AlertType((short)33, "ALERT.VR.PUBLIC.IFACE.MTU", true);
+ public static final AlertType ALERT_TYPE_VR_PRIVATE_IFACE_MTU = new AlertType((short)34, "ALERT.VR.PRIVATE.IFACE.MTU", true);
+ public static final AlertType ALERT_TYPE_EXTENSION_PATH_NOT_READY = new AlertType((short)33, "ALERT.TYPE.EXTENSION.PATH.NOT.READY", true, true);
+ public static final AlertType ALERT_TYPE_VPN_GATEWAY_OBSOLETE_PARAMETERS = new AlertType((short)34, "ALERT.S2S.VPN.GATEWAY.OBSOLETE.PARAMETERS", true, true);
public static final AlertType ALERT_TYPE_BACKUP_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_BACKUP_STORAGE, "ALERT.STORAGE.BACKUP", true);
public static final AlertType ALERT_TYPE_OBJECT_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_OBJECT_STORAGE, "ALERT.STORAGE.OBJECT", true);
@@ -85,6 +92,10 @@ public String getName() {
return name;
}
+ public boolean isRepetitionAllowed() {
+ return repetitionAllowed;
+ }
+
private static AlertType getAlertType(short type) {
for (AlertType alertType : defaultAlertTypes) {
if (alertType.getType() == type) {
@@ -108,7 +119,7 @@ public static AlertType generateAlert(short type, String name) {
if (defaultAlert != null && !defaultAlert.getName().equalsIgnoreCase(name)) {
throw new InvalidParameterValueException("There is a default alert having type " + type + " and name " + defaultAlert.getName());
} else {
- return new AlertType(type, name, false);
+ return new AlertType(type, name, false, false);
}
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/APICommand.java b/api/src/main/java/org/apache/cloudstack/api/APICommand.java
index c559be081165..b77649046ca9 100644
--- a/api/src/main/java/org/apache/cloudstack/api/APICommand.java
+++ b/api/src/main/java/org/apache/cloudstack/api/APICommand.java
@@ -50,4 +50,6 @@
RoleType[] authorized() default {};
Class>[] entityType() default {};
+
+ String httpMethod() default "";
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/AbstractGetUploadParamsCmd.java b/api/src/main/java/org/apache/cloudstack/api/AbstractGetUploadParamsCmd.java
index 028aab247572..13f351f3a27f 100644
--- a/api/src/main/java/org/apache/cloudstack/api/AbstractGetUploadParamsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/AbstractGetUploadParamsCmd.java
@@ -29,28 +29,28 @@
public abstract class AbstractGetUploadParamsCmd extends BaseCmd {
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the volume/template/iso")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "The name of the Volume/Template/ISO")
private String name;
- @Parameter(name = ApiConstants.FORMAT, type = CommandType.STRING, required = true, description = "the format for the volume/template/iso. Possible values include QCOW2, OVA, "
+ @Parameter(name = ApiConstants.FORMAT, type = CommandType.STRING, required = true, description = "The format for the Volume/Template/ISO. Possible values include QCOW2, OVA, "
+ "and VHD.")
private String format;
- @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "the ID of the zone the volume/template/iso is "
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "The ID of the zone the Volume/Template/ISO is "
+ "to be hosted on")
private Long zoneId;
- @Parameter(name = ApiConstants.CHECKSUM, type = CommandType.STRING, description = "the checksum value of this volume/template/iso " + ApiConstants.CHECKSUM_PARAMETER_PREFIX_DESCRIPTION)
+ @Parameter(name = ApiConstants.CHECKSUM, type = CommandType.STRING, description = "The checksum value of this Volume/Template/ISO " + ApiConstants.CHECKSUM_PARAMETER_PREFIX_DESCRIPTION)
private String checksum;
- @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional accountName. Must be used with domainId.")
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "An optional accountName. Must be used with domainId.")
private String accountName;
- @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "an optional domainId. If the account parameter is used, "
+ @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "An optional domainId. If the Account parameter is used, "
+ "domainId must also be used.")
private Long domainId;
- @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Upload volume/template/iso for the project")
+ @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Upload Volume/Template/ISO for the project")
private Long projectId;
public String getName() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java b/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java
index 4d33ba859a5b..e2ebb242cbf2 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java
@@ -127,8 +127,8 @@ public String toString() {
}
public static ApiCommandResourceType fromString(String value) {
- if (StringUtils.isNotEmpty(value) && EnumUtils.isValidEnum(ApiCommandResourceType.class, value)) {
- return valueOf(value);
+ if (StringUtils.isNotBlank(value) && EnumUtils.isValidEnumIgnoreCase(ApiCommandResourceType.class, value)) {
+ return EnumUtils.getEnumIgnoreCase(ApiCommandResourceType.class, value);
}
return null;
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
index 8fca652518f2..2150cfb2200f 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
@@ -19,6 +19,8 @@
public class ApiConstants {
public static final String ACCOUNT = "account";
public static final String ACCOUNTS = "accounts";
+ public static final String ACCOUNT_NAME = "accountname";
+ public static final String ACCOUNT_STATE_TO_SHOW = "accountstatetoshow";
public static final String ACCOUNT_TYPE = "accounttype";
public static final String ACCOUNT_ID = "accountid";
public static final String ACCOUNT_IDS = "accountids";
@@ -46,6 +48,7 @@ public class ApiConstants {
public static final String AS_NUMBER_ID = "asnumberid";
public static final String ASN_RANGE = "asnrange";
public static final String ASN_RANGE_ID = "asnrangeid";
+ public static final String API_KEY_FILTER = "apikeyfilter";
public static final String ASYNC_BACKUP = "asyncbackup";
public static final String AUTO_SELECT = "autoselect";
public static final String USER_API_KEY = "userapikey";
@@ -66,6 +69,8 @@ public class ApiConstants {
public static final String BACKUP_VM_OFFERING_REMOVED = "vmbackupofferingremoved";
public static final String IS_BACKUP_VM_EXPUNGED = "isbackupvmexpunged";
public static final String BACKUP_TOTAL = "backuptotal";
+ public static final String BALANCE = "balance";
+ public static final String BALANCES = "balances";
public static final String BASE64_IMAGE = "base64image";
public static final String BGP_PEERS = "bgppeers";
public static final String BGP_PEER_IDS = "bgppeerids";
@@ -74,6 +79,7 @@ public class ApiConstants {
public static final String BOOTABLE = "bootable";
public static final String BIND_DN = "binddn";
public static final String BIND_PASSWORD = "bindpass";
+ public static final String BLANK_INSTANCE = "blankinstance";
public static final String BUS_ADDRESS = "busaddress";
public static final String BYTES_READ_RATE = "bytesreadrate";
public static final String BYTES_READ_RATE_MAX = "bytesreadratemax";
@@ -154,6 +160,7 @@ public class ApiConstants {
public static final String CUSTOM_ID = "customid";
public static final String CUSTOM_ACTION_ID = "customactionid";
public static final String CUSTOM_JOB_ID = "customjobid";
+ public static final String CURRENCY = "currency";
public static final String CURRENT_START_IP = "currentstartip";
public static final String CURRENT_END_IP = "currentendip";
public static final String ENCRYPT = "encrypt";
@@ -167,6 +174,7 @@ public class ApiConstants {
public static final String DATACENTER_NAME = "datacentername";
public static final String DATADISKS_DETAILS = "datadisksdetails";
public static final String DATADISK_OFFERING_LIST = "datadiskofferinglist";
+ public static final String DATE = "date";
public static final String DEFAULT_VALUE = "defaultvalue";
public static final String DELETE_PROTECTION = "deleteprotection";
public static final String DESCRIPTION = "description";
@@ -213,6 +221,7 @@ public class ApiConstants {
public static final String DOMAIN_PATH = "domainpath";
public static final String DOMAIN_ID = "domainid";
public static final String DOMAIN__ID = "domainId";
+ public static final String DUMMY = "dummy";
public static final String DURATION = "duration";
public static final String ELIGIBLE = "eligible";
public static final String EMAIL = "email";
@@ -256,6 +265,7 @@ public class ApiConstants {
public static final String FOR_VIRTUAL_NETWORK = "forvirtualnetwork";
public static final String FOR_SYSTEM_VMS = "forsystemvms";
public static final String FOR_PROVIDER = "forprovider";
+ public static final String FROM_CHECKPOINT_ID = "fromcheckpointid";
public static final String FULL_PATH = "fullpath";
public static final String GATEWAY = "gateway";
public static final String IP6_GATEWAY = "ip6gateway";
@@ -282,6 +292,7 @@ public class ApiConstants {
public static final String HOST = "host";
public static final String HOST_CONTROL_STATE = "hostcontrolstate";
public static final String HOSTS_MAP = "hostsmap";
+ public static final String HTTP_REQUEST_TYPE = "httprequesttype";
public static final String HYPERVISOR = "hypervisor";
public static final String INLINE = "inline";
public static final String INSTANCE = "instance";
@@ -327,6 +338,7 @@ public class ApiConstants {
public static final String IS_2FA_VERIFIED = "is2faverified";
public static final String IS_2FA_MANDATED = "is2famandated";
+ public static final String IS_ACTIVE = "isactive";
public static final String IS_ASYNC = "isasync";
public static final String IP_AVAILABLE = "ipavailable";
public static final String IP_LIMIT = "iplimit";
@@ -355,6 +367,7 @@ public class ApiConstants {
public static final String JOB_STATUS = "jobstatus";
public static final String KEEPALIVE_ENABLED = "keepaliveenabled";
public static final String KERNEL_VERSION = "kernelversion";
+ public static final String KEYPAIR_ID = "keypairid";
public static final String KEY = "key";
public static final String LABEL = "label";
public static final String LASTNAME = "lastname";
@@ -375,6 +388,7 @@ public class ApiConstants {
public static final String MAC_ADDRESS = "macaddress";
public static final String MAC_ADDRESSES = "macaddresses";
public static final String MANUAL_UPGRADE = "manualupgrade";
+ public static final String MATCH_TYPE = "matchtype";
public static final String MAX = "max";
public static final String MAX_SNAPS = "maxsnaps";
public static final String MAX_BACKUPS = "maxbackups";
@@ -435,6 +449,7 @@ public class ApiConstants {
public static final String MAX_VGPU_PER_PHYSICAL_GPU = "maxvgpuperphysicalgpu";
public static final String GUEST_OS_LIST = "guestoslist";
public static final String GUEST_OS_COUNT = "guestoscount";
+ public static final String GUEST_OS_RULE = "guestosrule";
public static final String OS_MAPPING_CHECK_ENABLED = "osmappingcheckenabled";
public static final String OUTOFBANDMANAGEMENT_POWERSTATE = "outofbandmanagementpowerstate";
public static final String OUTOFBANDMANAGEMENT_ENABLED = "outofbandmanagementenabled";
@@ -501,7 +516,9 @@ public class ApiConstants {
public static final String RECONNECT = "reconnect";
public static final String RECOVER = "recover";
public static final String REPAIR = "repair";
+ public static final String REPETITION_ALLOWED = "repetitionallowed";
public static final String REQUIRES_HVM = "requireshvm";
+ public static final String RESERVED_RESOURCE_DETAILS = "reservedresourcedetails";
public static final String RESOURCES = "resources";
public static final String RESOURCE_COUNT = "resourcecount";
public static final String RESOURCE_NAME = "resourcename";
@@ -520,7 +537,6 @@ public class ApiConstants {
public static final String SCOPE = "scope";
public static final String SEARCH_BASE = "searchbase";
public static final String SECONDARY_IP = "secondaryip";
- public static final String SECRET_KEY = "secretkey";
public static final String SECURITY_GROUP_IDS = "securitygroupids";
public static final String SECURITY_GROUP_NAMES = "securitygroupnames";
public static final String SECURITY_GROUP_NAME = "securitygroupname";
@@ -534,9 +550,11 @@ public class ApiConstants {
public static final String SESSIONKEY = "sessionkey";
public static final String SHOW_CAPACITIES = "showcapacities";
public static final String SHOW_REMOVED = "showremoved";
+ public static final String SHOW_RESOURCES = "showresources";
public static final String SHOW_RESOURCE_ICON = "showicon";
public static final String SHOW_INACTIVE = "showinactive";
public static final String SHOW_UNIQUE = "showunique";
+ public static final String SHOW_PERMISSIONS = "showpermissions";
public static final String SIGNATURE = "signature";
public static final String SIGNATURE_VERSION = "signatureversion";
public static final String SINCE = "since";
@@ -552,6 +570,7 @@ public class ApiConstants {
public static final String USE_STORAGE_REPLICATION = "usestoragereplication";
public static final String SOURCE_CIDR_LIST = "sourcecidrlist";
+ public static final String SOURCE_OFFERING_ID = "sourceofferingid";
public static final String SOURCE_ZONE_ID = "sourcezoneid";
public static final String SSL_VERIFICATION = "sslverification";
public static final String START_ASN = "startasn";
@@ -584,6 +603,8 @@ public class ApiConstants {
public static final String SUITABLE_FOR_VM = "suitableforvirtualmachine";
public static final String SUPPORTS_STORAGE_SNAPSHOT = "supportsstoragesnapshot";
public static final String TARGET_IQN = "targetiqn";
+ public static final String TARIFF_ID = "tariffid";
+ public static final String TARIFF_NAME = "tariffname";
public static final String TASKS_FILTER = "tasksfilter";
public static final String TEMPLATE_FILTER = "templatefilter";
public static final String TEMPLATE_ID = "templateid";
@@ -597,9 +618,12 @@ public class ApiConstants {
public static final String TENANT_NAME = "tenantname";
public static final String TOTAL = "total";
public static final String TOTAL_SUBNETS = "totalsubnets";
+ public static final String TO_CHECKPOINT_ID = "tocheckpointid";
+ public static final String TOTAL_QUOTA = "totalquota";
public static final String TYPE = "type";
public static final String TRUST_STORE = "truststore";
public static final String TRUST_STORE_PASSWORD = "truststorepass";
+ public static final String UNIT = "unit";
public static final String URL = "url";
public static final String USAGE_INTERFACE = "usageinterface";
public static final String USED = "used";
@@ -621,6 +645,7 @@ public class ApiConstants {
public static final String USER_CONFIGURABLE = "userconfigurable";
public static final String USER_SECURITY_GROUP_LIST = "usersecuritygrouplist";
public static final String USER_SECRET_KEY = "usersecretkey";
+ public static final String USE_VDDK = "usevddk";
public static final String USE_VIRTUAL_NETWORK = "usevirtualnetwork";
public static final String USE_VIRTUAL_ROUTER_IP_RESOLVER = "userouteripresolver";
public static final String UPDATE_IN_SEQUENCE = "updateinsequence";
@@ -641,6 +666,7 @@ public class ApiConstants {
public static final String VIRTUAL_MACHINE_STATE = "vmstate";
public static final String VIRTUAL_MACHINES = "virtualmachines";
public static final String USAGE_ID = "usageid";
+ public static final String USAGE_NAME = "usagename";
public static final String USAGE_TYPE = "usagetype";
public static final String INCLUDE_TAGS = "includetags";
@@ -762,6 +788,7 @@ public class ApiConstants {
public static final String ROLE_TYPE = "roletype";
public static final String ROLE_NAME = "rolename";
public static final String PERMISSION = "permission";
+ public static final String PERMISSIONS = "permissions";
public static final String RULE = "rule";
public static final String RULES = "rules";
public static final String RULE_ID = "ruleid";
@@ -856,6 +883,7 @@ public class ApiConstants {
public static final String IS_SOURCE_NAT = "issourcenat";
public static final String IS_STATIC_NAT = "isstaticnat";
public static final String ITERATIONS = "iterations";
+ public static final String ITEMS = "items";
public static final String SORT_BY = "sortby";
public static final String CHANGE_CIDR = "changecidr";
public static final String PURPOSE = "purpose";
@@ -979,6 +1007,7 @@ public class ApiConstants {
public static final String REGION_ID = "regionid";
public static final String VPC_OFF_ID = "vpcofferingid";
public static final String VPC_OFF_NAME = "vpcofferingname";
+ public static final String VPC_OFFERING_CONSERVE_MODE = "vpcofferingconservemode";
public static final String NETWORK = "network";
public static final String VPC_ID = "vpcid";
public static final String VPC_NAME = "vpcname";
@@ -1025,7 +1054,7 @@ public class ApiConstants {
public static final String NSX_PROVIDER_PORT = "nsxproviderport";
public static final String NSX_CONTROLLER_ID = "nsxcontrollerid";
public static final String S3_ACCESS_KEY = "accesskey";
- public static final String S3_SECRET_KEY = "secretkey";
+ public static final String SECRET_KEY = "secretkey";
public static final String S3_END_POINT = "endpoint";
public static final String S3_BUCKET_NAME = "bucket";
public static final String S3_SIGNER = "s3signer";
@@ -1165,6 +1194,7 @@ public class ApiConstants {
public static final String OVM3_VIP = "ovm3vip";
public static final String CLEAN_UP_DETAILS = "cleanupdetails";
public static final String CLEAN_UP_EXTERNAL_DETAILS = "cleanupexternaldetails";
+ public static final String CLEAN_UP_EXTRA_CONFIG = "cleanupextraconfig";
public static final String CLEAN_UP_PARAMETERS = "cleanupparameters";
public static final String VIRTUAL_SIZE = "virtualsize";
public static final String NETSCALER_CONTROLCENTER_ID = "netscalercontrolcenterid";
@@ -1215,6 +1245,7 @@ public class ApiConstants {
public static final String DOCKER_REGISTRY_EMAIL = "dockerregistryemail";
public static final String ISO_NAME = "isoname";
public static final String ISO_STATE = "isostate";
+ public static final String ISO_URL = "isourl";
public static final String SEMANTIC_VERSION = "semanticversion";
public static final String KUBERNETES_VERSION_ID = "kubernetesversionid";
public static final String KUBERNETES_VERSION_NAME = "kubernetesversionname";
@@ -1235,6 +1266,13 @@ public class ApiConstants {
public static final String MAX_SIZE = "maxsize";
public static final String NODE_TYPE_OFFERING_MAP = "nodeofferings";
public static final String NODE_TYPE_TEMPLATE_MAP = "nodetemplates";
+ public static final String NODE_TYPE_AFFINITY_GROUP_MAP = "nodeaffinitygroups";
+ public static final String CONTROL_AFFINITY_GROUP_IDS = "controlaffinitygroupids";
+ public static final String CONTROL_AFFINITY_GROUP_NAMES = "controlaffinitygroupnames";
+ public static final String WORKER_AFFINITY_GROUP_IDS = "workeraffinitygroupids";
+ public static final String WORKER_AFFINITY_GROUP_NAMES = "workeraffinitygroupnames";
+ public static final String ETCD_AFFINITY_GROUP_IDS = "etcdaffinitygroupids";
+ public static final String ETCD_AFFINITY_GROUP_NAMES = "etcdaffinitygroupnames";
public static final String BOOT_TYPE = "boottype";
public static final String BOOT_MODE = "bootmode";
@@ -1256,6 +1294,7 @@ public class ApiConstants {
public static final String PROVIDER_FOR_2FA = "providerfor2fa";
public static final String ISSUER_FOR_2FA = "issuerfor2fa";
public static final String MANDATE_2FA = "mandate2fa";
+ public static final String PASSWORD_CHANGE_REQUIRED = "passwordchangerequired";
public static final String SECRET_CODE = "secretcode";
public static final String LOGIN = "login";
public static final String LOGOUT = "logout";
@@ -1278,6 +1317,8 @@ public class ApiConstants {
public static final String OBJECT_LOCKING = "objectlocking";
public static final String ENCRYPTION = "encryption";
public static final String QUOTA = "quota";
+ public static final String QUOTA_CONSUMED = "quotaconsumed";
+ public static final String QUOTA_USAGE = "quotausage";
public static final String ACCESS_KEY = "accesskey";
public static final String SOURCE_NAT_IP = "sourcenatipaddress";
@@ -1302,8 +1343,10 @@ public class ApiConstants {
public static final String VNF_CONFIGURE_MANAGEMENT = "vnfconfiguremanagement";
public static final String VNF_CIDR_LIST = "vnfcidrlist";
+ public static final String AUTHORIZE_URL = "authorizeurl";
public static final String CLIENT_ID = "clientid";
public static final String REDIRECT_URI = "redirecturi";
+ public static final String TOKEN_URL = "tokenurl";
public static final String IS_TAG_A_RULE = "istagarule";
@@ -1328,6 +1371,13 @@ public class ApiConstants {
public static final String OBJECT_STORAGE_LIMIT = "objectstoragelimit";
public static final String OBJECT_STORAGE_TOTAL = "objectstoragetotal";
+ public static final String KEEP_MAC_ADDRESS_ON_PUBLIC_NIC = "keepmacaddressonpublicnic";
+
+ public static final String PARAMETER_DESCRIPTION_KEEP_MAC_ADDRESS_ON_PUBLIC_NIC =
+ "Indicates whether to use the same MAC address for the public NIC of VRs on the same network. If \"true\", when creating redundant routers or recreating" +
+ " a VR, CloudStack will use the same MAC address for the public NIC of all VRs. Otherwise, if \"false\", new public NICs will always have " +
+ " a new MAC address.";
+
public static final String PARAMETER_DESCRIPTION_ACTIVATION_RULE = "Quota tariff's activation rule. It can receive a JS script that results in either " +
"a boolean or a numeric value: if it results in a boolean value, the tariff value will be applied according to the result; if it results in a numeric value, the " +
"numeric value will be applied; if the result is neither a boolean nor a numeric value, the tariff will not be applied. If the rule is not informed, the tariff " +
@@ -1363,6 +1413,10 @@ public class ApiConstants {
public static final String RECURSIVE_DOMAINS = "recursivedomains";
+ public static final String VPN_CUSTOMER_GATEWAY_PARAMETERS = "vpncustomergatewayparameters";
+ public static final String OBSOLETE_PARAMETERS = "obsoleteparameters";
+ public static final String EXCLUDED_PARAMETERS = "excludedparameters";
+
/**
* This enum specifies IO Drivers, each option controls specific policies on I/O.
* Qemu guests support "threads" and "native" options Since 0.8.8 ; "io_uring" is supported Since 6.3.0 (QEMU 5.0).
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiServerService.java b/api/src/main/java/org/apache/cloudstack/api/ApiServerService.java
index cb75939d6bc5..1ee41ac86c22 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiServerService.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiServerService.java
@@ -21,8 +21,11 @@
import javax.servlet.http.HttpSession;
+import org.apache.cloudstack.context.CallContext;
+
import com.cloud.domain.Domain;
import com.cloud.exception.CloudAuthenticationException;
+import com.cloud.user.Account;
import com.cloud.user.UserAccount;
public interface ApiServerService {
@@ -49,5 +52,23 @@ public ResponseObject loginUser(HttpSession session, String username, String pas
boolean resetPassword(UserAccount userAccount, String token, String password);
+ String getDomainId(Map params);
+
boolean isPostRequestsAndTimestampsEnforced();
+
+ AsyncCmdResult processAsyncCmd(BaseAsyncCmd cmdObj, Map params, CallContext ctx, Long callerUserId, Account caller) throws Exception;
+
+ class AsyncCmdResult {
+ public final Long objectId;
+ public final String objectUuid;
+ public final BaseAsyncCmd asyncCmd;
+ public final long jobId;
+
+ public AsyncCmdResult(Long objectId, String objectUuid, BaseAsyncCmd asyncCmd, long jobId) {
+ this.objectId = objectId;
+ this.objectUuid = objectUuid;
+ this.asyncCmd = asyncCmd;
+ this.jobId = jobId;
+ }
+ }
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCmd.java
index 6859b0a7f406..c67c5a023e09 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCmd.java
@@ -29,6 +29,7 @@ public abstract class BaseAsyncCmd extends BaseCmd {
public static final String migrationSyncObject = "migration";
public static final String snapshotHostSyncObject = "snapshothost";
public static final String gslbSyncObject = "globalserverloadbalancer";
+ public static final String user = "user";
private Object job;
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java
index 8680d7f11de3..b9b13dcfd884 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java
@@ -19,8 +19,8 @@
public abstract class BaseAsyncCreateCustomIdCmd extends BaseAsyncCreateCmd {
@Parameter(name = ApiConstants.CUSTOM_ID,
type = CommandType.STRING,
- description = "an optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only")
- private String customId;
+ description = "An optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only")
+ protected String customId;
public String getCustomId() {
return customId;
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCustomIdCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCustomIdCmd.java
index b251c6ef2ec2..c1777d3b8f84 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCustomIdCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCustomIdCmd.java
@@ -21,7 +21,7 @@
public abstract class BaseAsyncCustomIdCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.CUSTOM_ID,
type = CommandType.STRING,
- description = "an optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only", since = "4.4", authorized = {RoleType.Admin})
+ description = "An optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only", since = "4.4", authorized = {RoleType.Admin})
private String customId;
public String getCustomId() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseBackupListCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseBackupListCmd.java
index 0aa8366bcd5c..2a64a1fb6fd8 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseBackupListCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseBackupListCmd.java
@@ -25,7 +25,7 @@
import org.apache.cloudstack.backup.BackupOffering;
import org.apache.cloudstack.context.CallContext;
-public abstract class BaseBackupListCmd extends BaseListCmd {
+public abstract class BaseBackupListCmd extends BaseListAccountResourcesCmd {
protected void setupResponseBackupOfferingsList(final List offerings, final Integer count) {
final ListResponse response = new ListResponse<>();
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java
index 8f47d51b19d4..00b1bc310d5a 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java
@@ -35,6 +35,7 @@
import org.apache.cloudstack.acl.ProjectRoleService;
import org.apache.cloudstack.acl.RoleService;
import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.apikeypair.ApiKeyPairService;
import org.apache.cloudstack.affinity.AffinityGroupService;
import org.apache.cloudstack.alert.AlertService;
import org.apache.cloudstack.annotation.AnnotationService;
@@ -220,6 +221,8 @@ public static enum CommandType {
@Inject
public Ipv6Service ipv6Service;
@Inject
+ public ApiKeyPairService apiKeyPairService;
+ @Inject
public VnfTemplateManager vnfTemplateManager;
@Inject
public BucketApiService _bucketService;
@@ -382,7 +385,7 @@ public List getParamFields() {
if (roleIsAllowed) {
validFields.add(field);
} else {
- logger.debug("Ignoring parameter " + parameterAnnotation.name() + " as the caller is not authorized to pass it in");
+ logger.debug("Ignoring parameter {} as the caller is not authorized to pass it in", parameterAnnotation.name());
}
}
@@ -498,4 +501,8 @@ public Map convertExternalDetailsToMap(Map externalDetails) {
}
return details;
}
+
+ public String getResourceUuid(String parameterName) {
+ return CallContext.current().getApiResourceUuid(parameterName);
+ }
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseCustomIdCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseCustomIdCmd.java
index 7ca9f1efe7ef..8a2292eadd07 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseCustomIdCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseCustomIdCmd.java
@@ -22,7 +22,7 @@ public abstract class BaseCustomIdCmd extends BaseCmd {
@Parameter(name = ApiConstants.CUSTOM_ID,
type = CommandType.STRING,
- description = "an optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only", since = "4.4", authorized = {RoleType.Admin})
+ description = "An optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only", since = "4.4", authorized = {RoleType.Admin})
private String customId;
public String getCustomId() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java
index aa5273ace3bc..bb18080dfcc4 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java
@@ -19,7 +19,7 @@
public abstract class BaseListAccountResourcesCmd extends BaseListDomainResourcesCmd implements IBaseListAccountResourcesCmd {
- @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "list resources by account. Must be used with the domainId parameter.")
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "List resources by Account. Must be used with the domainId parameter.")
private String accountName;
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseListDomainResourcesCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseListDomainResourcesCmd.java
index 7a8cee337705..640caa935425 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseListDomainResourcesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseListDomainResourcesCmd.java
@@ -27,10 +27,10 @@ public abstract class BaseListDomainResourcesCmd extends BaseListCmd implements
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.UUID,
entityType = DomainResponse.class,
- description = "list only resources belonging to the domain specified")
+ description = "List only resources belonging to the domain specified")
private Long domainId;
- @Parameter(name = ApiConstants.IS_RECURSIVE, type = CommandType.BOOLEAN, description = "defaults to false,"
+ @Parameter(name = ApiConstants.IS_RECURSIVE, type = CommandType.BOOLEAN, description = "Defaults to false,"
+ " but if true, lists all resources from the parent specified by the domainId till leaves.")
private Boolean recursive;
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseListProjectAndAccountResourcesCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseListProjectAndAccountResourcesCmd.java
index 0bcfba15ea6e..d3c999ddb048 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseListProjectAndAccountResourcesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseListProjectAndAccountResourcesCmd.java
@@ -20,7 +20,7 @@
public abstract class BaseListProjectAndAccountResourcesCmd extends BaseListAccountResourcesCmd implements IBaseListProjectAndAccountResourcesCmd {
- @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "list objects by project; if projectid=-1 lists All VMs")
+ @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "List objects by project; if projectid=-1 lists All Instances")
private Long projectId;
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseListRetrieveOnlyResourceCountCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseListRetrieveOnlyResourceCountCmd.java
index 0e8e136a6c19..20c270c30b21 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseListRetrieveOnlyResourceCountCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseListRetrieveOnlyResourceCountCmd.java
@@ -19,7 +19,7 @@
import org.apache.commons.lang3.BooleanUtils;
public abstract class BaseListRetrieveOnlyResourceCountCmd extends BaseListTaggedResourcesCmd {
- @Parameter(name = ApiConstants.RETRIEVE_ONLY_RESOURCE_COUNT, type = CommandType.BOOLEAN, description = "makes the API's response contains only the resource count")
+ @Parameter(name = ApiConstants.RETRIEVE_ONLY_RESOURCE_COUNT, type = CommandType.BOOLEAN, description = "Makes the API's response contains only the resource count")
private Boolean retrieveOnlyResourceCount;
public Boolean getRetrieveOnlyResourceCount() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseListTemplateOrIsoPermissionsCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseListTemplateOrIsoPermissionsCmd.java
index be95547a8a73..27e58233b249 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseListTemplateOrIsoPermissionsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseListTemplateOrIsoPermissionsCmd.java
@@ -33,7 +33,7 @@ public abstract class BaseListTemplateOrIsoPermissionsCmd extends BaseCmd implem
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplatePermissionsResponse.class, required = true, description = "the template ID")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplatePermissionsResponse.class, required = true, description = "The Template ID")
private Long id;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseResponse.java b/api/src/main/java/org/apache/cloudstack/api/BaseResponse.java
index 45016c1a2a26..ebf0c4b19a00 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseResponse.java
@@ -25,11 +25,11 @@ public abstract class BaseResponse implements ResponseObject {
private transient String objectName;
@SerializedName(ApiConstants.JOB_ID)
- @Param(description = "the UUID of the latest async job acting on this object")
+ @Param(description = "The UUID of the latest async job acting on this object")
protected String jobId;
@SerializedName(ApiConstants.JOB_STATUS)
- @Param(description = "the current status of the latest async job acting on this object")
+ @Param(description = "The current status of the latest async job acting on this object")
private Integer jobStatus;
public BaseResponse() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseResponseWithAnnotations.java b/api/src/main/java/org/apache/cloudstack/api/BaseResponseWithAnnotations.java
index f7c0c21395f8..19d88382ce78 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseResponseWithAnnotations.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseResponseWithAnnotations.java
@@ -22,7 +22,7 @@
public abstract class BaseResponseWithAnnotations extends BaseResponse {
@SerializedName(ApiConstants.HAS_ANNOTATIONS)
- @Param(description = "true if the entity/resource has annotations")
+ @Param(description = "True if the entity/resource has annotations")
private Boolean hasAnnotation;
public Boolean hasAnnotation() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseResponseWithAssociatedNetwork.java b/api/src/main/java/org/apache/cloudstack/api/BaseResponseWithAssociatedNetwork.java
index 1ffe4657bd98..48be5c6b4de0 100755
--- a/api/src/main/java/org/apache/cloudstack/api/BaseResponseWithAssociatedNetwork.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseResponseWithAssociatedNetwork.java
@@ -22,11 +22,11 @@
public abstract class BaseResponseWithAssociatedNetwork extends BaseResponseWithAnnotations {
@SerializedName(ApiConstants.ASSOCIATED_NETWORK_ID)
- @Param(description = "the ID of the Network associated with this private gateway")
+ @Param(description = "The ID of the Network associated with this private gateway")
private String associatedNetworkId;
@SerializedName(ApiConstants.ASSOCIATED_NETWORK)
- @Param(description = "the name of the Network associated with this private gateway")
+ @Param(description = "The name of the Network associated with this private gateway")
private String associatedNetworkName;
public void setAssociatedNetworkId(String associatedNetworkId) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseResponseWithTagInformation.java b/api/src/main/java/org/apache/cloudstack/api/BaseResponseWithTagInformation.java
index 710b9f0b9ecf..a01cd5677bac 100755
--- a/api/src/main/java/org/apache/cloudstack/api/BaseResponseWithTagInformation.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseResponseWithTagInformation.java
@@ -26,7 +26,7 @@
public abstract class BaseResponseWithTagInformation extends BaseResponseWithAnnotations {
@SerializedName(ApiConstants.TAGS)
- @Param(description = "the list of resource tags associated", responseObject = ResourceTagResponse.class)
+ @Param(description = "The list of resource tags associated", responseObject = ResourceTagResponse.class)
protected Set tags;
public void addTag(ResourceTagResponse tag) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
index 8489bf05ec78..94c5d8ff39fc 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
@@ -30,49 +30,49 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.BOOTABLE, type = CommandType.BOOLEAN, description = "true if image is bootable, false otherwise; available only for updateIso API")
+ @Parameter(name = ApiConstants.BOOTABLE, type = CommandType.BOOLEAN, description = "True if image is bootable, false otherwise; available only for updateIso API")
private Boolean bootable;
- @Parameter(name = ApiConstants.REQUIRES_HVM, type = CommandType.BOOLEAN, description = "true if the template requires HVM, false otherwise; available only for updateTemplate API")
+ @Parameter(name = ApiConstants.REQUIRES_HVM, type = CommandType.BOOLEAN, description = "True if the Template requires HVM, false otherwise; available only for updateTemplate API")
private Boolean requiresHvm;
- @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "the display text of the image", length = 4096)
+ @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "The display text of the image", length = 4096)
private String displayText;
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplateResponse.class, required = true, description = "the ID of the image file")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplateResponse.class, required = true, description = "The ID of the image file")
private Long id;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the image file")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, length = 251, description = "The name of the image file")
private String templateName;
@Parameter(name = ApiConstants.OS_TYPE_ID,
type = CommandType.UUID,
entityType = GuestOSResponse.class,
- description = "the ID of the OS type that best represents the OS of this image.")
+ description = "The ID of the OS type that best represents the OS of this image.")
private Long osTypeId;
@Parameter(name = ApiConstants.FORCE_UPDATE_OS_TYPE, type = CommandType.BOOLEAN, since = "4.21", description = "Force OS type update. Warning: Updating OS type will " +
"update the guest OS configuration for all the existing Instances deployed with this template/iso, which may affect their behavior.")
private Boolean forceUpdateOsType;
- @Parameter(name = ApiConstants.FORMAT, type = CommandType.STRING, description = "the format for the image")
+ @Parameter(name = ApiConstants.FORMAT, type = CommandType.STRING, description = "The format for the image")
private String format;
- @Parameter(name = ApiConstants.PASSWORD_ENABLED, type = CommandType.BOOLEAN, description = "true if the image supports the password reset feature; default is false")
+ @Parameter(name = ApiConstants.PASSWORD_ENABLED, type = CommandType.BOOLEAN, description = "True if the image supports the password reset feature; default is false")
private Boolean passwordEnabled;
- @Parameter(name = ApiConstants.SSHKEY_ENABLED, type = CommandType.BOOLEAN, description = "true if the template supports the sshkey upload feature; default is false")
+ @Parameter(name = ApiConstants.SSHKEY_ENABLED, type = CommandType.BOOLEAN, description = "True if the Template supports the SSHkey upload feature; default is false")
private Boolean sshKeyEnabled;
- @Parameter(name = ApiConstants.SORT_KEY, type = CommandType.INTEGER, description = "sort key of the template, integer")
+ @Parameter(name = ApiConstants.SORT_KEY, type = CommandType.INTEGER, description = "Sort key of the Template, integer")
private Integer sortKey;
@Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE,
type = CommandType.BOOLEAN,
- description = "true if template/ISO contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
+ description = "True if Template/ISO contains XS/VMWare tools in order to support dynamic scaling of Instance CPU/memory")
private Boolean isDynamicallyScalable;
- @Parameter(name = ApiConstants.ROUTING, type = CommandType.BOOLEAN, description = "true if the template type is routing i.e., if template is used to deploy router")
+ @Parameter(name = ApiConstants.ROUTING, type = CommandType.BOOLEAN, description = "True if the Template type is routing i.e., if Template is used to deploy router")
protected Boolean isRoutingType;
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Details in key/value pairs using format details[i].keyname=keyvalue. Example: details[0].hypervisortoolsversion=xenserver61")
@@ -80,11 +80,11 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd {
@Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
type = CommandType.BOOLEAN,
- description = "optional boolean field, which indicates if details should be cleaned up or not (if set to true, details removed for this resource, details field ignored; if false or not set, no action)")
+ description = "Optional boolean field, which indicates if details should be cleaned up or not (if set to true, details removed for this resource, details field ignored; if false or not set, no action)")
private Boolean cleanupDetails;
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
- description = "the CPU arch of the template/ISO. Valid options are: x86_64, aarch64",
+ description = "the CPU arch of the template/ISO. Valid options are: x86_64, aarch64, s390x",
since = "4.20")
private String arch;
@@ -153,8 +153,8 @@ public Map getDetails() {
return (Map) (paramsCollection.toArray())[0];
}
- public boolean isCleanupDetails(){
- return cleanupDetails == null ? false : cleanupDetails.booleanValue();
+ public boolean isCleanupDetails() {
+ return cleanupDetails != null && cleanupDetails;
}
public CPU.CPUArch getCPUArch() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoPermissionsCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoPermissionsCmd.java
index e6ee0897db02..0a62591ddc24 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoPermissionsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoPermissionsCmd.java
@@ -40,31 +40,31 @@ protected String getResponseName() {
@Parameter(name = ApiConstants.ACCOUNTS,
type = CommandType.LIST,
collectionType = CommandType.STRING,
- description = "a comma delimited list of accounts within caller's domain. If specified, \"op\" parameter has to be passed in.")
+ description = "A comma delimited list of Accounts within caller's domain. If specified, \"op\" parameter has to be passed in.")
private List accountNames;
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplateResponse.class, required = true, description = "the template ID")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplateResponse.class, required = true, description = "The Template ID")
private Long id;
- @Parameter(name = ApiConstants.IS_FEATURED, type = CommandType.BOOLEAN, description = "true for featured template/iso, false otherwise")
+ @Parameter(name = ApiConstants.IS_FEATURED, type = CommandType.BOOLEAN, description = "True for featured Template/ISO, false otherwise")
private Boolean featured;
- @Parameter(name = ApiConstants.IS_PUBLIC, type = CommandType.BOOLEAN, description = "true for public template/iso, false for private templates/isos")
+ @Parameter(name = ApiConstants.IS_PUBLIC, type = CommandType.BOOLEAN, description = "True for public Template/ISO, false for private Templates/ISOs")
private Boolean isPublic;
@Parameter(name = ApiConstants.IS_EXTRACTABLE,
type = CommandType.BOOLEAN,
- description = "true if the template/iso is extractable, false other wise. Can be set only by root admin")
+ description = "True if the Template/ISO is extractable, false otherwise. Can be set only by root admin")
private Boolean isExtractable;
- @Parameter(name = ApiConstants.OP, type = CommandType.STRING, description = "permission operator (add, remove, reset)")
+ @Parameter(name = ApiConstants.OP, type = CommandType.STRING, description = "Permission operator (add, remove, reset)")
private String operation;
@Parameter(name = ApiConstants.PROJECT_IDS,
type = CommandType.LIST,
collectionType = CommandType.UUID,
entityType = ProjectResponse.class,
- description = "a comma delimited list of projects. If specified, \"op\" parameter has to be passed in.")
+ description = "A comma delimited list of projects. If specified, \"op\" parameter has to be passed in.")
private List projectIds;
// ///////////////////////////////////////////////////
@@ -121,7 +121,7 @@ public void execute() {
SuccessResponse response = new SuccessResponse(getCommandName());
setResponseObject(response);
} else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update template/iso permissions");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update Template/ISO permissions");
}
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
index 8e92e877f5ca..b0738cf78e16 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
@@ -24,6 +24,8 @@
import org.apache.cloudstack.api.response.ConsoleSessionResponse;
import org.apache.cloudstack.consoleproxy.ConsoleSession;
+import org.apache.cloudstack.acl.apikeypair.ApiKeyPair;
+import org.apache.cloudstack.acl.apikeypair.ApiKeyPairPermission;
import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
@@ -41,6 +43,7 @@
import org.apache.cloudstack.api.response.BackupOfferingResponse;
import org.apache.cloudstack.api.response.BackupRepositoryResponse;
import org.apache.cloudstack.api.response.BackupScheduleResponse;
+import org.apache.cloudstack.api.response.BaseRolePermissionResponse;
import org.apache.cloudstack.api.response.BucketResponse;
import org.apache.cloudstack.api.response.CapacityResponse;
import org.apache.cloudstack.api.response.ClusterResponse;
@@ -77,6 +80,7 @@
import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
import org.apache.cloudstack.api.response.IpQuarantineResponse;
import org.apache.cloudstack.api.response.IsolationMethodResponse;
+import org.apache.cloudstack.api.response.ApiKeyPairResponse;
import org.apache.cloudstack.api.response.LBHealthCheckResponse;
import org.apache.cloudstack.api.response.LBStickinessResponse;
import org.apache.cloudstack.api.response.ListResponse;
@@ -339,6 +343,8 @@ public interface ResponseGenerator {
UserVm findUserVmById(Long vmId);
+ UserVm findUserVmByNicId(Long nicId);
+
Volume findVolumeById(Long volumeId);
Account findAccountByNameDomain(String accountName, Long domainId);
@@ -583,4 +589,8 @@ List createTemplateResponses(ResponseView view, VirtualMachine
GuiThemeResponse createGuiThemeResponse(GuiThemeJoin guiThemeJoin);
ConsoleSessionResponse createConsoleSessionResponse(ConsoleSession consoleSession, ResponseView responseView);
+
+ ApiKeyPairResponse createKeyPairResponse(ApiKeyPair keyPair);
+
+ ListResponse createKeypairPermissionsResponse(List permissions);
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java
index 6dbc6acc59a9..cc154ed964b3 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java
@@ -50,12 +50,12 @@ public class CreateAccountCmd extends BaseCmd {
@Parameter(name = ApiConstants.ACCOUNT,
type = CommandType.STRING,
- description = "Name of the account to be created. The user will be added to this newly created account. If no account is specified, the username will be used as the account name.")
+ description = "Name of the Account to be created. The user will be added to this newly created account. If no Account is specified, the username will be used as the Account name.")
private String accountName;
@Parameter(name = ApiConstants.ACCOUNT_TYPE,
type = CommandType.INTEGER,
- description = "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin")
+ description = "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin")
private Integer accountType;
@Parameter(name = ApiConstants.ROLE_ID, type = CommandType.UUID, entityType = RoleResponse.class, description = "Creates the account under the specified role.")
@@ -64,13 +64,13 @@ public class CreateAccountCmd extends BaseCmd {
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "Creates the user under the specified domain.")
private Long domainId;
- @Parameter(name = ApiConstants.EMAIL, type = CommandType.STRING, required = true, description = "email")
+ @Parameter(name = ApiConstants.EMAIL, type = CommandType.STRING, required = true, description = "E-mail")
private String email;
- @Parameter(name = ApiConstants.FIRSTNAME, type = CommandType.STRING, required = true, description = "firstname")
+ @Parameter(name = ApiConstants.FIRSTNAME, type = CommandType.STRING, required = true, description = "First name")
private String firstName;
- @Parameter(name = ApiConstants.LASTNAME, type = CommandType.STRING, required = true, description = "lastname")
+ @Parameter(name = ApiConstants.LASTNAME, type = CommandType.STRING, required = true, description = "Last name")
private String lastName;
@Parameter(name = ApiConstants.PASSWORD,
@@ -87,16 +87,16 @@ public class CreateAccountCmd extends BaseCmd {
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "Unique username.")
private String userName;
- @Parameter(name = ApiConstants.NETWORK_DOMAIN, type = CommandType.STRING, description = "Network domain for the account's networks")
+ @Parameter(name = ApiConstants.NETWORK_DOMAIN, type = CommandType.STRING, description = "Network domain for the Account's Networks")
private String networkDomain;
- @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters")
+ @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "Details for Account used to store specific parameters")
private Map details;
- @Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.STRING, description = "Account UUID, required for adding account from external provisioning system")
+ @Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.STRING, description = "Account UUID, required for adding Account from external provisioning system")
private String accountUUID;
- @Parameter(name = ApiConstants.USER_ID, type = CommandType.STRING, description = "User UUID, required for adding account from external provisioning system")
+ @Parameter(name = ApiConstants.USER_ID, type = CommandType.STRING, description = "User UUID, required for adding Account from external provisioning system")
private String userUUID;
/////////////////////////////////////////////////////
@@ -177,7 +177,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
validateParams();
- CallContext.current().setEventDetails("Account Name: " + getUsername() + ", Domain Id:" + getDomainId());
+ CallContext.current().setEventDetails("Account Name: " + getUsername() + ", Domain ID:" + getResourceUuid(ApiConstants.DOMAIN_ID));
UserAccount userAccount =
_accountService.createUserAccount(this);
if (userAccount != null) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java
index a90fc4aebe9c..c207801e3640 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java
@@ -35,7 +35,7 @@
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
-@APICommand(name = "deleteAccount", description = "Deletes a account, and all users associated with this account", responseObject = SuccessResponse.class, entityType = {Account.class},
+@APICommand(name = "deleteAccount", description = "Deletes an Account and all Users associated with this Account", responseObject = SuccessResponse.class, entityType = {Account.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class DeleteAccountCmd extends BaseAsyncCmd {
@@ -79,8 +79,8 @@ public String getEventType() {
@Override
public String getEventDescription() {
Account account = _accountService.getAccount(getId());
- return (account != null ? "Deleting user account " + account.getAccountName() + " (ID: " + account.getUuid() + ") and all corresponding users"
- : "Account delete, but this account does not exist in the system");
+ return (account != null ? "Deleting user Account " + account.getAccountName() + " (ID: " + account.getUuid() + ") and all corresponding users"
+ : "Cannot delete Account - it does not exist in the system");
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java
index 55293eca619e..f7f8bd974272 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java
@@ -50,13 +50,13 @@ public class DisableAccountCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "Account id")
private Long id;
- @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Disables specified account.")
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Disables specified Account.")
private String accountName;
- @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "Disables specified account in this domain.")
+ @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "Disables specified Account in this domain.")
private Long domainId;
- @Parameter(name = ApiConstants.LOCK, type = CommandType.BOOLEAN, required = true, description = "If true, only lock the account; else disable the account")
+ @Parameter(name = ApiConstants.LOCK, type = CommandType.BOOLEAN, required = true, description = "If true, only lock the Account; else disable the Account")
private Boolean lockRequested;
@Inject
@@ -108,19 +108,27 @@ public long getEntityOwnerId() {
@Override
public String getEventDescription() {
- return "disabling account: " + getAccountName() + " in domain: " + getDomainId();
+ String message = "Disabling Account ";
+
+ if (getId() != null) {
+ message += "with ID: " + getResourceUuid(ApiConstants.ID);
+ } else {
+ message += getAccountName() + " in Domain: " + getResourceUuid(ApiConstants.DOMAIN_ID);
+ }
+
+ return message;
}
@Override
public void execute() throws ConcurrentOperationException, ResourceUnavailableException {
- CallContext.current().setEventDetails("Account Name: " + getAccountName() + ", Domain Id:" + getDomainId());
+ CallContext.current().setEventDetails("Account Name: " + getAccountName() + ", Domain Id:" + getResourceUuid(ApiConstants.DOMAIN_ID));
Account result = _regionService.disableAccount(this);
if (result != null){
AccountResponse response = _responseGenerator.createAccountResponse(ResponseView.Full, result);
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, lockRequested == true ? "Failed to lock account" : "Failed to disable account");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, lockRequested == true ? "Failed to lock Account" : "Failed to disable Account");
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java
index da96383f1345..7478bc8b8116 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java
@@ -46,10 +46,10 @@ public class EnableAccountCmd extends BaseCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "Account id")
private Long id;
- @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Enables specified account.")
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Enables specified Account.")
private String accountName;
- @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "Enables specified account in this domain.")
+ @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "Enables specified Account in this domain.")
private Long domainId;
@Inject
@@ -98,7 +98,7 @@ public void execute() {
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to enable account");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to enable Account");
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/ListAccountsCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/ListAccountsCmdByAdmin.java
index 09a626ac9547..50e9ba4989cd 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/ListAccountsCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/ListAccountsCmdByAdmin.java
@@ -23,7 +23,7 @@
import com.cloud.user.Account;
-@APICommand(name = "listAccounts", description = "Lists accounts and provides detailed account information for listed accounts", responseObject = AccountResponse.class, responseView = ResponseView.Full, entityType = {Account.class},
+@APICommand(name = "listAccounts", description = "Lists Accounts and provides detailed Account information for listed Accounts", responseObject = AccountResponse.class, responseView = ResponseView.Full, entityType = {Account.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
public class ListAccountsCmdByAdmin extends ListAccountsCmd {
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/LockAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/LockAccountCmd.java
index d7847373e927..3ec191acf846 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/LockAccountCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/LockAccountCmd.java
@@ -28,7 +28,7 @@
import com.cloud.utils.exception.CloudRuntimeException;
@APICommand(name = "lockAccount",
- description = "This deprecated function used to locks an account. Look for the API DisableAccount instead",
+ description = "This deprecated function used to lock an Account. Look for the API DisableAccount instead",
responseObject = AccountResponse.class,
entityType = {Account.class},
requestHasSensitiveInfo = false,
@@ -47,7 +47,7 @@ public class LockAccountCmd extends BaseCmd {
type = CommandType.UUID,
entityType = DomainResponse.class,
required = true,
- description = "Locks the specified account on this domain.")
+ description = "Locks the specified Account on this domain.")
private Long domainId;
/////////////////////////////////////////////////////
@@ -78,6 +78,6 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- throw new CloudRuntimeException("LockAccount does not lock accounts. Its implementation is disabled. Use DisableAccount instead");
+ throw new CloudRuntimeException("LockAccount does not lock Accounts. Its implementation is disabled. Use DisableAccount instead.");
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
index 3347a0d09f37..b6b975ae1ce7 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
@@ -41,7 +41,7 @@
import com.cloud.user.Account;
-@APICommand(name = "updateAccount", description = "Updates account information for the authenticated user", responseObject = AccountResponse.class, entityType = {Account.class},
+@APICommand(name = "updateAccount", description = "Updates Account information for the authenticated user", responseObject = AccountResponse.class, entityType = {Account.class},
responseView = ResponseView.Restricted, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
public class UpdateAccountCmd extends BaseCmd implements UserCmd {
@@ -52,24 +52,24 @@ public class UpdateAccountCmd extends BaseCmd implements UserCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "Account UUID")
private Long id;
- @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Current account name")
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Current Account name")
private String accountName;
- @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "The UUID of the domain where the account exists")
+ @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "The UUID of the domain where the Account exists")
private Long domainId;
- @Parameter(name = ApiConstants.ROLE_ID, type = CommandType.UUID, entityType = RoleResponse.class, description = "The UUID of the dynamic role to set for the account")
+ @Parameter(name = ApiConstants.ROLE_ID, type = CommandType.UUID, entityType = RoleResponse.class, description = "The UUID of the dynamic role to set for the Account")
private Long roleId;
- @Parameter(name = ApiConstants.NEW_NAME, type = CommandType.STRING, description = "New name for the account")
+ @Parameter(name = ApiConstants.NEW_NAME, type = CommandType.STRING, description = "New name for the Account")
private String newName;
@Parameter(name = ApiConstants.NETWORK_DOMAIN,
type = CommandType.STRING,
- description = "Network domain for the account's networks; empty string will update domainName with NULL value")
+ description = "Network domain for the Account's networks; empty string will update domainName with NULL value")
private String networkDomain;
- @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "Details for the account used to store specific parameters")
+ @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "Details for the Account used to store specific parameters")
private Map details;
@Parameter(name = ApiConstants.API_KEY_ACCESS, type = CommandType.STRING, description = "Determines if Api key access for this user is enabled, disabled or inherits the value from its parent, the domain level setting api.key.access", since = "4.20.1.0", authorized = {RoleType.Admin})
@@ -144,7 +144,7 @@ public void execute() {
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update account");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update Account");
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRoleCmd.java
index e67a3e2c0a00..59a09ef7a486 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRoleCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRoleCmd.java
@@ -109,7 +109,7 @@ private void validateRoleParameters() {
}
if (getRoleId() != null && getRoleId() < 1L) {
- throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role id provided");
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role ID provided");
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java
index 232c4760e1e6..13405431f63e 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java
@@ -81,7 +81,7 @@ public void execute() {
if (role == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role id provided");
}
- CallContext.current().setEventDetails("Role id: " + role.getId() + ", rule:" + getRule() + ", permission: " + getPermission() + ", description: " + getDescription());
+ CallContext.current().setEventDetails("Role ID: " + role.getUuid() + ", rule:" + getRule() + ", permission: " + getPermission() + ", description: " + getDescription());
final RolePermission rolePermission = roleService.createRolePermission(role, getRule(), getPermission(), getDescription());
if (rolePermission == null) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create role permission");
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java
index fd2d11aeda0a..80ec08260ab2 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java
@@ -70,7 +70,7 @@ public void execute() {
if (role == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find the role with provided id");
}
- CallContext.current().setEventDetails("Role id: " + role.getId());
+ CallContext.current().setEventDetails("Role ID: " + role.getUuid());
boolean result = roleService.deleteRole(role);
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java
index bedaca9e23af..cf4a62bf6c43 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java
@@ -68,7 +68,7 @@ public void execute() {
if (rolePermission == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role permission id provided");
}
- CallContext.current().setEventDetails("Role permission id: " + rolePermission.getId());
+ CallContext.current().setEventDetails("Role permission ID: " + rolePermission.getUuid());
boolean result = roleService.deleteRolePermission(rolePermission);
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DisableRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DisableRoleCmd.java
index 80cb92c8362f..2c5659b2bc4b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DisableRoleCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DisableRoleCmd.java
@@ -55,7 +55,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
if (role == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find the role with provided id");
}
- CallContext.current().setEventDetails("Role id: " + role.getId());
+ CallContext.current().setEventDetails("Role ID: " + role.getUuid());
boolean result = roleService.disableRole(role);
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/EnableRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/EnableRoleCmd.java
index c4a6505d52f6..05dfbe1270fa 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/EnableRoleCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/EnableRoleCmd.java
@@ -55,7 +55,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
if (role == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find the role with provided id");
}
- CallContext.current().setEventDetails("Role id: " + role.getId());
+ CallContext.current().setEventDetails("Role ID: " + role.getUuid());
boolean result = roleService.enableRole(role);
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRoleCmd.java
index 7d002cd889b6..78fe062ac43e 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRoleCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRoleCmd.java
@@ -46,7 +46,7 @@ public class UpdateRoleCmd extends RoleCmd {
description = "ID of the role", validations = {ApiArgValidator.PositiveNumber})
private Long roleId;
- @Parameter(name = ApiConstants.NAME, type = BaseCmd.CommandType.STRING, description = "creates a role with this unique name")
+ @Parameter(name = ApiConstants.NAME, type = BaseCmd.CommandType.STRING, description = "Creates a role with this unique name")
private String roleName;
@Parameter(name = ApiConstants.DESCRIPTION, type = BaseCmd.CommandType.STRING, description = "The description of the role")
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java
index 3f926092ec3e..992564413f6b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java
@@ -53,7 +53,7 @@ public class UpdateRolePermissionCmd extends BaseCmd {
private Long roleId;
@Parameter(name = ApiConstants.RULE_ORDER, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = RolePermissionResponse.class,
- description = "The parent role permission uuid, use 0 to move this rule at the top of the list")
+ description = "The parent role permission UUID, use 0 to move this rule at the top of the list")
private List rulePermissionOrder;
@Parameter(name = ApiConstants.RULE_ID, type = CommandType.UUID, entityType = RolePermissionResponse.class,
@@ -111,7 +111,7 @@ public void execute() {
if (getRuleId() != null || getRulePermission() != null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameters permission and ruleid must be mutually exclusive with ruleorder");
}
- CallContext.current().setEventDetails("Reordering permissions for role id: " + role.getId());
+ CallContext.current().setEventDetails("Reordering permissions for role with ID: " + role.getUuid());
final List rolePermissionsOrder = new ArrayList<>();
for (Long rolePermissionId : getRulePermissionOrder()) {
final RolePermission rolePermission = roleService.findRolePermission(rolePermissionId);
@@ -129,7 +129,7 @@ public void execute() {
if (rolePermission == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid rule id provided");
}
- CallContext.current().setEventDetails("Updating permission for rule id: " + getRuleId() + " to: " + getRulePermission().toString());
+ CallContext.current().setEventDetails("Updating permission for rule with ID: " + getResourceUuid(ApiConstants.RULE_ID) + " to: " + getRulePermission().toString());
result = roleService.updateRolePermission(role, rolePermission, getRulePermission());
}
SuccessResponse response = new SuccessResponse(getCommandName());
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRoleCmd.java
index ed17a876b248..f71daee5b531 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRoleCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRoleCmd.java
@@ -41,7 +41,7 @@ public class CreateProjectRoleCmd extends ProjectRoleCmd {
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.NAME, type = BaseCmd.CommandType.STRING, required = true,
- description = "creates a project role with this unique name")
+ description = "Creates a project role with this unique name")
private String projectRoleName;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRolePermissionCmd.java
index d39c2312aa91..e085c10cee0b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRolePermissionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRolePermissionCmd.java
@@ -72,7 +72,7 @@ public void execute() {
if (projectRole == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid project role ID provided");
}
- CallContext.current().setEventDetails("Project Role ID: " + projectRole.getId() + ", Rule:" + getRule() + ", Permission: " + getPermission() + ", Description: " + getDescription());
+ CallContext.current().setEventDetails("Project Role ID: " + projectRole.getUuid() + ", Rule:" + getRule() + ", Permission: " + getPermission() + ", Description: " + getDescription());
final ProjectRolePermission projectRolePermission = projRoleService.createProjectRolePermission(this);
if (projectRolePermission == null) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create project role permission");
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRoleCmd.java
index 9f8d82489584..84f73e7a1a32 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRoleCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRoleCmd.java
@@ -69,7 +69,7 @@ public void execute() {
if (role == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find project role with provided id");
}
- CallContext.current().setEventDetails("Deleting Project Role with id: " + role.getId());
+ CallContext.current().setEventDetails("Deleting Project Role with ID: " + role.getUuid());
boolean result = projRoleService.deleteProjectRole(role, getProjectId());
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRolePermissionCmd.java
index ac68278535e2..d7941a6a4cc3 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRolePermissionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRolePermissionCmd.java
@@ -70,7 +70,7 @@ public void execute() {
if (rolePermission == null || rolePermission.getProjectId() != getProjectId()) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role permission id provided for the project");
}
- CallContext.current().setEventDetails("Deleting Project Role permission with id: " + rolePermission.getId());
+ CallContext.current().setEventDetails("Deleting Project Role permission with ID: " + rolePermission.getUuid());
boolean result = projRoleService.deleteProjectRolePermission(rolePermission);
SuccessResponse response = new SuccessResponse();
response.setSuccess(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRoleCmd.java
index 3bc8b3d61868..80dbfd71275f 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRoleCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRoleCmd.java
@@ -43,7 +43,7 @@ public class UpdateProjectRoleCmd extends ProjectRoleCmd {
private Long id;
@Parameter(name = ApiConstants.NAME, type = BaseCmd.CommandType.STRING,
- description = "creates a project role with this unique name", validations = {ApiArgValidator.NotNullOrEmpty})
+ description = "Creates a project role with this unique name", validations = {ApiArgValidator.NotNullOrEmpty})
private String projectRoleName;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRolePermissionCmd.java
index dd59310c66ae..fd0c043f2321 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRolePermissionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRolePermissionCmd.java
@@ -57,7 +57,7 @@ public class UpdateProjectRolePermissionCmd extends BaseCmd {
private Long projectId;
@Parameter(name = ApiConstants.RULE_ORDER, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = ProjectRolePermissionResponse.class,
- description = "The parent role permission uuid, use 0 to move this rule at the top of the list")
+ description = "ID of the parent role permission, use 0 to move this rule at the top of the list")
private List projectRulePermissionOrder;
@Parameter(name = ApiConstants.PROJECT_ROLE_PERMISSION_ID, type = CommandType.UUID, entityType = ProjectRolePermissionResponse.class,
@@ -115,7 +115,7 @@ public void execute() {
if (getProjectRuleId() != null || getProjectRolePermission() != null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameters permission and ruleid must be mutually exclusive with ruleorder");
}
- CallContext.current().setEventDetails("Reordering permissions for role id: " + projectRole.getId());
+ CallContext.current().setEventDetails("Reordering permissions for role with ID: " + projectRole.getUuid());
result = updateProjectRolePermissionOrder(projectRole);
} else if (getProjectRuleId() != null || getProjectRolePermission() != null ) {
@@ -123,7 +123,7 @@ public void execute() {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameters permission and ruleid must be mutually exclusive with ruleorder");
}
ProjectRolePermission rolePermission = getValidProjectRolePermission();
- CallContext.current().setEventDetails("Updating project role permission for rule id: " + getProjectRuleId() + " to: " + getProjectRolePermission().toString());
+ CallContext.current().setEventDetails("Updating project role permission for rule ID: " + getProjectRuleId() + " to: " + getProjectRolePermission().toString());
result = projRoleService.updateProjectRolePermission(projectId, projectRole, rolePermission, getProjectRolePermission());
}
SuccessResponse response = new SuccessResponse(getCommandName());
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
index 7397697bd2cc..88c48103c1b4 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
@@ -40,7 +40,7 @@ public class AcquirePodIpCmdByAdmin extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.STRING, entityType = ZoneResponse.class, required = true, description = "the ID of the zone")
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.STRING, entityType = ZoneResponse.class, required = true, description = "The ID of the zone")
private String zoneId;
@Parameter(name = ApiConstants.POD_ID, type = CommandType.STRING, entityType = ZoneResponse.class, required = false, description = "Pod ID")
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/address/AssociateIPAddrCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/address/AssociateIPAddrCmdByAdmin.java
index 672691ffbd8f..a34de31f78e1 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/address/AssociateIPAddrCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/address/AssociateIPAddrCmdByAdmin.java
@@ -23,7 +23,7 @@
import org.apache.cloudstack.api.command.user.address.AssociateIPAddrCmd;
import org.apache.cloudstack.api.response.IPAddressResponse;
-@APICommand(name = "associateIpAddress", description = "Acquires and associates a public IP to an account.", responseObject = IPAddressResponse.class, responseView = ResponseView.Full,
+@APICommand(name = "associateIpAddress", description = "Acquires and associates a public IP to an Account.", responseObject = IPAddressResponse.class, responseView = ResponseView.Full,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class AssociateIPAddrCmdByAdmin extends AssociateIPAddrCmd implements AdminCmd {
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/address/ListPublicIpAddressesCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/address/ListPublicIpAddressesCmdByAdmin.java
index 4bd6aa7227c8..9976747e1b62 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/address/ListPublicIpAddressesCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/address/ListPublicIpAddressesCmdByAdmin.java
@@ -24,6 +24,6 @@
import com.cloud.network.IpAddress;
-@APICommand(name = "listPublicIpAddresses", description = "Lists all public ip addresses", responseObject = IPAddressResponse.class, responseView = ResponseView.Full,
+@APICommand(name = "listPublicIpAddresses", description = "Lists all public IP addresses", responseObject = IPAddressResponse.class, responseView = ResponseView.Full,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, entityType = {IpAddress.class})
public class ListPublicIpAddressesCmdByAdmin extends ListPublicIpAddressesCmd implements AdminCmd {}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java
index 7d4cab6a0ac4..266c8eecd58c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java
@@ -70,7 +70,7 @@ public void execute() {
response.setDisplayText("IP is released successfully");
setResponseObject(response);
} else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release Pod ip ");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release Pod IP");
}
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/affinitygroup/UpdateVMAffinityGroupCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/affinitygroup/UpdateVMAffinityGroupCmdByAdmin.java
index 43e70838e18f..fbe2d3cc0bd2 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/affinitygroup/UpdateVMAffinityGroupCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/affinitygroup/UpdateVMAffinityGroupCmdByAdmin.java
@@ -26,7 +26,7 @@
import com.cloud.vm.VirtualMachine;
-@APICommand(name = "updateVMAffinityGroup", description = "Updates the affinity/anti-affinity group associations of a virtual machine. The VM has to be stopped and restarted for the "
+@APICommand(name = "updateVMAffinityGroup", description = "Updates the affinity/anti-affinity group associations of an Instance. The Instance has to be stopped and restarted for the "
+ "new properties to take effect.", responseObject = UserVmResponse.class, responseView = ResponseView.Full,
entityType = {VirtualMachine.class},
requestHasSensitiveInfo = false,
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/AddAnnotationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/AddAnnotationCmd.java
index c2ded921c401..834fda1834bb 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/AddAnnotationCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/AddAnnotationCmd.java
@@ -33,22 +33,22 @@
import org.apache.cloudstack.context.CallContext;
import org.apache.commons.lang3.BooleanUtils;
-@APICommand(name = "addAnnotation", description = "add an annotation.", responseObject = AnnotationResponse.class,
+@APICommand(name = "addAnnotation", description = "Add an annotation.", responseObject = AnnotationResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.11", authorized = {RoleType.Admin})
public class AddAnnotationCmd extends BaseCmd {
- @Parameter(name = ApiConstants.ANNOTATION, type = CommandType.STRING, description = "the annotation text")
+ @Parameter(name = ApiConstants.ANNOTATION, type = CommandType.STRING, description = "The annotation text")
private String annotation;
@Parameter(name = ApiConstants.ENTITY_TYPE, type = CommandType.STRING, description = "The following entity types are allowed VM, VOLUME, SNAPSHOT, VM_SNAPSHOT, INSTANCE_GROUP, SSH_KEYPAIR, USER_DATA, NETWORK, VPC, PUBLIC_IP_ADDRESS, VPN_CUSTOMER_GATEWAY, TEMPLATE, ISO, KUBERNETES_CLUSTER, SERVICE_OFFERING, DISK_OFFERING, NETWORK_OFFERING, ZONE, POD, CLUSTER, HOST, DOMAIN, PRIMARY_STORAGE, SECONDARY_STORAGE, VR, SYSTEM_VM, AUTOSCALE_VM_GROUP, MANAGEMENT_SERVER")
private String entityType;
- @Parameter(name = ApiConstants.ENTITY_ID, type = CommandType.STRING, description = "the id of the entity to annotate")
+ @Parameter(name = ApiConstants.ENTITY_ID, type = CommandType.STRING, description = "The ID of the entity to annotate")
private String entityUuid;
@Parameter(name = ApiConstants.ADMINS_ONLY, type = CommandType.BOOLEAN, since = "4.16.0",
- description = "the annotation is visible for admins only")
+ description = "The annotation is visible for admins only")
private Boolean adminsOnly;
public String getAnnotation() {
@@ -77,7 +77,7 @@ public boolean isAdminsOnly() {
public void execute()
throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException,
NetworkRuleConflictException {
- Preconditions.checkNotNull(getEntityUuid(),"I have to have an entity to set an annotation on!");
+ Preconditions.checkNotNull(getEntityUuid(),"I need to have an entity to set an annotation on!");
Preconditions.checkState(AnnotationService.EntityType.contains(entityType),(java.lang.String)"'%s' is not a valid EntityType to put annotations on", entityType);
AnnotationResponse annotationResponse = annotationService.addAnnotation(this);
annotationResponse.setResponseName(getCommandName());
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/ListAnnotationsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/ListAnnotationsCmd.java
index 3df4536786f4..fcaba5154e1f 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/ListAnnotationsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/ListAnnotationsCmd.java
@@ -37,22 +37,22 @@
public class ListAnnotationsCmd extends BaseListCmd {
- @Parameter(name = ApiConstants.ID, type = CommandType.STRING, description = "the id of the annotation")
+ @Parameter(name = ApiConstants.ID, type = CommandType.STRING, description = "The ID of the annotation")
private String uuid;
- @Parameter(name = ApiConstants.ENTITY_TYPE, type = CommandType.STRING, description = "the entity type")
+ @Parameter(name = ApiConstants.ENTITY_TYPE, type = CommandType.STRING, description = "The entity type")
private String entityType;
- @Parameter(name = ApiConstants.ENTITY_ID, type = CommandType.STRING, description = "the id of the entity for which to show annotations")
+ @Parameter(name = ApiConstants.ENTITY_ID, type = CommandType.STRING, description = "The ID of the entity for which to show annotations")
private String entityUuid;
@Parameter(name = ApiConstants.USER_ID, type = CommandType.STRING, since = "4.16.0",
- description = "optional: the id of the user of the annotation", required = false)
+ description = "Optional: The ID of the user of the annotation", required = false)
private String userUuid;
@Parameter(name = ApiConstants.ANNOTATION_FILTER,
type = CommandType.STRING, since = "4.16.0",
- description = "possible values are \"self\" and \"all\". "
+ description = "Possible values are \"self\" and \"all\". "
+ "* self : annotations that have been created by the calling user. "
+ "* all : all the annotations the calling user can access")
private String annotationFilter;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/RemoveAnnotationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/RemoveAnnotationCmd.java
index 693ad09bfa9b..d173c35289f2 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/RemoveAnnotationCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/RemoveAnnotationCmd.java
@@ -30,12 +30,12 @@
import org.apache.cloudstack.api.response.AnnotationResponse;
import org.apache.cloudstack.context.CallContext;
-@APICommand(name = "removeAnnotation", description = "remove an annotation.", responseObject = AnnotationResponse.class,
+@APICommand(name = "removeAnnotation", description = "Remove an annotation.", responseObject = AnnotationResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.11", authorized = {RoleType.Admin})
public class RemoveAnnotationCmd extends BaseCmd {
- @Parameter(name = ApiConstants.ID, type = CommandType.STRING, required = true, description = "the id of the annotation")
+ @Parameter(name = ApiConstants.ID, type = CommandType.STRING, required = true, description = "The ID of the annotation")
private String uuid;
public String getUuid() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/UpdateAnnotationVisibilityCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/UpdateAnnotationVisibilityCmd.java
index b1b7295510cd..d0bd7042ead8 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/UpdateAnnotationVisibilityCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/UpdateAnnotationVisibilityCmd.java
@@ -30,7 +30,7 @@
import org.apache.cloudstack.api.response.AnnotationResponse;
import org.apache.cloudstack.context.CallContext;
-@APICommand(name = "updateAnnotationVisibility", description = "update an annotation visibility.",
+@APICommand(name = "updateAnnotationVisibility", description = "Update an annotation visibility.",
responseObject = AnnotationResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
since = "4.16", authorized = {RoleType.Admin})
@@ -38,11 +38,11 @@ public class UpdateAnnotationVisibilityCmd extends BaseCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.STRING, required = true,
- description = "the id of the annotation")
+ description = "The ID of the annotation")
private String uuid;
@Parameter(name = ApiConstants.ADMINS_ONLY, type = CommandType.BOOLEAN, required = true,
- description = "the annotation is visible for admins only")
+ description = "The annotation is visible for admins only")
private Boolean adminsOnly;
public String getUuid() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java
index 013d0f966ddf..d7be56bf3f46 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java
@@ -32,7 +32,7 @@
import com.cloud.network.as.Counter;
import com.cloud.user.Account;
-@APICommand(name = "createCounter", description = "Adds metric counter for VM auto scaling", responseObject = CounterResponse.class,
+@APICommand(name = "createCounter", description = "Adds metric counter for Instance auto scaling", responseObject = CounterResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class CreateCounterCmd extends BaseAsyncCreateCmd {
private static final String s_name = "counterresponse";
@@ -97,7 +97,7 @@ public void create() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Counter ID: " + getEntityId());
+ CallContext.current().setEventDetails("Counter ID: " + getEntityUuid());
Counter ctr = _autoScaleService.getCounter(getEntityId());
CounterResponse response = _responseGenerator.createCounterResponse(ctr);
response.setResponseName(getCommandName());
@@ -116,7 +116,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "creating a new Counter";
+ return "Creating a new Counter";
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java
index b7b2ce5cb70d..8e941965e84b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java
@@ -32,7 +32,7 @@
import com.cloud.exception.ResourceInUseException;
import com.cloud.user.Account;
-@APICommand(name = "deleteCounter", description = "Deletes a counter for VM auto scaling", responseObject = SuccessResponse.class,
+@APICommand(name = "deleteCounter", description = "Deletes a counter for Instance auto scaling", responseObject = SuccessResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class DeleteCounterCmd extends BaseAsyncCmd {
@@ -40,7 +40,7 @@ public class DeleteCounterCmd extends BaseAsyncCmd {
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = CounterResponse.class, required = true, description = "the ID of the counter")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = CounterResponse.class, required = true, description = "The ID of the counter")
private Long id;
// ///////////////////////////////////////////////////
@@ -61,7 +61,7 @@ public void execute() {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
- logger.warn("Failed to delete counter with Id: " + getId());
+ logger.warn("Failed to delete counter with Id: {}", getId());
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete counter.");
}
}
@@ -91,6 +91,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting a counter.";
+ return "Deleting auto scaling counter with ID: " + getResourceUuid(ApiConstants.ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CloneBackupOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CloneBackupOfferingCmd.java
new file mode 100644
index 000000000000..500a77f3d4fc
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CloneBackupOfferingCmd.java
@@ -0,0 +1,166 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.backup;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.offering.DomainAndZoneIdResolver;
+import org.apache.cloudstack.api.response.BackupOfferingResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.backup.BackupManager;
+import org.apache.cloudstack.backup.BackupOffering;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.LongFunction;
+
+@APICommand(name = "cloneBackupOffering",
+ description = "Clones a backup offering from an existing offering",
+ responseObject = BackupOfferingResponse.class, since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class CloneBackupOfferingCmd extends BaseAsyncCmd implements DomainAndZoneIdResolver {
+
+ @Inject
+ protected BackupManager backupManager;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ ////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.SOURCE_OFFERING_ID, type = BaseCmd.CommandType.UUID, entityType = BackupOfferingResponse.class,
+ required = true, description = "The ID of the source backup offering to clone from")
+ private Long sourceOfferingId;
+
+ @Parameter(name = ApiConstants.NAME, type = BaseCmd.CommandType.STRING, required = true,
+ description = "The name of the cloned offering")
+ private String name;
+
+ @Parameter(name = ApiConstants.DESCRIPTION, type = BaseCmd.CommandType.STRING, required = false,
+ description = "The description of the cloned offering")
+ private String description;
+
+ @Parameter(name = ApiConstants.EXTERNAL_ID, type = BaseCmd.CommandType.STRING, required = false,
+ description = "The backup offering ID (from backup provider side)")
+ private String externalId;
+
+ @Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
+ description = "The zone ID", required = false)
+ private Long zoneId;
+
+ @Parameter(name = ApiConstants.DOMAIN_ID,
+ type = CommandType.STRING,
+ description = "the ID of the containing domain(s) as comma separated string, public for public offerings",
+ length = 4096)
+ private String domainIds;
+
+ @Parameter(name = ApiConstants.ALLOW_USER_DRIVEN_BACKUPS, type = BaseCmd.CommandType.BOOLEAN,
+ description = "Whether users are allowed to create adhoc backups and backup schedules", required = false)
+ private Boolean userDrivenBackups;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getSourceOfferingId() {
+ return sourceOfferingId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getExternalId() {
+ return externalId;
+ }
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public Boolean getUserDrivenBackups() {
+ return userDrivenBackups;
+ }
+
+ public List getDomainIds() {
+ if (domainIds != null && !domainIds.isEmpty()) {
+ return Arrays.asList(Arrays.stream(domainIds.split(",")).map(domainId -> Long.parseLong(domainId.trim())).toArray(Long[]::new));
+ }
+ LongFunction> defaultDomainsProvider = null;
+ if (backupManager != null) {
+ defaultDomainsProvider = backupManager::getBackupOfferingDomains;
+ }
+ return resolveDomainIds(domainIds, sourceOfferingId, defaultDomainsProvider, "backup offering");
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
+ try {
+ BackupOffering policy = backupManager.cloneBackupOffering(this);
+ if (policy == null) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to clone backup offering");
+ }
+ BackupOfferingResponse response = _responseGenerator.createBackupOfferingResponse(policy);
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ } catch (InvalidParameterValueException e) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
+ } catch (CloudRuntimeException e) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+ }
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_VM_BACKUP_OFFERING_CLONE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Cloning backup offering: " + name + " from source offering: " + (sourceOfferingId == null ? "" : sourceOfferingId.toString());
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CreateImageTransferCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CreateImageTransferCmd.java
new file mode 100644
index 000000000000..c98bfb850529
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CreateImageTransferCmd.java
@@ -0,0 +1,100 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.BackupResponse;
+import org.apache.cloudstack.api.response.ImageTransferResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.backup.ImageTransfer;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.utils.EnumUtils;
+
+@APICommand(name = "createImageTransfer",
+ description = "Create image transfer for a disk in backup. This API is intended for testing only and is disabled by default.",
+ responseObject = ImageTransferResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class CreateImageTransferCmd extends BaseCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Parameter(name = ApiConstants.BACKUP_ID,
+ type = CommandType.UUID,
+ entityType = BackupResponse.class,
+ description = "ID of the backup")
+ private Long backupId;
+
+ @Parameter(name = ApiConstants.VOLUME_ID,
+ type = CommandType.UUID,
+ entityType = VolumeResponse.class,
+ required = true,
+ description = "ID of the disk/volume")
+ private Long volumeId;
+
+ @Parameter(name = ApiConstants.DIRECTION,
+ type = CommandType.STRING,
+ required = true,
+ description = "Direction of the transfer: upload, download")
+ private String direction;
+
+ @Parameter(name = ApiConstants.FORMAT,
+ type = CommandType.STRING,
+ description = "Format for the image transfer: raw/cow. 'raw' will create an NBD backend. 'cow' will use the File backend." +
+ "For download, only the 'raw' format is supported. Default: raw")
+ private String format;
+
+ public Long getBackupId() {
+ return backupId;
+ }
+
+ public Long getVolumeId() {
+ return volumeId;
+ }
+
+ public ImageTransfer.Direction getDirection() {
+ return ImageTransfer.Direction.valueOf(direction);
+ }
+
+ public ImageTransfer.Format getFormat() {
+ return EnumUtils.getEnum(ImageTransfer.Format.class, format);
+ }
+
+ @Override
+ public void execute() {
+ ImageTransferResponse response = kvmBackupExportService.createImageTransfer(this);
+ response.setObjectName(ImageTransfer.class.getSimpleName().toLowerCase());
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/DeleteVmCheckpointCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/DeleteVmCheckpointCmd.java
new file mode 100644
index 000000000000..d0e17e86d427
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/DeleteVmCheckpointCmd.java
@@ -0,0 +1,85 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+import org.apache.cloudstack.context.CallContext;
+
+@APICommand(name = "deleteVirtualMachineCheckpoint",
+ description = "Delete a VM checkpoint. This API is intended for testing only and is disabled by default.",
+ responseObject = SuccessResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class DeleteVmCheckpointCmd extends BaseCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+ type = CommandType.UUID,
+ entityType = UserVmResponse.class,
+ required = true,
+ description = "ID of the VM")
+ private Long vmId;
+
+ @Parameter(name = "checkpointid",
+ type = CommandType.STRING,
+ required = true,
+ description = "Checkpoint ID")
+ private String checkpointId;
+
+ public Long getVmId() {
+ return vmId;
+ }
+
+ public String getCheckpointId() {
+ return checkpointId;
+ }
+
+ public void setVmId(Long vmId) {
+ this.vmId = vmId;
+ }
+
+ public void setCheckpointId(String checkpointId) {
+ this.checkpointId = checkpointId;
+ }
+
+ @Override
+ public void execute() {
+ boolean result = kvmBackupExportService.deleteVmCheckpoint(this);
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ response.setSuccess(result);
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/FinalizeBackupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/FinalizeBackupCmd.java
new file mode 100644
index 000000000000..45173f8668ee
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/FinalizeBackupCmd.java
@@ -0,0 +1,103 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.BackupResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.backup.Backup;
+import org.apache.cloudstack.backup.BackupManager;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+
+@APICommand(name = "finalizeBackup",
+ description = "Finalize a VM backup session. This API is intended for testing only and is disabled by default.",
+ responseObject = BackupResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class FinalizeBackupCmd extends BaseAsyncCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Inject
+ private BackupManager backupManager;
+
+ @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+ type = CommandType.UUID,
+ entityType = UserVmResponse.class,
+ required = true,
+ description = "ID of the VM")
+ private Long vmId;
+
+ @Parameter(name = ApiConstants.ID,
+ type = CommandType.UUID,
+ entityType = BackupResponse.class,
+ required = true,
+ description = "ID of the backup")
+ private Long backupId;
+
+ public Long getVmId() {
+ return vmId;
+ }
+
+ public Long getBackupId() {
+ return backupId;
+ }
+
+ @Override
+ public void execute() {
+ Backup backup = kvmBackupExportService.finalizeBackup(this);
+
+ if (backup == null) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create Backup");
+ }
+
+ BackupResponse response = backupManager.createBackupResponse(backup, null);
+
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_VM_BACKUP_CREATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Finalizing backup " + backupId;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/FinalizeImageTransferCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/FinalizeImageTransferCmd.java
new file mode 100644
index 000000000000..dfc43e233bf2
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/FinalizeImageTransferCmd.java
@@ -0,0 +1,69 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.ImageTransferResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.backup.ImageTransfer;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+import org.apache.cloudstack.context.CallContext;
+
+@APICommand(name = "finalizeImageTransfer",
+ description = "Finalize an image transfer. This API is intended for testing only and is disabled by default.",
+ responseObject = SuccessResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class FinalizeImageTransferCmd extends BaseCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Parameter(name = ApiConstants.ID,
+ type = CommandType.UUID,
+ entityType = ImageTransferResponse.class,
+ required = true,
+ description = "ID of the image transfer")
+ private Long imageTransferId;
+
+ public Long getImageTransferId() {
+ return imageTransferId;
+ }
+
+ @Override
+ public void execute() {
+ boolean result = kvmBackupExportService.finalizeImageTransfer(this);
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ response.setSuccess(result);
+ response.setObjectName(ImageTransfer.class.getSimpleName().toLowerCase());
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java
index 7d3902bc4902..4cf27c561508 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java
@@ -27,6 +27,7 @@
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.BackupOfferingResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.backup.BackupManager;
import org.apache.cloudstack.backup.BackupOffering;
@@ -40,6 +41,11 @@
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.utils.exception.CloudRuntimeException;
+import org.apache.commons.collections.CollectionUtils;
+
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
@APICommand(name = "importBackupOffering",
description = "Imports a backup offering using a backup provider",
@@ -48,18 +54,18 @@
public class ImportBackupOfferingCmd extends BaseAsyncCmd {
@Inject
- private BackupManager backupManager;
+ protected BackupManager backupManager;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
////////////////////////////////////////////////////
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true,
- description = "the name of the backup offering")
+ description = "The name of the backup offering")
private String name;
@Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, required = true,
- description = "the description of the backup offering")
+ description = "The description of the backup offering")
private String description;
@Parameter(name = ApiConstants.EXTERNAL_ID,
@@ -76,6 +82,14 @@ public class ImportBackupOfferingCmd extends BaseAsyncCmd {
description = "Whether users are allowed to create adhoc backups and backup schedules", required = true)
private Boolean userDrivenBackups;
+ @Parameter(name = ApiConstants.DOMAIN_ID,
+ type = CommandType.LIST,
+ collectionType = CommandType.UUID,
+ entityType = DomainResponse.class,
+ description = "the ID of the containing domain(s), null for public offerings",
+ since = "4.23.0")
+ private List domainIds;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -100,6 +114,15 @@ public Boolean getUserDrivenBackups() {
return userDrivenBackups == null ? false : userDrivenBackups;
}
+ public List getDomainIds() {
+ if (CollectionUtils.isNotEmpty(domainIds)) {
+ Set set = new LinkedHashSet<>(domainIds);
+ domainIds.clear();
+ domainIds.addAll(set);
+ }
+ return domainIds;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@@ -134,6 +157,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Importing backup offering: " + name + " (external ID: " + externalId + ") on zone ID " + zoneId ;
+ return "Importing backup offering: " + name + " (external ID: " + externalId + ") on zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID) ;
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListImageTransfersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListImageTransfersCmd.java
new file mode 100644
index 000000000000..d810d21ab5f8
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListImageTransfersCmd.java
@@ -0,0 +1,81 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.BackupResponse;
+import org.apache.cloudstack.api.response.ImageTransferResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.backup.ImageTransfer;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+import org.apache.cloudstack.context.CallContext;
+
+@APICommand(name = "listImageTransfers",
+ description = "List image transfers for a backup. This API is intended for testing only and is disabled by default.",
+ responseObject = ImageTransferResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class ListImageTransfersCmd extends BaseListCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Parameter(name = ApiConstants.ID,
+ type = CommandType.UUID,
+ entityType = ImageTransferResponse.class,
+ description = "ID of the Image Transfer")
+ private Long id;
+
+ @Parameter(name = ApiConstants.BACKUP_ID,
+ type = CommandType.UUID,
+ entityType = BackupResponse.class,
+ description = "ID of the backup")
+ private Long backupId;
+
+ public Long getId() {
+ return id;
+ }
+
+ public Long getBackupId() {
+ return backupId;
+ }
+
+ @Override
+ public void execute() {
+ List responses = kvmBackupExportService.listImageTransfers(this);
+ ListResponse response = new ListResponse<>();
+ response.setResponses(responses);
+ response.setObjectName(ImageTransfer.class.getSimpleName().toLowerCase());
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListVmCheckpointsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListVmCheckpointsCmd.java
new file mode 100644
index 000000000000..a61661e982de
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListVmCheckpointsCmd.java
@@ -0,0 +1,69 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.CheckpointResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+
+@APICommand(name = "listVirtualMachineCheckpoints",
+ description = "List checkpoints for a VM. This API is intended for testing only and is disabled by default.",
+ responseObject = CheckpointResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class ListVmCheckpointsCmd extends BaseListCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+ type = CommandType.UUID,
+ entityType = UserVmResponse.class,
+ required = true,
+ description = "ID of the VM")
+ private Long vmId;
+
+ public Long getVmId() {
+ return vmId;
+ }
+
+ @Override
+ public void execute() {
+ List responses = kvmBackupExportService.listVmCheckpoints(this);
+ ListResponse response = new ListResponse<>();
+ response.setResponses(responses);
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return 0;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/StartBackupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/StartBackupCmd.java
new file mode 100644
index 000000000000..1bf6d45db049
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/StartBackupCmd.java
@@ -0,0 +1,120 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.BackupResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.backup.Backup;
+import org.apache.cloudstack.backup.BackupManager;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+
+@APICommand(name = "startBackup",
+ description = "Start a VM backup session using pull mode backup-begin on the KVM host. This API is intended for testing only and is disabled by default.",
+ responseObject = BackupResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+ public class StartBackupCmd extends BaseAsyncCreateCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Inject
+ private BackupManager backupManager;
+
+ @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+ type = CommandType.UUID,
+ entityType = UserVmResponse.class,
+ required = true,
+ description = "ID of the VM")
+ private Long vmId;
+
+ @Parameter(name = ApiConstants.NAME,
+ type = CommandType.STRING,
+ description = "the name of the backup")
+ private String name;
+
+ @Parameter(name = ApiConstants.DESCRIPTION,
+ type = CommandType.STRING,
+ description = "the description for the backup")
+ private String description;
+
+ public Long getVmId() {
+ return vmId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public void execute() {
+ try {
+ Backup backup = kvmBackupExportService.startBackup(this);
+ BackupResponse response = backupManager.createBackupResponse(backup, null);
+
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ } catch (Exception e) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+ }
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+
+ @Override
+ public void create() {
+ Backup backup = kvmBackupExportService.createBackup(this);
+
+ if (backup != null) {
+ setEntityId(backup.getId());
+ setEntityUuid(backup.getUuid());
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create Backup");
+ }
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_VM_BACKUP_CREATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Starting backup for Instance " + vmId;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/UpdateBackupOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/UpdateBackupOfferingCmd.java
index 9de06715ee74..2f0dd6acd0e1 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/UpdateBackupOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/UpdateBackupOfferingCmd.java
@@ -25,19 +25,24 @@
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.offering.DomainAndZoneIdResolver;
import org.apache.cloudstack.api.response.BackupOfferingResponse;
import org.apache.cloudstack.backup.BackupManager;
import org.apache.cloudstack.backup.BackupOffering;
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.user.Account;
import com.cloud.utils.exception.CloudRuntimeException;
+import java.util.List;
+import java.util.function.LongFunction;
+
@APICommand(name = "updateBackupOffering", description = "Updates a backup offering.", responseObject = BackupOfferingResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.16.0")
-public class UpdateBackupOfferingCmd extends BaseCmd {
+public class UpdateBackupOfferingCmd extends BaseCmd implements DomainAndZoneIdResolver {
@Inject
private BackupManager backupManager;
@@ -57,6 +62,13 @@ public class UpdateBackupOfferingCmd extends BaseCmd {
@Parameter(name = ApiConstants.ALLOW_USER_DRIVEN_BACKUPS, type = CommandType.BOOLEAN, description = "Whether to allow user driven backups or not")
private Boolean allowUserDrivenBackups;
+ @Parameter(name = ApiConstants.DOMAIN_ID,
+ type = CommandType.STRING,
+ description = "the ID of the containing domain(s) as comma separated string, public for public offerings",
+ since = "4.23.0",
+ length = 4096)
+ private String domainIds;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -82,7 +94,7 @@ public Boolean getAllowUserDrivenBackups() {
@Override
public void execute() {
try {
- if (StringUtils.isAllEmpty(getName(), getDescription()) && getAllowUserDrivenBackups() == null) {
+ if (StringUtils.isAllEmpty(getName(), getDescription()) && getAllowUserDrivenBackups() == null && CollectionUtils.isEmpty(getDomainIds())) {
throw new InvalidParameterValueException(String.format("Can't update Backup Offering [id: %s] because there are no parameters to be updated, at least one of the",
"following should be informed: name, description or allowUserDrivenBackups.", id));
}
@@ -98,11 +110,23 @@ public void execute() {
this.setResponseObject(response);
} catch (CloudRuntimeException e) {
ApiErrorCode paramError = e instanceof InvalidParameterValueException ? ApiErrorCode.PARAM_ERROR : ApiErrorCode.INTERNAL_ERROR;
- logger.error(String.format("Failed to update Backup Offering [id: %s] due to: [%s].", id, e.getMessage()), e);
+ logger.error("Failed to update Backup Offering [id: {}] due to: [{}].", id, e.getMessage(), e);
throw new ServerApiException(paramError, e.getMessage());
}
}
+ public List getDomainIds() {
+ // backupManager may be null in unit tests where the command is spied without injection.
+ // Avoid creating a method reference to a null receiver which causes NPE. When backupManager
+ // is null, pass null as the defaultDomainsProvider so resolveDomainIds will simply return
+ // an empty list or parse the explicit domainIds string.
+ LongFunction> defaultDomainsProvider = null;
+ if (backupManager != null) {
+ defaultDomainsProvider = backupManager::getBackupOfferingDomains;
+ }
+ return resolveDomainIds(domainIds, id, defaultDomainsProvider, "backup offering");
+ }
+
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java
index 463af000f58b..79dad4269c9b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java
@@ -149,6 +149,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "issuing certificate for domain(s)=" + domains + ", ip(s)=" + addresses;
+ return "Issuing certificate for domain(s)=" + domains + ", ip(s)=" + addresses;
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java
index a39985549ac8..d333a74fdb3b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java
@@ -52,7 +52,7 @@ public class ProvisionCertificateCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, required = true, entityType = HostResponse.class,
- description = "The host/agent uuid to which the certificate has to be provisioned (issued and propagated)")
+ description = "The host/agent ID to which the certificate has to be provisioned (issued and propagated)")
private Long hostId;
@Parameter(name = ApiConstants.RECONNECT, type = CommandType.BOOLEAN,
@@ -63,6 +63,12 @@ public class ProvisionCertificateCmd extends BaseAsyncCmd {
description = "Name of the CA service provider, otherwise the default configured provider plugin will be used")
private String provider;
+ @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN,
+ description = "When true, uses SSH to re-provision the agent's certificate, bypassing the NIO agent connection. " +
+ "Use this when agents are disconnected due to a CA change. Supported for KVM hosts and SystemVMs. Default is false",
+ since = "4.23.0")
+ private Boolean forced;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -79,6 +85,10 @@ public String getProvider() {
return provider;
}
+ public boolean isForced() {
+ return forced != null && forced;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@@ -90,7 +100,7 @@ public void execute() {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to find host by ID: " + getHostId());
}
- boolean result = caManager.provisionCertificate(host, getReconnect(), getProvider());
+ boolean result = caManager.provisionCertificate(host, getReconnect(), getProvider(), isForced());
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
setResponseObject(response);
@@ -108,7 +118,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "provisioning certificate for host id=" + hostId + " using provider=" + provider;
+ return "Provisioning certificate for host with ID: " + getResourceUuid(ApiConstants.HOST_ID) + " using provider: " + provider;
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/RevokeCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/RevokeCertificateCmd.java
index 381bed65f95c..c2212442f4ba 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/RevokeCertificateCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/RevokeCertificateCmd.java
@@ -105,6 +105,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "revoking certificate with serial id=" + serial + ", cn=" + cn;
+ return "Revoking certificate with serial id=" + serial + ", cn=" + cn;
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
index 3aef11b92e9d..d8fa2123d228 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
@@ -44,48 +44,48 @@
requestHasSensitiveInfo = true, responseHasSensitiveInfo = false)
public class AddClusterCmd extends BaseCmd {
- @Parameter(name = ApiConstants.CLUSTER_NAME, type = CommandType.STRING, required = true, description = "the cluster name")
+ @Parameter(name = ApiConstants.CLUSTER_NAME, type = CommandType.STRING, required = true, description = "The cluster name")
private String clusterName;
- @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = false, description = "the password for the host")
+ @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = false, description = "The password for the host")
private String password;
- @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, required = true, description = "the Pod ID for the host")
+ @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, required = true, description = "The Pod ID for the host")
private Long podId;
- @Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = false, description = "the URL")
+ @Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = false, description = "The URL")
private String url;
- @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = false, description = "the username for the cluster")
+ @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = false, description = "The username for the cluster")
private String username;
- @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "the Zone ID for the cluster")
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "The Zone ID for the cluster")
private Long zoneId;
@Parameter(name = ApiConstants.HYPERVISOR,
type = CommandType.STRING,
required = true,
- description = "hypervisor type of the cluster: XenServer,KVM,VMware,Hyperv,BareMetal,Simulator,Ovm3,External")
+ description = "Hypervisor type of the cluster: XenServer,KVM,VMware,Hyperv,BareMetal,Simulator,Ovm3,External")
private String hypervisor;
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
- description = "the CPU arch of the cluster. Valid options are: x86_64, aarch64",
+ description = "The CPU arch of the cluster. Valid options are: x86_64, aarch64, s390x",
since = "4.20")
private String arch;
- @Parameter(name = ApiConstants.CLUSTER_TYPE, type = CommandType.STRING, required = true, description = "type of the cluster: CloudManaged, ExternalManaged")
+ @Parameter(name = ApiConstants.CLUSTER_TYPE, type = CommandType.STRING, required = true, description = "Type of the cluster: CloudManaged, ExternalManaged")
private String clusterType;
@Parameter(name = ApiConstants.ALLOCATION_STATE, type = CommandType.STRING, description = "Allocation state of this cluster for allocation of new resources")
private String allocationState;
- @Parameter(name = ApiConstants.VSM_USERNAME, type = CommandType.STRING, required = false, description = "the username for the VSM associated with this cluster")
+ @Parameter(name = ApiConstants.VSM_USERNAME, type = CommandType.STRING, required = false, description = "The username for the VSM associated with this cluster")
private String vsmusername;
- @Parameter(name = ApiConstants.VSM_PASSWORD, type = CommandType.STRING, required = false, description = "the password for the VSM associated with this cluster")
+ @Parameter(name = ApiConstants.VSM_PASSWORD, type = CommandType.STRING, required = false, description = "The password for the VSM associated with this cluster")
private String vsmpassword;
- @Parameter(name = ApiConstants.VSM_IPADDRESS, type = CommandType.STRING, required = false, description = "the ipaddress of the VSM associated with this cluster")
+ @Parameter(name = ApiConstants.VSM_IPADDRESS, type = CommandType.STRING, required = false, description = "The IP address of the VSM associated with this cluster")
private String vsmipaddress;
@Parameter(name = ApiConstants.VSWITCH_TYPE_GUEST_TRAFFIC,
@@ -109,7 +109,7 @@ public class AddClusterCmd extends BaseCmd {
@Parameter(name = ApiConstants.VSWITCH_NAME_PUBLIC_TRAFFIC,
type = CommandType.STRING,
required = false,
- description = "Name of virtual switch used for public traffic in the cluster. This would override zone wide traffic label setting.")
+ description = "Name of virtual switch used for public traffic in the cluster. This would override zone wide traffic label setting.")
private String vSwitchNamePublicTraffic;
@Parameter(name = ApiConstants.OVM3_POOL, type = CommandType.STRING, required = false, description = "Ovm3 native pooling enabled for cluster")
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/DeleteClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/DeleteClusterCmd.java
index 2b1cfe8bcb58..afabf7fef166 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/DeleteClusterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/DeleteClusterCmd.java
@@ -38,7 +38,7 @@ public class DeleteClusterCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ClusterResponse.class, required = true, description = "the cluster ID")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ClusterResponse.class, required = true, description = "The cluster ID")
private Long id;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ExecuteClusterDrsPlanCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ExecuteClusterDrsPlanCmd.java
index 60f2c2b1deea..00e7da6e37c1 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ExecuteClusterDrsPlanCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ExecuteClusterDrsPlanCmd.java
@@ -142,6 +142,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return String.format("Executing DRS plan for cluster: %d", getId());
+ return "Executing DRS plan for cluster with ID: " + getResourceUuid(ApiConstants.ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java
index b38278e39469..9fe4e3f5cfc1 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java
@@ -52,31 +52,31 @@ public class ListClustersCmd extends BaseListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ClusterResponse.class, description = "lists clusters by the cluster ID")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ClusterResponse.class, description = "Lists clusters by the cluster ID")
private Long id;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "lists clusters by the cluster name")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Lists clusters by the cluster name")
private String clusterName;
- @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, description = "lists clusters by Pod ID")
+ @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, description = "Lists clusters by Pod ID")
private Long podId;
- @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "lists clusters by Zone ID")
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "Lists clusters by Zone ID")
private Long zoneId;
- @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, description = "lists clusters by hypervisor type")
+ @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, description = "Lists clusters by hypervisor type")
private String hypervisorType;
- @Parameter(name = ApiConstants.CLUSTER_TYPE, type = CommandType.STRING, description = "lists clusters by cluster type")
+ @Parameter(name = ApiConstants.CLUSTER_TYPE, type = CommandType.STRING, description = "Lists clusters by cluster type")
private String clusterType;
- @Parameter(name = ApiConstants.ALLOCATION_STATE, type = CommandType.STRING, description = "lists clusters by allocation state")
+ @Parameter(name = ApiConstants.ALLOCATION_STATE, type = CommandType.STRING, description = "Lists clusters by allocation state")
private String allocationState;
- @Parameter(name = ApiConstants.MANAGED_STATE, type = CommandType.STRING, description = "whether this cluster is managed by cloudstack")
+ @Parameter(name = ApiConstants.MANAGED_STATE, type = CommandType.STRING, description = "Whether this cluster is managed by cloudstack")
private String managedState;
- @Parameter(name = ApiConstants.SHOW_CAPACITIES, type = CommandType.BOOLEAN, description = "flag to display the capacity of the clusters")
+ @Parameter(name = ApiConstants.SHOW_CAPACITIES, type = CommandType.BOOLEAN, description = "Flag to display the capacity of the clusters")
private Boolean showCapacities;
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java
index c160cfd2e034..77d0557af05b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java
@@ -39,26 +39,26 @@
public class UpdateClusterCmd extends BaseCmd {
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ClusterResponse.class, required = true, description = "the ID of the Cluster")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ClusterResponse.class, required = true, description = "The ID of the Cluster")
private Long id;
- @Parameter(name = ApiConstants.CLUSTER_NAME, type = CommandType.STRING, description = "the cluster name")
+ @Parameter(name = ApiConstants.CLUSTER_NAME, type = CommandType.STRING, description = "The cluster name")
private String clusterName;
- @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, description = "hypervisor type of the cluster")
+ @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, description = "Hypervisor type of the cluster")
private String hypervisor;
- @Parameter(name = ApiConstants.CLUSTER_TYPE, type = CommandType.STRING, description = "hypervisor type of the cluster")
+ @Parameter(name = ApiConstants.CLUSTER_TYPE, type = CommandType.STRING, description = "Hypervisor type of the cluster")
private String clusterType;
@Parameter(name = ApiConstants.ALLOCATION_STATE, type = CommandType.STRING, description = "Allocation state of this cluster for allocation of new resources")
private String allocationState;
- @Parameter(name = ApiConstants.MANAGED_STATE, type = CommandType.STRING, description = "whether this cluster is managed by cloudstack")
+ @Parameter(name = ApiConstants.MANAGED_STATE, type = CommandType.STRING, description = "Whether this cluster is managed by cloudstack")
private String managedState;
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
- description = "the CPU arch of the cluster. Valid options are: x86_64, aarch64",
+ description = "the CPU arch of the cluster. Valid options are: x86_64, aarch64, s390x",
since = "4.20")
private String arch;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgGroupsByCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgGroupsByCmd.java
index d735218169d6..c63e7cf92d4d 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgGroupsByCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgGroupsByCmd.java
@@ -40,7 +40,7 @@ public class ListCfgGroupsByCmd extends BaseListCmd {
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
- @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "lists configuration group by group name")
+ @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "Lists configuration group by group name")
private String groupName;
// ///////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java
index e365d8bc2dc7..055443934609 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java
@@ -19,23 +19,23 @@
import java.util.ArrayList;
import java.util.List;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.commons.lang3.StringUtils;
-
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.ConfigurationResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ImageStoreResponse;
import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.ManagementServerResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.config.Configuration;
+import org.apache.commons.lang3.StringUtils;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.utils.Pair;
@@ -52,55 +52,62 @@ public class ListCfgsByCmd extends BaseListCmd {
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
- @Parameter(name = ApiConstants.CATEGORY, type = CommandType.STRING, description = "lists configurations by category")
+ @Parameter(name = ApiConstants.CATEGORY, type = CommandType.STRING, description = "Lists configurations by category")
private String category;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "lists configuration by name")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Lists configuration by name")
private String configName;
@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.UUID,
entityType = ZoneResponse.class,
- description = "the ID of the Zone to update the parameter value for corresponding zone")
+ description = "The ID of the Zone to update the parameter value for corresponding zone")
private Long zoneId;
@Parameter(name = ApiConstants.CLUSTER_ID,
type = CommandType.UUID,
entityType = ClusterResponse.class,
- description = "the ID of the Cluster to update the parameter value for corresponding cluster")
+ description = "The ID of the Cluster to update the parameter value for corresponding cluster")
private Long clusterId;
@Parameter(name = ApiConstants.STORAGE_ID,
type = CommandType.UUID,
entityType = StoragePoolResponse.class,
- description = "the ID of the Storage pool to update the parameter value for corresponding storage pool")
+ description = "The ID of the Storage pool to update the parameter value for corresponding storage pool")
private Long storagePoolId;
@Parameter(name = ApiConstants.ACCOUNT_ID,
type = CommandType.UUID,
entityType = AccountResponse.class,
- description = "the ID of the Account to update the parameter value for corresponding account")
+ description = "The ID of the Account to update the parameter value for corresponding account")
private Long accountId;
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.UUID,
entityType = DomainResponse.class,
- description = "the ID of the Domain to update the parameter value for corresponding domain")
+ description = "The ID of the Domain to update the parameter value for corresponding domain")
private Long domainId;
@Parameter(name = ApiConstants.IMAGE_STORE_UUID,
type = CommandType.UUID,
entityType = ImageStoreResponse.class,
- description = "the ID of the Image Store to update the parameter value for corresponding image store")
+ description = "The ID of the Image Store to update the parameter value for corresponding image store")
private Long imageStoreId;
- @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "lists configuration by group name (primarily used for UI)", since = "4.18.0")
+ @Parameter(name = ApiConstants.MANAGEMENT_SERVER_ID,
+ type = CommandType.UUID,
+ entityType = ManagementServerResponse.class,
+ description = "the ID of the Management Server to update the parameter value for corresponding management server",
+ since = "4.23.0")
+ private Long managementServerId;
+
+ @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "Lists configuration by group name (primarily used for UI)", since = "4.18.0")
private String groupName;
- @Parameter(name = ApiConstants.SUBGROUP, type = CommandType.STRING, description = "lists configuration by subgroup name (primarily used for UI)", since = "4.18.0")
+ @Parameter(name = ApiConstants.SUBGROUP, type = CommandType.STRING, description = "Lists configuration by subgroup name (primarily used for UI)", since = "4.18.0")
private String subGroupName;
- @Parameter(name = ApiConstants.PARENT, type = CommandType.STRING, description = "lists configuration by parent name (primarily used for UI)", since = "4.18.0")
+ @Parameter(name = ApiConstants.PARENT, type = CommandType.STRING, description = "Lists configuration by parent name (primarily used for UI)", since = "4.18.0")
private String parentName;
// ///////////////////////////////////////////////////
@@ -139,6 +146,10 @@ public Long getImageStoreId() {
return imageStoreId;
}
+ public Long getManagementServerId() {
+ return managementServerId;
+ }
+
public String getGroupName() {
return groupName;
}
@@ -200,6 +211,9 @@ private void setScope(ConfigurationResponse cfgResponse) {
if (getImageStoreId() != null){
cfgResponse.setScope("imagestore");
}
+ if (getManagementServerId() != null){
+ cfgResponse.setScope("managementserver");
+ }
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListHypervisorCapabilitiesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListHypervisorCapabilitiesCmd.java
index e7cc9e0234e2..d8622f94b6b6 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListHypervisorCapabilitiesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListHypervisorCapabilitiesCmd.java
@@ -47,7 +47,7 @@ public class ListHypervisorCapabilitiesCmd extends BaseListCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HypervisorCapabilitiesResponse.class, description = "ID of the hypervisor capability")
private Long id;
- @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, description = "the hypervisor for which to restrict the search")
+ @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, description = "The hypervisor for which to restrict the search")
private String hypervisor;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ResetCfgCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ResetCfgCmd.java
index f114b263b634..3c3c36b29d7e 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ResetCfgCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ResetCfgCmd.java
@@ -23,16 +23,16 @@
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ImageStoreResponse;
-import org.apache.cloudstack.framework.config.ConfigKey;
-
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.ConfigurationResponse;
import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ImageStoreResponse;
+import org.apache.cloudstack.api.response.ManagementServerResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.config.Configuration;
+import org.apache.cloudstack.framework.config.ConfigKey;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
@@ -45,45 +45,52 @@ public class ResetCfgCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the configuration", validations = {ApiArgValidator.NotNullOrEmpty})
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "The name of the configuration", validations = {ApiArgValidator.NotNullOrEmpty})
private String cfgName;
@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.UUID,
entityType = ZoneResponse.class,
- description = "the ID of the Zone to reset the parameter value for corresponding zone")
+ description = "The ID of the Zone to reset the parameter value for corresponding zone")
private Long zoneId;
@Parameter(name = ApiConstants.CLUSTER_ID,
type = CommandType.UUID,
entityType = ClusterResponse.class,
- description = "the ID of the Cluster to reset the parameter value for corresponding cluster")
+ description = "The ID of the Cluster to reset the parameter value for corresponding cluster")
private Long clusterId;
@Parameter(name = ApiConstants.STORAGE_ID,
type = CommandType.UUID,
entityType = StoragePoolResponse.class,
- description = "the ID of the Storage pool to reset the parameter value for corresponding storage pool")
+ description = "The ID of the Storage pool to reset the parameter value for corresponding storage pool")
private Long storagePoolId;
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.UUID,
entityType = DomainResponse.class,
- description = "the ID of the Domain to reset the parameter value for corresponding domain")
+ description = "The ID of the Domain to reset the parameter value for corresponding domain")
private Long domainId;
@Parameter(name = ApiConstants.ACCOUNT_ID,
type = CommandType.UUID,
entityType = AccountResponse.class,
- description = "the ID of the Account to reset the parameter value for corresponding account")
+ description = "The ID of the Account to reset the parameter value for corresponding account")
private Long accountId;
@Parameter(name = ApiConstants.IMAGE_STORE_ID,
type = CommandType.UUID,
entityType = ImageStoreResponse.class,
- description = "the ID of the Image Store to reset the parameter value for corresponding image store")
+ description = "The ID of the Image Store to reset the parameter value for corresponding image store")
private Long imageStoreId;
+ @Parameter(name = ApiConstants.MANAGEMENT_SERVER_ID,
+ type = CommandType.UUID,
+ entityType = ManagementServerResponse.class,
+ description = "the ID of the Management Server to update the parameter value for corresponding management server",
+ since = "4.23.0")
+ private Long managementServerId;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -116,6 +123,10 @@ public Long getImageStoreId() {
return imageStoreId;
}
+ public Long getManagementServerId() {
+ return managementServerId;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@@ -149,6 +160,9 @@ public void execute() {
if (getImageStoreId() != null) {
response.setScope(ConfigKey.Scope.ImageStore.name());
}
+ if (getManagementServerId() != null) {
+ response.setScope(ConfigKey.Scope.ManagementServer.name());
+ }
response.setValue(cfg.second());
this.setResponseObject(response);
} else {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java
index dbf478df7012..9db9529dc8d8 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java
@@ -16,9 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.admin.config;
-import com.cloud.utils.crypt.DBEncryptionUtil;
import org.apache.cloudstack.acl.RoleService;
-import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiArgValidator;
import org.apache.cloudstack.api.ApiConstants;
@@ -29,13 +27,17 @@
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.ConfigurationResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ImageStoreResponse;
+import org.apache.cloudstack.api.response.ManagementServerResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.config.Configuration;
+import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.commons.lang3.StringUtils;
import com.cloud.user.Account;
+import com.cloud.utils.crypt.DBEncryptionUtil;
@APICommand(name = "updateConfiguration", description = "Updates a configuration.", responseObject = ConfigurationResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@@ -45,49 +47,56 @@ public class UpdateCfgCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the configuration")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "The name of the configuration")
private String cfgName;
- @Parameter(name = ApiConstants.VALUE, type = CommandType.STRING, description = "the value of the configuration", length = 4096)
+ @Parameter(name = ApiConstants.VALUE, type = CommandType.STRING, description = "The value of the configuration", length = 4096)
private String value;
@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.UUID,
entityType = ZoneResponse.class,
- description = "the ID of the Zone to update the parameter value for corresponding zone")
+ description = "The ID of the Zone to update the parameter value for corresponding zone")
private Long zoneId;
@Parameter(name = ApiConstants.CLUSTER_ID,
type = CommandType.UUID,
entityType = ClusterResponse.class,
- description = "the ID of the Cluster to update the parameter value for corresponding cluster")
+ description = "The ID of the Cluster to update the parameter value for corresponding cluster")
private Long clusterId;
@Parameter(name = ApiConstants.STORAGE_ID,
type = CommandType.UUID,
entityType = StoragePoolResponse.class,
- description = "the ID of the Storage pool to update the parameter value for corresponding storage pool")
+ description = "The ID of the Storage pool to update the parameter value for corresponding storage pool")
private Long storagePoolId;
@Parameter(name = ApiConstants.ACCOUNT_ID,
type = CommandType.UUID,
entityType = AccountResponse.class,
- description = "the ID of the Account to update the parameter value for corresponding account")
+ description = "The ID of the Account to update the parameter value for corresponding account")
private Long accountId;
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.UUID,
entityType = DomainResponse.class,
- description = "the ID of the Domain to update the parameter value for corresponding domain")
+ description = "The ID of the Domain to update the parameter value for corresponding domain")
private Long domainId;
@Parameter(name = ApiConstants.IMAGE_STORE_UUID,
type = CommandType.UUID,
entityType = ImageStoreResponse.class,
- description = "the ID of the Image Store to update the parameter value for corresponding image store",
+ description = "The ID of the Image Store to update the parameter value for corresponding image store",
validations = ApiArgValidator.PositiveNumber)
private Long imageStoreId;
+ @Parameter(name = ApiConstants.MANAGEMENT_SERVER_ID,
+ type = CommandType.UUID,
+ entityType = ManagementServerResponse.class,
+ description = "the ID of the Management Server to update the parameter value for corresponding management server",
+ since = "4.23.0")
+ private Long managementServerId;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -112,7 +121,7 @@ public Long getClusterId() {
return clusterId;
}
- public Long getStoragepoolId() {
+ public Long getStoragePoolId() {
return storagePoolId;
}
@@ -128,6 +137,10 @@ public Long getImageStoreId() {
return imageStoreId;
}
+ public Long getManagementServerId() {
+ return managementServerId;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@@ -150,7 +163,7 @@ public void execute() {
ConfigurationResponse response = _responseGenerator.createConfigurationResponse(cfg);
response.setResponseName(getCommandName());
response = setResponseScopes(response);
- response = setResponseValue(response, cfg);
+ setResponseValue(response, cfg);
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update config");
@@ -161,15 +174,13 @@ public void execute() {
* Sets the configuration value in the response. If the configuration is in the `Hidden` or `Secure` categories, the value is encrypted before being set in the response.
* @param response to be set with the configuration `cfg` value
* @param cfg to be used in setting the response value
- * @return the response with the configuration's value
*/
- public ConfigurationResponse setResponseValue(ConfigurationResponse response, Configuration cfg) {
+ public void setResponseValue(ConfigurationResponse response, Configuration cfg) {
+ String value = cfg.getValue();
if (cfg.isEncrypted()) {
- response.setValue(DBEncryptionUtil.encrypt(getValue()));
- } else {
- response.setValue(getValue());
+ value = DBEncryptionUtil.encrypt(value);
}
- return response;
+ response.setValue(value);
}
/**
@@ -184,7 +195,7 @@ public ConfigurationResponse setResponseScopes(ConfigurationResponse response) {
if (getClusterId() != null) {
response.setScope("cluster");
}
- if (getStoragepoolId() != null) {
+ if (getStoragePoolId() != null) {
response.setScope("storagepool");
}
if (getAccountId() != null) {
@@ -193,6 +204,9 @@ public ConfigurationResponse setResponseScopes(ConfigurationResponse response) {
if (getDomainId() != null) {
response.setScope("domain");
}
+ if (getManagementServerId() != null) {
+ response.setScope(ConfigKey.Scope.ManagementServer.name().toLowerCase());
+ }
return response;
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateHypervisorCapabilitiesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateHypervisorCapabilitiesCmd.java
index 01f7af108416..d7342654ec40 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateHypervisorCapabilitiesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateHypervisorCapabilitiesCmd.java
@@ -43,28 +43,28 @@ public class UpdateHypervisorCapabilitiesCmd extends BaseCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HypervisorCapabilitiesResponse.class, description = "ID of the hypervisor capability")
private Long id;
- @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, description = "the hypervisor for which the hypervisor capabilities are to be updated", since = "4.19.1")
+ @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, description = "The hypervisor for which the hypervisor capabilities are to be updated", since = "4.19.1")
private String hypervisor;
- @Parameter(name = ApiConstants.HYPERVISOR_VERSION, type = CommandType.STRING, description = "the hypervisor version for which the hypervisor capabilities are to be updated", since = "4.19.1")
+ @Parameter(name = ApiConstants.HYPERVISOR_VERSION, type = CommandType.STRING, description = "The hypervisor version for which the hypervisor capabilities are to be updated", since = "4.19.1")
private String hypervisorVersion;
- @Parameter(name = ApiConstants.SECURITY_GROUP_EANBLED, type = CommandType.BOOLEAN, description = "set true to enable security group for this hypervisor.")
+ @Parameter(name = ApiConstants.SECURITY_GROUP_EANBLED, type = CommandType.BOOLEAN, description = "Set true to enable security group for this hypervisor.")
private Boolean securityGroupEnabled;
- @Parameter(name = ApiConstants.MAX_GUESTS_LIMIT, type = CommandType.LONG, description = "the max number of Guest VMs per host for this hypervisor.")
+ @Parameter(name = ApiConstants.MAX_GUESTS_LIMIT, type = CommandType.LONG, description = "The maximum number of Guest Instances per host for this hypervisor.")
private Long maxGuestsLimit;
- @Parameter(name = ApiConstants.MAX_DATA_VOLUMES_LIMIT, type = CommandType.INTEGER, description = "the maximum number of Data Volumes that can be attached to a VM for this hypervisor.", since = "4.16.0")
+ @Parameter(name = ApiConstants.MAX_DATA_VOLUMES_LIMIT, type = CommandType.INTEGER, description = "The maximum number of Data Volumes that can be attached to an Instance for this hypervisor.", since = "4.16.0")
private Integer maxDataVolumesLimit;
- @Parameter(name = ApiConstants.STORAGE_MOTION_ENABLED, type = CommandType.BOOLEAN, description = "set true to enable storage motion support for this hypervisor", since = "4.16.0")
+ @Parameter(name = ApiConstants.STORAGE_MOTION_ENABLED, type = CommandType.BOOLEAN, description = "Set true to enable storage motion support for this hypervisor", since = "4.16.0")
private Boolean storageMotionSupported;
- @Parameter(name = ApiConstants.MAX_HOSTS_PER_CLUSTER, type = CommandType.INTEGER, description = "the maximum number of the hypervisor hosts per cluster ", since = "4.16.0")
+ @Parameter(name = ApiConstants.MAX_HOSTS_PER_CLUSTER, type = CommandType.INTEGER, description = "The maximum number of the hypervisor hosts per cluster ", since = "4.16.0")
private Integer maxHostsPerClusterLimit;
- @Parameter(name = ApiConstants.VM_SNAPSHOT_ENABELD, type = CommandType.BOOLEAN, description = "set true to enable VM snapshots for this hypervisor", since = "4.16.0")
+ @Parameter(name = ApiConstants.VM_SNAPSHOT_ENABELD, type = CommandType.BOOLEAN, description = "Set true to enable Instance Snapshots for this hypervisor", since = "4.16.0")
private Boolean vmSnapshotEnabled;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/GetDiagnosticsDataCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/GetDiagnosticsDataCmd.java
index 553ba6b1729d..c140de5aa01e 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/GetDiagnosticsDataCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/GetDiagnosticsDataCmd.java
@@ -48,7 +48,7 @@
entityType = {VirtualMachine.class},
responseHasSensitiveInfo = false,
requestHasSensitiveInfo = false,
- description = "Get diagnostics and files from system VMs",
+ description = "Get diagnostics and files from System VMs",
since = "4.14.0.0",
authorized = {RoleType.Admin})
public class GetDiagnosticsDataCmd extends BaseAsyncCmd {
@@ -64,7 +64,7 @@ public class GetDiagnosticsDataCmd extends BaseAsyncCmd {
entityType = SystemVmResponse.class,
required = true,
validations = {ApiArgValidator.PositiveNumber},
- description = "The ID of the system VM instance to retrieve diagnostics data files from")
+ description = "The ID of the System VM to retrieve diagnostics data files from")
private Long id;
@Parameter(name = ApiConstants.FILES,
@@ -113,7 +113,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
- throw new CloudRuntimeException("failed to generate valid download url: " + downloadUrl);
+ throw new CloudRuntimeException("Failed to generate valid download url: " + downloadUrl);
}
} catch (ServerApiException e) {
throw new CloudRuntimeException("Internal exception caught while retrieving diagnostics files: ", e);
@@ -140,7 +140,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Getting diagnostics data files from system vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+ return "Getting diagnostics data files from System Instance with ID: " + getResourceUuid(ApiConstants.TARGET_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java
index 4537eb6f215c..d1f22baf6604 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java
@@ -48,7 +48,7 @@
@APICommand(name = "runDiagnostics", responseObject = RunDiagnosticsResponse.class, entityType = {VirtualMachine.class},
responseHasSensitiveInfo = false,
requestHasSensitiveInfo = false,
- description = "Execute network-utility command (ping/arping/tracert) on system VMs remotely",
+ description = "Execute network-utility command (ping/arping/tracert) on System VMs remotely",
authorized = {RoleType.Admin},
since = "4.12.0.0")
public class RunDiagnosticsCmd extends BaseAsyncCmd {
@@ -62,7 +62,7 @@ public class RunDiagnosticsCmd extends BaseAsyncCmd {
@ACL(accessType = SecurityChecker.AccessType.OperateEntry)
@Parameter(name = ApiConstants.TARGET_ID, type = CommandType.UUID, required = true, entityType = SystemVmResponse.class,
validations = {ApiArgValidator.PositiveNumber},
- description = "The ID of the system VM instance to diagnose")
+ description = "The ID of the System VM to diagnose")
private Long id;
@Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = true,
@@ -70,7 +70,7 @@ public class RunDiagnosticsCmd extends BaseAsyncCmd {
private String address;
@Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, required = true,
- description = "The system VM diagnostics type valid options are: ping, traceroute, arping")
+ description = "The System VM diagnostics type valid options are: ping, traceroute, arping")
private String type;
@Parameter(name = ApiConstants.PARAMS, type = CommandType.STRING,
@@ -153,7 +153,7 @@ public ApiCommandResourceType getApiResourceType() {
@Override
public String getEventDescription() {
- return "Executing diagnostics on system vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+ return "Executing diagnostics on System Instance with ID: " + getResourceUuid(ApiConstants.TARGET_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/ListTemplateDirectDownloadCertificatesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/ListTemplateDirectDownloadCertificatesCmd.java
index 145ff6ba7823..9a605ec4200d 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/ListTemplateDirectDownloadCertificatesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/ListTemplateDirectDownloadCertificatesCmd.java
@@ -41,7 +41,7 @@
import java.util.List;
@APICommand(name = "listTemplateDirectDownloadCertificates",
- description = "List the uploaded certificates for direct download templates",
+ description = "List the uploaded certificates for direct download Templates",
responseObject = DirectDownloadCertificateResponse.class,
since = "4.17.0",
authorized = {RoleType.Admin})
@@ -51,15 +51,15 @@ public class ListTemplateDirectDownloadCertificatesCmd extends BaseListCmd {
DirectDownloadManager directDownloadManager;
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DirectDownloadCertificateResponse.class,
- description = "list direct download certificate by ID")
+ description = "List direct download certificate by ID")
private Long id;
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class,
- description = "the zone where certificates are uploaded")
+ description = "The zone where certificates are uploaded")
private Long zoneId;
@Parameter(name = ApiConstants.LIST_HOSTS, type = CommandType.BOOLEAN,
- description = "if set to true: include the hosts where the certificate is uploaded to")
+ description = "If set to true: include the hosts where the certificate is uploaded to")
private Boolean listHosts;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/ProvisionTemplateDirectDownloadCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/ProvisionTemplateDirectDownloadCertificateCmd.java
index 88f538547e10..3dfbbd940c40 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/ProvisionTemplateDirectDownloadCertificateCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/ProvisionTemplateDirectDownloadCertificateCmd.java
@@ -50,11 +50,11 @@ public class ProvisionTemplateDirectDownloadCertificateCmd extends BaseCmd {
DirectDownloadManager directDownloadManager;
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DirectDownloadCertificateResponse.class,
- description = "the id of the direct download certificate to provision", required = true)
+ description = "The id of the direct download certificate to provision", required = true)
private Long id;
@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class,
- description = "the host to provision the certificate", required = true)
+ description = "The host to provision the certificate", required = true)
private Long hostId;
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/RevokeTemplateDirectDownloadCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/RevokeTemplateDirectDownloadCertificateCmd.java
index eb9031cbc587..1ad8f271cfcf 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/RevokeTemplateDirectDownloadCertificateCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/RevokeTemplateDirectDownloadCertificateCmd.java
@@ -59,23 +59,23 @@ public class RevokeTemplateDirectDownloadCertificateCmd extends BaseCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID,
entityType = DirectDownloadCertificateResponse.class,
- description = "id of the certificate")
+ description = "ID of the certificate")
private Long certificateId;
@Parameter(name = ApiConstants.NAME, type = BaseCmd.CommandType.STRING,
- description = "(optional) alias of the SSL certificate")
+ description = "(Optional) alias of the SSL certificate")
private String certificateAlias;
@Parameter(name = ApiConstants.HYPERVISOR, type = BaseCmd.CommandType.STRING,
- description = "(optional) hypervisor type")
+ description = "(Optional) hypervisor type")
private String hypervisor;
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class,
- description = "(optional) zone to revoke certificate", required = true)
+ description = "(Optional) zone to revoke certificate", required = true)
private Long zoneId;
@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class,
- description = "(optional) the host ID to revoke certificate")
+ description = "(Optional) the host ID to revoke certificate")
private Long hostId;
private void createResponse(final List hostsRevokeStatusList) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java
index c5c102be56d6..ad440376a913 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java
@@ -39,7 +39,7 @@
import java.util.List;
@APICommand(name = "uploadTemplateDirectDownloadCertificate",
- description = "Upload a certificate for HTTPS direct template download on KVM hosts",
+ description = "Upload a certificate for HTTPS direct Template download on KVM hosts",
responseObject = DirectDownloadCertificateResponse.class,
since = "4.11.0",
authorized = {RoleType.Admin})
@@ -65,7 +65,7 @@ public class UploadTemplateDirectDownloadCertificateCmd extends BaseCmd {
private Long zoneId;
@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class,
- description = "(optional) the host ID to upload certificate")
+ description = "(Optional) the host ID to upload certificate")
private Long hostId;
private void createResponse(DirectDownloadCertificate certificate, final List hostStatusList) {
@@ -95,7 +95,7 @@ public void execute() {
}
try {
- logger.debug("Uploading certificate " + name + " to agents for Direct Download");
+ logger.debug("Uploading certificate {} to agents for Direct Download", name);
Pair> uploadStatus =
directDownloadManager.uploadCertificateToHosts(certificate, name, hypervisor, zoneId, hostId);
DirectDownloadCertificate certificate = uploadStatus.first();
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java
index c7f06920bb8d..d2775548a841 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java
@@ -40,13 +40,13 @@ public class CreateDomainCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "creates domain with this name")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Creates domain with this name")
private String domainName;
@Parameter(name = ApiConstants.PARENT_DOMAIN_ID,
type = CommandType.UUID,
entityType = DomainResponse.class,
- description = "assigns new domain a parent domain by domain ID of the parent. If no parent domain is specified, the ROOT domain is assumed.")
+ description = "Assigns new domain a parent domain by domain ID of the parent. If no parent domain is specified, the ROOT domain is assumed.")
private Long parentDomainId;
@Parameter(name = ApiConstants.NETWORK_DOMAIN, type = CommandType.STRING, description = "Network domain for networks in the domain")
@@ -86,7 +86,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Domain Name: " + getDomainName() + ((getParentDomainId() != null) ? ", Parent DomainId :" + getParentDomainId() : ""));
+ CallContext.current().setEventDetails("Domain Name: " + getDomainName() + ((getParentDomainId() != null) ? ", Parent Domain ID:" + getResourceUuid(ApiConstants.PARENT_DOMAIN_ID) : ""));
Domain domain = _domainService.createDomain(getDomainName(), getParentDomainId(), getNetworkDomain(), getDomainUUID());
if (domain != null) {
DomainResponse response = _responseGenerator.createDomainResponse(domain);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java
index db3bae25e399..cf02e6a56bf8 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java
@@ -49,7 +49,7 @@ public class DeleteDomainCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.CLEANUP,
type = CommandType.BOOLEAN,
- description = "true if all domain resources (child domains, accounts) have to be cleaned up, false otherwise")
+ description = "True if all domain resources (child domains, Accounts) have to be cleaned up, false otherwise")
private Boolean cleanup;
@Inject
@@ -88,12 +88,12 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "deleting domain: " + getId();
+ return "Deleting domain with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
public void execute() {
- CallContext.current().setEventDetails("Domain Id: " + getId());
+ CallContext.current().setEventDetails("Domain ID: " + getResourceUuid(ApiConstants.ID));
boolean result = _regionService.deleteDomain(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainChildrenCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainChildrenCmd.java
index 8514bb6dda56..e93948987bb7 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainChildrenCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainChildrenCmd.java
@@ -42,15 +42,15 @@ public class ListDomainChildrenCmd extends BaseListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "list children domain by parent domain ID.")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "List children domain by parent domain ID.")
private Long id;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "list children domains by name")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "List children domains by name")
private String domainName;
@Parameter(name = ApiConstants.IS_RECURSIVE,
type = CommandType.BOOLEAN,
- description = "to return the entire tree, use the value \"true\". To return the first level children, use the value \"false\".")
+ description = "To return the entire tree, use the value \"true\". To return the first level children, use the value \"false\".")
private Boolean recursive;
@Parameter(name = ApiConstants.LIST_ALL,
@@ -59,7 +59,7 @@ public class ListDomainChildrenCmd extends BaseListCmd {
private Boolean listAll;
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN,
- description = "flag to display the resource icon for domains")
+ description = "Flag to display the resource icon for domains")
private Boolean showIcon;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java
index 895e93289923..aa1978042265 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java
@@ -23,7 +23,7 @@
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiConstants.DomainDetails;
-import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.BaseListTaggedResourcesCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.command.user.UserCmd;
@@ -39,7 +39,7 @@
@APICommand(name = "listDomains", description = "Lists domains and provides detailed information for listed domains", responseObject = DomainResponse.class, responseView = ResponseView.Restricted, entityType = {Domain.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ListDomainsCmd extends BaseListCmd implements UserCmd {
+public class ListDomainsCmd extends BaseListTaggedResourcesCmd implements UserCmd {
private static final String s_name = "listdomainsresponse";
@@ -64,11 +64,11 @@ public class ListDomainsCmd extends BaseListCmd implements UserCmd {
@Parameter(name = ApiConstants.DETAILS,
type = CommandType.LIST,
collectionType = CommandType.STRING,
- description = "comma separated list of domain details requested, value can be a list of [ all, resource, min]")
+ description = "Comma separated list of domain details requested, value can be a list of [ all, resource, min]")
private List viewDetails;
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN,
- description = "flag to display the resource icon for domains")
+ description = "Flag to display the resource icon for domains")
private Boolean showIcon;
@Parameter(name = ApiConstants.TAG, type = CommandType.STRING, description = "Tag for resource type to return usage", since = "4.20.0")
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java
index 353cb852bfdf..124a84931548 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java
@@ -44,7 +44,7 @@ public class UpdateDomainCmd extends BaseCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainResponse.class, required = true, description = "ID of domain to update")
private Long id;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "updates domain with this name")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Updates domain with this name")
private String domainName;
@Parameter(name = ApiConstants.NETWORK_DOMAIN,
@@ -82,7 +82,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Domain Id: " + getId());
+ CallContext.current().setEventDetails("Domain ID: " + getResourceUuid(ApiConstants.ID));
Domain domain = _regionService.updateDomain(this);
if (domain != null) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/gpu/DiscoverGpuDevicesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/gpu/DiscoverGpuDevicesCmd.java
index 2ac07a9fb3a0..83aca1a2eb64 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/gpu/DiscoverGpuDevicesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/gpu/DiscoverGpuDevicesCmd.java
@@ -46,7 +46,7 @@ public class DiscoverGpuDevicesCmd extends BaseListCmd {
@Override
public void execute() {
- CallContext.current().setEventDetails("Discovering GPU Devices on host id: " + getId());
+ CallContext.current().setEventDetails("Discovering GPU Devices on host with ID: " + getResourceUuid(ApiConstants.ID));
ListResponse response = gpuService.discoverGpuDevices(this);
response.setResponseName(getCommandName());
setResponseObject(response);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
index b854e8389c4f..c0e995c497d2 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
@@ -120,7 +120,7 @@ public void create() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Guest OS Id: " + getEntityId());
+ CallContext.current().setEventDetails("Guest OS ID: " + getEntityUuid());
GuestOS guestOs = _mgr.getAddedGuestOs(getEntityId());
if (guestOs != null) {
GuestOSResponse response = _responseGenerator.createGuestOSResponse(guestOs);
@@ -138,7 +138,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "adding a new guest OS type Id: " + getEntityId();
+ return "Adding a new guest OS type Id: " + getEntityId();
}
@Override
@@ -153,7 +153,7 @@ public String getCreateEventType() {
@Override
public String getCreateEventDescription() {
- return "adding new guest OS type";
+ return "Adding new guest OS type";
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java
index 3fdfebb54bf5..1a32168308ed 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java
@@ -133,7 +133,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "adding a new guest OS mapping Id: " + getEntityId();
+ return "Adding a new guest OS mapping Id: " + getEntityId();
}
@Override
@@ -148,6 +148,6 @@ public String getCreateEventType() {
@Override
public String getCreateEventDescription() {
- return "adding new guest OS mapping";
+ return "Adding new guest OS mapping";
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/GetHypervisorGuestOsNamesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/GetHypervisorGuestOsNamesCmd.java
index da920a2ec2d0..811ecc8b165b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/GetHypervisorGuestOsNamesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/GetHypervisorGuestOsNamesCmd.java
@@ -44,11 +44,11 @@ public class GetHypervisorGuestOsNamesCmd extends BaseAsyncCmd {
validations = {ApiArgValidator.NotNullOrEmpty})
private String hypervisor;
- @Parameter(name = ApiConstants.HYPERVISOR_VERSION, type = CommandType.STRING, required = true, description = "Hypervisor version to get the guest os names (atleast one hypervisor host with the version specified must be available)",
+ @Parameter(name = ApiConstants.HYPERVISOR_VERSION, type = CommandType.STRING, required = true, description = "Hypervisor version to get the guest OS names (at least one hypervisor host with the version specified must be available)",
validations = {ApiArgValidator.NotNullOrEmpty})
private String hypervisorVersion;
- @Parameter(name = ApiConstants.KEYWORD, type = CommandType.STRING, required = false, description = "Keyword for guest os name")
+ @Parameter(name = ApiConstants.KEYWORD, type = CommandType.STRING, required = false, description = "Keyword for guest OS name")
private String keyword;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/ListGuestOsMappingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/ListGuestOsMappingCmd.java
index 23e62cdc7810..47082dae68c2 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/ListGuestOsMappingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/ListGuestOsMappingCmd.java
@@ -40,22 +40,22 @@ public class ListGuestOsMappingCmd extends BaseListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = GuestOsMappingResponse.class, required = false, description = "list mapping by its UUID")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = GuestOsMappingResponse.class, required = false, description = "List mapping by its UUID")
private Long id;
- @Parameter(name = ApiConstants.OS_TYPE_ID, type = CommandType.UUID, entityType = GuestOSResponse.class, required = false, description = "list mapping by Guest OS Type UUID")
+ @Parameter(name = ApiConstants.OS_TYPE_ID, type = CommandType.UUID, entityType = GuestOSResponse.class, required = false, description = "List mapping by Guest OS Type UUID")
private Long osTypeId;
- @Parameter(name = ApiConstants.OS_DISPLAY_NAME, type = CommandType.STRING, required = false, description = "list Guest OS mapping by OS display name")
+ @Parameter(name = ApiConstants.OS_DISPLAY_NAME, type = CommandType.STRING, required = false, description = "List Guest OS mapping by OS display name")
private String osDisplayName;
- @Parameter(name = ApiConstants.OS_NAME_FOR_HYPERVISOR, type = CommandType.STRING, required = false, description = "list Guest OS mapping by OS mapping name with hypervisor")
+ @Parameter(name = ApiConstants.OS_NAME_FOR_HYPERVISOR, type = CommandType.STRING, required = false, description = "List Guest OS mapping by OS mapping name with hypervisor")
private String osNameForHypervisor;
- @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, required = false, description = "list Guest OS mapping by hypervisor")
+ @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, required = false, description = "List Guest OS mapping by hypervisor")
private String hypervisor;
- @Parameter(name = ApiConstants.HYPERVISOR_VERSION, type = CommandType.STRING, required = false, description = "list Guest OS mapping by hypervisor version. Must be used with hypervisor parameter")
+ @Parameter(name = ApiConstants.HYPERVISOR_VERSION, type = CommandType.STRING, required = false, description = "List Guest OS mapping by hypervisor version. Must be used with hypervisor parameter")
private String hypervisorVersion;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java
index d38682ce5bb4..f5c7d965c13f 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java
@@ -62,7 +62,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Guest OS Id: " + id);
+ CallContext.current().setEventDetails("Guest OS ID: " + getResourceUuid(ApiConstants.ID));
boolean result = _mgr.removeGuestOs(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
@@ -74,7 +74,7 @@ public void execute() {
@Override
public String getEventDescription() {
- return "Removing Guest OS: " + getId();
+ return "Removing Guest OS with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java
index a472ab672c55..bd4a53889f25 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java
@@ -62,7 +62,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Guest OS Mapping Id: " + id);
+ CallContext.current().setEventDetails("Guest OS Mapping ID: " + getResourceUuid(ApiConstants.ID));
boolean result = _mgr.removeGuestOsMapping(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
@@ -74,7 +74,7 @@ public void execute() {
@Override
public String getEventDescription() {
- return "Removing Guest OS Mapping: " + getId();
+ return "Removing Guest OS Mapping with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
index 59909e09854a..035ff6a19e24 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
@@ -123,7 +123,7 @@ public void execute() {
@Override
public String getEventDescription() {
- return "Updating guest OS: " + getId();
+ return "Updating guest OS with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java
index fc67ef0a7e76..161bb5323070 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java
@@ -86,7 +86,7 @@ public long getEntityOwnerId() {
@Override
public String getEventDescription() {
- return "Updating Guest OS Mapping: " + getId();
+ return "Updating Guest OS with ID: " + getResourceUuid(ApiConstants.ID) + " mapping.";
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java
index 12033c04b80f..cb427e659495 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java
@@ -87,6 +87,7 @@ private void setupResponse(final boolean result, final String resourceUuid) {
final HostHAResponse response = new HostHAResponse();
response.setId(resourceUuid);
response.setProvider(getHaProvider().toLowerCase());
+ response.setStatus(result);
response.setResponseName(getCommandName());
setResponseObject(response);
}
@@ -102,7 +103,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
if (!result) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to configure HA provider for the host");
}
- CallContext.current().setEventDetails("Host Id:" + host.getId() + " HA configured with provider: " + getHaProvider());
+ CallContext.current().setEventDetails("Host ID:" + host.getUuid() + " HA configured with provider: " + getHaProvider());
CallContext.current().putContextParameter(Host.class, host.getUuid());
setupResponse(result, host.getUuid());
@@ -115,6 +116,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "configure HA for host: " + getHostId();
+ return "Configuring HA for host with ID: " + getResourceUuid(ApiConstants.HOST_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java
index d570746765be..63c657a9e454 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java
@@ -89,7 +89,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to find cluster by ID: " + getClusterId());
}
final boolean result = haConfigManager.disableHA(cluster);
- CallContext.current().setEventDetails("Cluster Id:" + cluster.getId() + " HA enabled: false");
+ CallContext.current().setEventDetails("Cluster ID:" + cluster.getUuid() + " HA enabled: false");
CallContext.current().putContextParameter(Cluster.class, cluster.getUuid());
setupResponse(result);
@@ -102,7 +102,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "disable HA for cluster: " + getClusterId();
+ return "Disabling HA for cluster with ID: " + getResourceUuid(ApiConstants.CLUSTER_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java
index 5a8b1f1954f2..b90f731ff565 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java
@@ -91,7 +91,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
}
final boolean result = haConfigManager.disableHA(host.getId(), HAResource.ResourceType.Host);
- CallContext.current().setEventDetails("Host Id:" + host.getId() + " HA enabled: false");
+ CallContext.current().setEventDetails("Host ID:" + host.getUuid() + " HA enabled: false");
CallContext.current().putContextParameter(Host.class, host.getUuid());
setupResponse(result, host.getUuid());
@@ -104,6 +104,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "disable HA for host: " + getHostId();
+ return "Disabling HA for host with ID: " + getResourceUuid(ApiConstants.HOST_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java
index fbd57fa82a15..07a6fbd2b399 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java
@@ -90,7 +90,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
}
final boolean result = haConfigManager.disableHA(dataCenter);
- CallContext.current().setEventDetails("Zone Id:" + dataCenter.getId() + " HA enabled: false");
+ CallContext.current().setEventDetails("Zone ID:" + dataCenter.getUuid() + " HA enabled: false");
CallContext.current().putContextParameter(DataCenter.class, dataCenter.getUuid());
setupResponse(result);
@@ -103,7 +103,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "disable HA for zone: " + getZoneId();
+ return "Disabling HA for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java
index 7e627939ca55..635fba988c60 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java
@@ -90,7 +90,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
}
final boolean result = haConfigManager.enableHA(cluster);
- CallContext.current().setEventDetails("Cluster Id:" + cluster.getId() + " HA enabled: true");
+ CallContext.current().setEventDetails("Cluster ID:" + cluster.getUuid() + " HA enabled: true");
CallContext.current().putContextParameter(Cluster.class, cluster.getUuid());
setupResponse(result);
@@ -103,6 +103,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "enable HA for cluster: " + getClusterId();
+ return "Enabling HA for cluster with ID: " + getResourceUuid(ApiConstants.CLUSTER_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java
index aac3d3505198..0bda19a7ad3c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java
@@ -91,7 +91,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
}
final boolean result = haConfigManager.enableHA(host.getId(), HAResource.ResourceType.Host);
- CallContext.current().setEventDetails("Host Id:" + host.getId() + " HA enabled: true");
+ CallContext.current().setEventDetails("Host ID:" + host.getUuid() + " HA enabled: true");
CallContext.current().putContextParameter(Host.class, host.getUuid());
setupResponse(result, host.getUuid());
@@ -104,6 +104,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "enable HA for host: " + getHostId();
+ return "Enabling HA for host with ID: " + getResourceUuid(ApiConstants.HOST_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java
index f9b1560bd8a1..f6d0f62bb120 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java
@@ -90,7 +90,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
}
final boolean result = haConfigManager.enableHA(dataCenter);
- CallContext.current().setEventDetails("Zone Id:" + dataCenter.getId() + " HA enabled: true");
+ CallContext.current().setEventDetails("Zone ID:" + dataCenter.getUuid() + " HA enabled: true");
CallContext.current().putContextParameter(DataCenter.class, dataCenter.getUuid());
setupResponse(result);
@@ -103,7 +103,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "enable HA for zone: " + getZoneId();
+ return "Enabling HA for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddHostCmd.java
index cc124ab8106e..5a1758345609 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddHostCmd.java
@@ -45,34 +45,35 @@ public class AddHostCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.CLUSTER_ID, type = CommandType.UUID, entityType = ClusterResponse.class, description = "the cluster ID for the host")
+ @Parameter(name = ApiConstants.CLUSTER_ID, type = CommandType.UUID, entityType = ClusterResponse.class, description = "The cluster ID for the host")
private Long clusterId;
- @Parameter(name = ApiConstants.CLUSTER_NAME, type = CommandType.STRING, description = "the cluster name for the host")
+ @Parameter(name = ApiConstants.CLUSTER_NAME, type = CommandType.STRING, description = "The cluster name for the host")
private String clusterName;
- @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "the username for the host; required to be passed for hypervisors other than VMWare")
+ @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "The username for the host; required to be passed for hypervisors other than VMWare")
private String username;
- @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "the password for the host; required to be passed for hypervisors other than VMWare")
+ @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for the host; required to be passed for hypervisors other than VMWare")
private String password;
- @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, required = true, description = "the Pod ID for the host")
+ @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, required = true, description = "The Pod ID for the host")
private Long podId;
- @Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = true, description = "the host URL")
+ @Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = true, description = "The host URL, optionally add ssh port (format: 'host:port') for KVM hosts," +
+ " otherwise falls back to the port defined at the config 'kvm.host.discovery.ssh.port'")
private String url;
- @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "the Zone ID for the host")
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "The Zone ID for the host")
private Long zoneId;
- @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, required = true, description = "hypervisor type of the host")
+ @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, required = true, description = "Hypervisor type of the host")
private String hypervisor;
@Parameter(name = ApiConstants.ALLOCATION_STATE, type = CommandType.STRING, description = "Allocation state of this Host for allocation of new resources")
private String allocationState;
- @Parameter(name = ApiConstants.HOST_TAGS, type = CommandType.LIST, collectionType = CommandType.STRING, description = "list of tags to be added to the host")
+ @Parameter(name = ApiConstants.HOST_TAGS, type = CommandType.LIST, collectionType = CommandType.STRING, description = "List of tags to be added to the host")
private List hostTags;
@Parameter(name = ApiConstants.STORAGE_ACCESS_GROUPS,
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java
index c965a39450bd..585fd1b87a88 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java
@@ -29,6 +29,11 @@
import com.cloud.exception.DiscoveryException;
import com.cloud.storage.ImageStore;
import com.cloud.user.Account;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
@APICommand(name = "addSecondaryStorage", description = "Adds secondary storage.", responseObject = ImageStoreResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@@ -38,12 +43,15 @@ public class AddSecondaryStorageCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = true, description = "the URL for the secondary storage")
+ @Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = true, description = "The URL for the secondary storage")
protected String url;
- @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the Zone ID for the secondary storage")
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "The Zone ID for the secondary storage")
protected Long zoneId;
+ @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Details in key/value pairs using format details[i].keyname=keyvalue. Example: details[0].copytemplatesfromothersecondarystorages=true")
+ protected Map details;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -56,6 +64,20 @@ public Long getZoneId() {
return zoneId;
}
+ public Map getDetails() {
+ Map detailsMap = new HashMap<>();
+ if (MapUtils.isNotEmpty(details)) {
+ Collection> props = details.values();
+ for (Object prop : props) {
+ HashMap detail = (HashMap) prop;
+ for (Map.Entry entry: detail.entrySet()) {
+ detailsMap.put(entry.getKey(),entry.getValue());
+ }
+ }
+ }
+ return detailsMap;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@@ -68,7 +90,7 @@ public long getEntityOwnerId() {
@Override
public void execute(){
try{
- ImageStore result = _storageService.discoverImageStore(null, getUrl(), "NFS", getZoneId(), null);
+ ImageStore result = _storageService.discoverImageStore(null, getUrl(), "NFS", getZoneId(), getDetails());
ImageStoreResponse storeResponse = null;
if (result != null ) {
storeResponse = _responseGenerator.createImageStoreResponse(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostAsDegradedCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostAsDegradedCmd.java
index 4e9d997b3b76..56930d47b2ec 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostAsDegradedCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostAsDegradedCmd.java
@@ -47,7 +47,7 @@ public class CancelHostAsDegradedCmd extends BaseAsyncCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, entityType = HostResponse.class, description = "host ID", required = true, validations = {ApiArgValidator.PositiveNumber})
+ @Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, entityType = HostResponse.class, description = "Host ID", required = true, validations = {ApiArgValidator.PositiveNumber})
private Long id;
/////////////////////////////////////////////////////
@@ -78,7 +78,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "declaring host: " + getId() + " as Degraded";
+ return "Removing host with ID: " + getResourceUuid(ApiConstants.ID) + " from Degraded state.";
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostMaintenanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostMaintenanceCmd.java
index 55fe8ec23cec..5d44bafb4b5c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostMaintenanceCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostMaintenanceCmd.java
@@ -40,7 +40,7 @@ public class CancelHostMaintenanceCmd extends BaseAsyncCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "the host ID")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "The host ID")
private Long id;
/////////////////////////////////////////////////////
@@ -76,7 +76,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "canceling maintenance for host: " + getId();
+ return "Canceling maintenance for host with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeclareHostAsDegradedCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeclareHostAsDegradedCmd.java
index 6bb8f382e541..1dd65a583706 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeclareHostAsDegradedCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeclareHostAsDegradedCmd.java
@@ -33,7 +33,7 @@
import org.apache.cloudstack.context.CallContext;
@APICommand(name = "declareHostAsDegraded",
- description = "Declare host as 'Degraded'. Host must be on 'Disconnected' or 'Alert' state. The ADMIN must be sure that there are no VMs running on the respective host otherwise this command might corrupted VMs that were running on the 'Degraded' host.",
+ description = "Declare host as 'Degraded'. Host must be on 'Disconnected' or 'Alert' state. The ADMIN must be sure that there are no Instances running on the respective host otherwise this command might corrupted Instances that were running on the 'Degraded' host.",
since = "4.16.0.0",
responseObject = HostResponse.class,
requestHasSensitiveInfo = false,
@@ -47,7 +47,7 @@ public class DeclareHostAsDegradedCmd extends BaseAsyncCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, entityType = HostResponse.class, description = "host ID", required = true, validations = {ApiArgValidator.PositiveNumber})
+ @Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, entityType = HostResponse.class, description = "Host ID", required = true, validations = {ApiArgValidator.PositiveNumber})
private Long id;
/////////////////////////////////////////////////////
@@ -78,7 +78,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "declaring host: " + getId() + " as Degraded";
+ return "Declaring host with ID: " + getResourceUuid(ApiConstants.ID) + " as Degraded.";
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeleteHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeleteHostCmd.java
index 38325c2f072d..79ad1acec9f6 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeleteHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeleteHostCmd.java
@@ -37,17 +37,17 @@ public class DeleteHostCmd extends BaseCmd {
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "the host ID")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "The host ID")
private Long id;
@Parameter(name = ApiConstants.FORCED,
type = CommandType.BOOLEAN,
- description = "Force delete the host. All HA enabled vms running on the host will be put to HA; HA disabled ones will be stopped")
+ description = "Force delete the host. All HA enabled Instances running on the host will be put to HA; HA disabled ones will be stopped")
private Boolean forced;
@Parameter(name = ApiConstants.FORCED_DESTROY_LOCAL_STORAGE,
type = CommandType.BOOLEAN,
- description = "Force destroy local storage on this host. All VMs created on this local storage will be destroyed")
+ description = "Force destroy local storage on this host. All Instances created on this local storage will be destroyed")
private Boolean forceDestroyLocalStorage;
// ///////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java
index db30e4f4c02f..4d6ef7419616 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java
@@ -33,7 +33,7 @@
import com.cloud.utils.Pair;
import com.cloud.utils.Ternary;
-@APICommand(name = "findHostsForMigration", description = "Find hosts suitable for migrating a virtual machine.", responseObject = HostForMigrationResponse.class,
+@APICommand(name = "findHostsForMigration", description = "Find hosts suitable for migrating an Instance.", responseObject = HostForMigrationResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class FindHostsForMigrationCmd extends BaseListCmd {
@@ -46,7 +46,7 @@ public class FindHostsForMigrationCmd extends BaseListCmd {
type = CommandType.UUID,
entityType = UserVmResponse.class,
required = true,
- description = "find hosts to which this VM can be migrated and flag the hosts with enough " + "CPU/RAM to host the VM")
+ description = "Find hosts to which this Instance can be migrated and flag the hosts with enough " + "CPU/RAM to host the Instance")
private Long virtualMachineId;
/////////////////////////////////////////////////////
@@ -78,7 +78,7 @@ public void execute() {
for (Host host : result.first()) {
HostForMigrationResponse hostResponse = _responseGenerator.createHostForMigrationResponse(host);
Boolean suitableForMigration = false;
- if (hostsWithCapacity.contains(host)) {
+ if (hostsWithCapacity != null && hostsWithCapacity.contains(host)) {
suitableForMigration = true;
}
hostResponse.setSuitableForMigration(suitableForMigration);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java
index a71150a69e27..8f5e6c784d6e 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java
@@ -52,59 +52,59 @@ public class ListHostsCmd extends BaseListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.CLUSTER_ID, type = CommandType.UUID, entityType = ClusterResponse.class, description = "lists hosts existing in particular cluster")
+ @Parameter(name = ApiConstants.CLUSTER_ID, type = CommandType.UUID, entityType = ClusterResponse.class, description = "Lists hosts existing in particular cluster")
private Long clusterId;
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, description = "the id of the host")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, description = "The ID of the host")
private Long id;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the host")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "The name of the host")
private String hostName;
- @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, description = "the Pod ID for the host")
+ @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, description = "The Pod ID for the host")
private Long podId;
- @Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "the state of the host")
+ @Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "The state of the host")
private String state;
- @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "the host type")
+ @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "The host type")
private String type;
- @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the Zone ID for the host")
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "The Zone ID for the host")
private Long zoneId;
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
type = CommandType.UUID,
entityType = UserVmResponse.class,
required = false,
- description = "lists hosts in the same cluster as this VM and flag hosts with enough CPU/RAm to host this VM")
+ description = "Lists hosts in the same cluster as this Instance and flag hosts with enough CPU/RAm to host this Instance")
private Long virtualMachineId;
@Parameter(name = ApiConstants.OUTOFBANDMANAGEMENT_ENABLED,
type = CommandType.BOOLEAN,
- description = "list hosts for which out-of-band management is enabled")
+ description = "List hosts for which out-of-band management is enabled")
private Boolean outOfBandManagementEnabled;
@Parameter(name = ApiConstants.OUTOFBANDMANAGEMENT_POWERSTATE,
type = CommandType.STRING,
- description = "list hosts by its out-of-band management interface's power state. Its value can be one of [On, Off, Unknown]")
+ description = "List hosts by its out-of-band management interface's power state. Its value can be one of [On, Off, Unknown]")
private String outOfBandManagementPowerState;
@Parameter(name = ApiConstants.RESOURCE_STATE,
type = CommandType.STRING,
- description = "list hosts by resource state. Resource state represents current state determined by admin of host, value can be one of [Enabled, Disabled, Unmanaged, PrepareForMaintenance, ErrorInMaintenance, Maintenance, Error]")
+ description = "List hosts by resource state. Resource state represents current state determined by admin of host, value can be one of [Enabled, Disabled, Unmanaged, PrepareForMaintenance, ErrorInMaintenance, Maintenance, Error]")
private String resourceState;
@Parameter(name = ApiConstants.DETAILS,
type = CommandType.LIST,
collectionType = CommandType.STRING,
- description = "comma separated list of host details requested, value can be a list of [ min, all, capacity, events, stats]")
+ description = "Comma separated list of host details requested, value can be a list of [ min, all, capacity, events, stats]")
private List viewDetails;
- @Parameter(name = ApiConstants.HA_HOST, type = CommandType.BOOLEAN, description = "if true, list only hosts dedicated to HA")
+ @Parameter(name = ApiConstants.HA_HOST, type = CommandType.BOOLEAN, description = "If true, list only hosts dedicated to HA")
private Boolean haHost;
- @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, description = "hypervisor type of host: XenServer,KVM,VMware,Hyperv,BareMetal,Simulator")
+ @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, description = "Hypervisor type of host: XenServer,KVM,VMware,Hyperv,BareMetal,Simulator")
private String hypervisor;
@Parameter(name = ApiConstants.MANAGEMENT_SERVER_ID, type = CommandType.UUID, entityType = ManagementServerResponse.class, description = "the id of the management server", since="4.21.0")
@@ -118,6 +118,9 @@ public class ListHostsCmd extends BaseListCmd {
since = "4.21.0")
private String storageAccessGroup;
+ @Parameter(name = ApiConstants.VERSION, type = CommandType.STRING, description = "the host version", since = "4.20.3")
+ private String version;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -222,6 +225,10 @@ public ListHostsCmd(String storageAccessGroup) {
this.storageAccessGroup = storageAccessGroup;
}
+ public String getVersion() {
+ return version;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@@ -245,7 +252,7 @@ protected ListResponse getHostResponses() {
for (Host host : result.first()) {
HostResponse hostResponse = _responseGenerator.createHostResponse(host, getDetails());
Boolean suitableForMigration = false;
- if (hostsWithCapacity.contains(host)) {
+ if (hostsWithCapacity != null && hostsWithCapacity.contains(host)) {
suitableForMigration = true;
}
hostResponse.setSuitableForMigration(suitableForMigration);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForHostMaintenanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForHostMaintenanceCmd.java
index 5c2b50c87239..843c7fd7fcbe 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForHostMaintenanceCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForHostMaintenanceCmd.java
@@ -40,7 +40,7 @@ public class PrepareForHostMaintenanceCmd extends BaseAsyncCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "the host ID")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "The host ID")
private Long id;
/////////////////////////////////////////////////////
@@ -76,7 +76,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "preparing host: " + getId() + " for maintenance";
+ return "Preparing host with ID: " + getResourceUuid(ApiConstants.ID) + " for maintenance.";
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java
index 3550d61fdb97..b9892ed6033c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java
@@ -41,7 +41,7 @@ public class ReconnectHostCmd extends BaseAsyncCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "the host ID")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "The host ID")
private Long id;
/////////////////////////////////////////////////////
@@ -77,7 +77,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "reconnecting host: " + getId();
+ return "Reconnecting host with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java
index 7fee0684c781..bddb5b13e452 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java
@@ -40,7 +40,7 @@ public class ReleaseHostReservationCmd extends BaseAsyncCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "the host ID")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "The host ID")
private Long id;
/////////////////////////////////////////////////////
@@ -72,7 +72,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "releasing reservation for host: " + getId();
+ return "Releasing reservation from host with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java
index 86f002b9b7da..69bca7c79e21 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java
@@ -40,7 +40,7 @@ public class UpdateHostCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "the ID of the host to update")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "The ID of the host to update")
private Long id;
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Change the name of host", since = "4.15", authorized = {RoleType.Admin})
@@ -49,21 +49,26 @@ public class UpdateHostCmd extends BaseCmd {
@Parameter(name = ApiConstants.OS_CATEGORY_ID,
type = CommandType.UUID,
entityType = GuestOSCategoryResponse.class,
- description = "the id of Os category to update the host with")
+ description = "the ID of OS category used to prioritize VMs with matching OS category during the allocation process. " +
+ "It cannot be used alongside the 'guestosrule' parameter.")
private Long osCategoryId;
+ @Parameter(name = ApiConstants.GUEST_OS_RULE, type = CommandType.STRING, description = "the guest OS rule written in JavaScript to match with the OS of the VM." +
+ "It cannot be used alongside the 'oscategoryid' parameter.")
+ private String guestOsRule;
+
@Parameter(name = ApiConstants.ALLOCATION_STATE,
type = CommandType.STRING,
description = "Change resource state of host, valid values are [Enable, Disable]. Operation may failed if host in states not allowing Enable/Disable")
private String allocationState;
- @Parameter(name = ApiConstants.HOST_TAGS, type = CommandType.LIST, collectionType = CommandType.STRING, description = "list of tags to be added to the host")
+ @Parameter(name = ApiConstants.HOST_TAGS, type = CommandType.LIST, collectionType = CommandType.STRING, description = "List of tags to be added to the host")
private List hostTags;
@Parameter(name = ApiConstants.IS_TAG_A_RULE, type = CommandType.BOOLEAN, description = ApiConstants.PARAMETER_DESCRIPTION_IS_TAG_A_RULE)
private Boolean isTagARule;
- @Parameter(name = ApiConstants.URL, type = CommandType.STRING, description = "the new uri for the secondary storage: nfs://host/path")
+ @Parameter(name = ApiConstants.URL, type = CommandType.STRING, description = "The new URI for the secondary storage: nfs://host/path")
private String url;
@Parameter(name = ApiConstants.ANNOTATION, type = CommandType.STRING, description = "Add an annotation to this host", since = "4.11", authorized = {RoleType.Admin})
@@ -96,6 +101,10 @@ public Long getOsCategoryId() {
return osCategoryId;
}
+ public String getGuestOsRule() {
+ return guestOsRule;
+ }
+
public String getAllocationState() {
return allocationState;
}
@@ -147,7 +156,7 @@ public void execute() {
this.setResponseObject(hostResponse);
} catch (Exception e) {
Host host = _entityMgr.findById(Host.class, getId());
- logger.debug("Failed to update host: {} with id {}", host, getId(), e);
+ logger.error("Failed to update {}", host, e);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to update host: %s with id %d, %s", host, getId(), e.getMessage()));
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostPasswordCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostPasswordCmd.java
index c94fe2c58656..f96f01d3a877 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostPasswordCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostPasswordCmd.java
@@ -36,19 +36,19 @@ public class UpdateHostPasswordCmd extends BaseCmd {
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
- @Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, description = "the host ID")
+ @Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, description = "The host ID")
private Long hostId;
- @Parameter(name = ApiConstants.CLUSTER_ID, type = CommandType.UUID, entityType = ClusterResponse.class, description = "the cluster ID")
+ @Parameter(name = ApiConstants.CLUSTER_ID, type = CommandType.UUID, entityType = ClusterResponse.class, description = "The cluster ID")
private Long clusterId;
- @Parameter(name = ApiConstants.SHOULD_UPDATE_PASSWORD, type = CommandType.BOOLEAN, description = "if the password should also be updated on the hosts")
+ @Parameter(name = ApiConstants.SHOULD_UPDATE_PASSWORD, type = CommandType.BOOLEAN, description = "If the password should also be updated on the hosts")
private Boolean updatePasswdOnHost;
- @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "the username for the host/cluster")
+ @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "The username for the host/cluster")
private String username;
- @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "the new password for the host/cluster")
+ @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "The new password for the host/cluster")
private String password;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java
index c94d326ee622..51aa86546603 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java
@@ -50,7 +50,7 @@ public class ConfigureInternalLoadBalancerElementCmd extends BaseAsyncCmd {
type = CommandType.UUID,
entityType = InternalLoadBalancerElementResponse.class,
required = true,
- description = "the ID of the internal lb provider")
+ description = "The ID of the internal lb provider")
private Long id;
@Parameter(name = ApiConstants.ENABLED, type = CommandType.BOOLEAN, required = true, description = "Enables/Disables the Internal Load Balancer element")
@@ -84,12 +84,12 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "configuring internal load balancer element: " + id;
+ return "Configuring internal load balancer element with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
- CallContext.current().setEventDetails("Internal load balancer element: " + id);
+ CallContext.current().setEventDetails("Internal load balancer element: " + getResourceUuid(ApiConstants.ID));
InternalLoadBalancerElementService service = _networkService.getInternalLoadBalancerElementById(id);
VirtualRouterProvider result = service.configureInternalLoadBalancerElement(getId(), getEnabled());
if (result != null) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java
index 924287b673ba..aa9e5f1ba7f4 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java
@@ -48,7 +48,7 @@ public class CreateInternalLoadBalancerElementCmd extends BaseAsyncCreateCmd {
type = CommandType.UUID,
entityType = ProviderResponse.class,
required = true,
- description = "the network service provider ID of the internal load balancer element")
+ description = "The network service provider ID of the internal load balancer element")
private Long nspId;
/////////////////////////////////////////////////////
@@ -74,7 +74,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Virtual router element Id: " + getEntityId());
+ CallContext.current().setEventDetails("Virtual router element ID: " + getEntityUuid());
InternalLoadBalancerElementService service = _networkService.getInternalLoadBalancerElementByNetworkServiceProviderId(getNspId());
VirtualRouterProvider result = service.getInternalLoadBalancerElement(getEntityId());
if (result != null) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java
index 0eb00234382d..9ba23279c5df 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java
@@ -35,7 +35,7 @@
import com.cloud.network.router.VirtualRouter.Role;
import com.cloud.vm.VirtualMachine;
-@APICommand(name = "listInternalLoadBalancerVMs", description = "List internal LB VMs.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class},
+@APICommand(name = "listInternalLoadBalancerVMs", description = "List internal LB Instances.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListInternalLBVMsCmd extends BaseListProjectAndAccountResourcesCmd {
@@ -45,36 +45,36 @@ public class ListInternalLBVMsCmd extends BaseListProjectAndAccountResourcesCmd
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, description = "the host ID of the Internal LB VM")
+ @Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, description = "The host ID of the Internal LB Instance")
private Long hostId;
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = UserVmResponse.class, description = "the ID of the Internal LB VM")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = UserVmResponse.class, description = "The ID of the Internal LB Instance")
private Long id;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the Internal LB VM")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "The name of the Internal LB Instance")
private String routerName;
- @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, description = "the Pod ID of the Internal LB VM")
+ @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, description = "The Pod ID of the Internal LB Instance")
private Long podId;
- @Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "the state of the Internal LB VM")
+ @Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "The state of the Internal LB Instance")
private String state;
- @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the Zone ID of the Internal LB VM")
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "The Zone ID of the Internal LB Instance")
private Long zoneId;
- @Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "list by network id")
+ @Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "List by Network ID")
private Long networkId;
- @Parameter(name = ApiConstants.VPC_ID, type = CommandType.UUID, entityType = VpcResponse.class, description = "List Internal LB VMs by VPC")
+ @Parameter(name = ApiConstants.VPC_ID, type = CommandType.UUID, entityType = VpcResponse.class, description = "List Internal LB Instances by VPC")
private Long vpcId;
- @Parameter(name = ApiConstants.FOR_VPC, type = CommandType.BOOLEAN, description = "if true is passed for this parameter, list only VPC Internal LB VMs")
+ @Parameter(name = ApiConstants.FOR_VPC, type = CommandType.BOOLEAN, description = "If true is passed for this parameter, list only VPC Internal LB Instances")
private Boolean forVpc;
@Parameter(name = ApiConstants.FETCH_ROUTER_HEALTH_CHECK_RESULTS, type = CommandType.BOOLEAN, since = "4.14",
- description = "if true is passed for this parameter, also fetch last executed health check results for the VM. Default is false")
+ description = "If true is passed for this parameter, also fetch last executed health check results for the Instance. Default is false")
private Boolean fetchHealthCheckResults;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java
index b17cc22e7466..9cd7ba2656b5 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java
@@ -50,16 +50,16 @@ public class ListInternalLoadBalancerElementsCmd extends BaseListCmd {
@Parameter(name = ApiConstants.ID,
type = CommandType.UUID,
entityType = InternalLoadBalancerElementResponse.class,
- description = "list internal load balancer elements by id")
+ description = "List internal load balancer elements by ID")
private Long id;
@Parameter(name = ApiConstants.NSP_ID,
type = CommandType.UUID,
entityType = ProviderResponse.class,
- description = "list internal load balancer elements by network service provider id")
+ description = "List internal load balancer elements by network service provider ID")
private Long nspId;
- @Parameter(name = ApiConstants.ENABLED, type = CommandType.BOOLEAN, description = "list internal load balancer elements by enabled state")
+ @Parameter(name = ApiConstants.ENABLED, type = CommandType.BOOLEAN, description = "List internal load balancer elements by enabled state")
private Boolean enabled;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java
index 3dd7d2adf378..d9d4e46726fc 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java
@@ -38,7 +38,7 @@
import com.cloud.network.router.VirtualRouter.Role;
import com.cloud.vm.VirtualMachine;
-@APICommand(name = "startInternalLoadBalancerVM", responseObject = DomainRouterResponse.class, description = "Starts an existing internal lb vm.", entityType = {VirtualMachine.class},
+@APICommand(name = "startInternalLoadBalancerVM", responseObject = DomainRouterResponse.class, description = "Starts an existing Internal LB Instance.", entityType = {VirtualMachine.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class StartInternalLBVMCmd extends BaseAsyncCmd {
private static final String s_name = "startinternallbvmresponse";
@@ -47,7 +47,7 @@ public class StartInternalLBVMCmd extends BaseAsyncCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@ACL(accessType = AccessType.OperateEntry)
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "the ID of the internal lb vm")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "The ID of the Internal LB Instance")
private Long id;
/////////////////////////////////////////////////////
@@ -77,7 +77,7 @@ public long getEntityOwnerId() {
if (router != null && router.getRole() == Role.INTERNAL_LB_VM) {
return router.getAccountId();
} else {
- throw new InvalidParameterValueException("Unable to find internal lb vm by id");
+ throw new InvalidParameterValueException("Unable to find Internal LB Instance by ID");
}
}
@@ -88,7 +88,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "starting internal lb vm: " + getId();
+ return "Starting internal LB Instance with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
@@ -103,11 +103,11 @@ public Long getApiResourceId() {
@Override
public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
- CallContext.current().setEventDetails("Internal Lb Vm Id: " + getId());
+ CallContext.current().setEventDetails("Internal LB Instance ID: " + getResourceUuid(ApiConstants.ID));
VirtualRouter result = null;
VirtualRouter router = _routerService.findRouter(getId());
if (router == null || router.getRole() != Role.INTERNAL_LB_VM) {
- throw new InvalidParameterValueException("Can't find internal lb vm by id");
+ throw new InvalidParameterValueException("Can't find Internal LB Instance by ID");
} else {
result = _internalLbSvc.startInternalLbVm(getId(), CallContext.current().getCallingAccount(), CallContext.current().getCallingUserId());
}
@@ -117,7 +117,7 @@ public void execute() throws ConcurrentOperationException, ResourceUnavailableEx
routerResponse.setResponseName(getCommandName());
setResponseObject(routerResponse);
} else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to start internal lb vm");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to start Internal LB Instance");
}
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java
index a746e5d906d6..253c59e671e5 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java
@@ -37,7 +37,7 @@
import com.cloud.network.router.VirtualRouter.Role;
import com.cloud.vm.VirtualMachine;
-@APICommand(name = "stopInternalLoadBalancerVM", description = "Stops an Internal LB vm.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class},
+@APICommand(name = "stopInternalLoadBalancerVM", description = "Stops an Internal LB Instance.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class StopInternalLBVMCmd extends BaseAsyncCmd {
private static final String s_name = "stopinternallbvmresponse";
@@ -46,10 +46,10 @@ public class StopInternalLBVMCmd extends BaseAsyncCmd {
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
@ACL(accessType = AccessType.OperateEntry)
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "the ID of the internal lb vm")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "The ID of the internal LB Instance")
private Long id;
- @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force stop the VM (vm is marked as Stopped even when command fails to be send to the backend, otherwise a force poweroff is attempted). To be used if the caller knows the VM is stopped and should be marked as such.")
+ @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force stop the Instance (Instance is marked as Stopped even when command fails to be send to the backend, otherwise a force poweroff is attempted). To be used if the caller knows the Instance is stopped and should be marked as such.")
private Boolean forced;
// ///////////////////////////////////////////////////
@@ -75,7 +75,7 @@ public long getEntityOwnerId() {
if (vm != null && vm.getRole() == Role.INTERNAL_LB_VM) {
return vm.getAccountId();
} else {
- throw new InvalidParameterValueException("Unable to find internal lb vm by id");
+ throw new InvalidParameterValueException("Unable to find Internal LB Instance by ID");
}
}
@@ -86,7 +86,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "stopping internal lb vm: " + getId();
+ return "Stopping Internal LB Instance: " + getResourceUuid(ApiConstants.ID);
}
@Override
@@ -105,11 +105,11 @@ public boolean isForced() {
@Override
public void execute() throws ConcurrentOperationException, ResourceUnavailableException {
- CallContext.current().setEventDetails("Internal lb vm Id: " + getId());
+ CallContext.current().setEventDetails("Internal LB Instance ID: " + getResourceUuid(ApiConstants.ID));
VirtualRouter result = null;
VirtualRouter vm = _routerService.findRouter(getId());
if (vm == null || vm.getRole() != Role.INTERNAL_LB_VM) {
- throw new InvalidParameterValueException("Can't find internal lb vm by id");
+ throw new InvalidParameterValueException("Can't find Internal LB Instance by ID");
} else {
result = _internalLbSvc.stopInternalLbVm(getId(), isForced(), CallContext.current().getCallingAccount(), CallContext.current().getCallingUserId());
}
@@ -119,7 +119,7 @@ public void execute() throws ConcurrentOperationException, ResourceUnavailableEx
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to stop internal lb vm");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to stop Internal LB Instance");
}
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/AttachIsoCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/AttachIsoCmdByAdmin.java
index e39107b2593c..d253580f0983 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/AttachIsoCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/AttachIsoCmdByAdmin.java
@@ -22,6 +22,6 @@
import org.apache.cloudstack.api.command.user.iso.AttachIsoCmd;
import org.apache.cloudstack.api.response.UserVmResponse;
-@APICommand(name = "attachIso", description = "Attaches an ISO to a virtual machine.", responseObject = UserVmResponse.class, responseView = ResponseView.Full,
+@APICommand(name = "attachIso", description = "Attaches an ISO to an Instance.", responseObject = UserVmResponse.class, responseView = ResponseView.Full,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
public class AttachIsoCmdByAdmin extends AttachIsoCmd implements AdminCmd { }
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/CopyIsoCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/CopyIsoCmdByAdmin.java
index f27c0c5c234a..f64326638a33 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/CopyIsoCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/CopyIsoCmdByAdmin.java
@@ -21,7 +21,7 @@
import org.apache.cloudstack.api.command.user.iso.CopyIsoCmd;
import org.apache.cloudstack.api.response.TemplateResponse;
-@APICommand(name = "copyIso", description = "Copies an iso from one zone to another.", responseObject = TemplateResponse.class, responseView = ResponseView.Full,
+@APICommand(name = "copyIso", description = "Copies an ISO from one zone to another.", responseObject = TemplateResponse.class, responseView = ResponseView.Full,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class CopyIsoCmdByAdmin extends CopyIsoCmd {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/DetachIsoCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/DetachIsoCmdByAdmin.java
index 5eeba2bfa301..553d0ae13c69 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/DetachIsoCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/DetachIsoCmdByAdmin.java
@@ -22,6 +22,6 @@
import org.apache.cloudstack.api.command.user.iso.DetachIsoCmd;
import org.apache.cloudstack.api.response.UserVmResponse;
-@APICommand(name = "detachIso", description = "Detaches any ISO file (if any) currently attached to a virtual machine.", responseObject = UserVmResponse.class, responseView = ResponseView.Full,
+@APICommand(name = "detachIso", description = "Detaches any ISO file (if any) currently attached to an Instance.", responseObject = UserVmResponse.class, responseView = ResponseView.Full,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
public class DetachIsoCmdByAdmin extends DetachIsoCmd implements AdminCmd {}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/ListIsoPermissionsCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/ListIsoPermissionsCmdByAdmin.java
index 46bd4f3766e7..b831a99cb0af 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/ListIsoPermissionsCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/ListIsoPermissionsCmdByAdmin.java
@@ -1,4 +1,4 @@
-// Licensedname = "listIsoPermissions", to the Apache Software Foundation (ASF) under one
+// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
@@ -23,7 +23,7 @@
import org.apache.cloudstack.api.response.TemplatePermissionsResponse;
@APICommand(name = "listIsoPermissions",
- description = "List iso visibility and all accounts that have permissions to view this iso.",
+ description = "List ISO visibility and all accounts that have permissions to view this ISO.",
responseObject = TemplatePermissionsResponse.class,
responseView = ResponseView.Full,
requestHasSensitiveInfo = false,
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/loadbalancer/ListLoadBalancerRuleInstancesCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/loadbalancer/ListLoadBalancerRuleInstancesCmdByAdmin.java
index b11988b241fb..a37e058924f6 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/loadbalancer/ListLoadBalancerRuleInstancesCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/loadbalancer/ListLoadBalancerRuleInstancesCmdByAdmin.java
@@ -23,7 +23,7 @@
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRuleInstancesCmd;
-@APICommand(name = "listLoadBalancerRuleInstances", description = "List all virtual machine instances that are assigned to a load balancer rule.", responseObject = LoadBalancerRuleVmMapResponse.class, responseView = ResponseView.Full,
+@APICommand(name = "listLoadBalancerRuleInstances", description = "List all Instances that are assigned to a load balancer rule.", responseObject = LoadBalancerRuleVmMapResponse.class, responseView = ResponseView.Full,
requestHasSensitiveInfo = false,
responseHasSensitiveInfo = true)
public class ListLoadBalancerRuleInstancesCmdByAdmin extends ListLoadBalancerRuleInstancesCmd implements AdminCmd {}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/management/ListMgmtsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/management/ListMgmtsCmd.java
index 7b7eae1d0e93..293cb34e7028 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/management/ListMgmtsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/management/ListMgmtsCmd.java
@@ -34,10 +34,10 @@ public class ListMgmtsCmd extends BaseListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ManagementServerResponse.class, description = "the id of the management server")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ManagementServerResponse.class, description = "The ID of the management server")
private Long id;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the management server")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "The name of the management server")
private String hostName;
@Parameter(name = ApiConstants.PEERS, type = CommandType.BOOLEAN,
@@ -45,6 +45,10 @@ public class ListMgmtsCmd extends BaseListCmd {
since = "4.20.1.0")
private Boolean peers;
+ @Parameter(name = ApiConstants.VERSION, type = CommandType.STRING,
+ description = "the version of the management server", since = "4.20.3")
+ private String version;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -61,6 +65,10 @@ public Boolean getPeers() {
return BooleanUtils.toBooleanDefaultIfNull(peers, false);
}
+ public String getVersion() {
+ return version;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkDeviceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkDeviceCmd.java
index 334772970431..e90a56a92abb 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkDeviceCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkDeviceCmd.java
@@ -55,7 +55,7 @@ public class AddNetworkDeviceCmd extends BaseCmd {
description = "Network device type, now supports ExternalDhcp, PxeServer, NetscalerMPXLoadBalancer, NetscalerVPXLoadBalancer, NetscalerSDXLoadBalancer, F5BigIpLoadBalancer, JuniperSRXFirewall, PaloAltoFirewall")
private String type;
- @Parameter(name = ApiConstants.NETWORK_DEVICE_PARAMETER_LIST, type = CommandType.MAP, description = "parameters for network device")
+ @Parameter(name = ApiConstants.NETWORK_DEVICE_PARAMETER_LIST, type = CommandType.MAP, description = "Parameters for network device")
private Map paramList;
public String getDeviceType() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java
index 40a822393452..3e42a0103d8b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java
@@ -52,22 +52,22 @@ public class AddNetworkServiceProviderCmd extends BaseAsyncCreateCmd {
type = CommandType.UUID,
entityType = PhysicalNetworkResponse.class,
required = true,
- description = "the Physical Network ID to add the provider to")
+ description = "The Physical Network ID to add the provider to")
private Long physicalNetworkId;
@Parameter(name = ApiConstants.DEST_PHYSICAL_NETWORK_ID,
type = CommandType.UUID,
entityType = PhysicalNetworkResponse.class,
- description = "the destination Physical Network ID to bridge to")
+ description = "The destination Physical Network ID to bridge to")
private Long destinationPhysicalNetworkId;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name for the physical network service provider")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "The name for the physical network service provider")
private String name;
@Parameter(name = ApiConstants.SERVICE_LIST,
type = CommandType.LIST,
collectionType = CommandType.STRING,
- description = "the list of services to be enabled for this physical network service provider")
+ description = "The list of services to be enabled for this physical network service provider")
private List enabledServices;
/////////////////////////////////////////////////////
@@ -101,7 +101,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Network ServiceProvider Id: " + getEntityId());
+ CallContext.current().setEventDetails("Network ServiceProvider ID: " + getEntityUuid());
PhysicalNetworkServiceProvider result = _networkService.getCreatedPhysicalNetworkServiceProvider(getEntityId());
if (result != null) {
ProviderResponse response = _responseGenerator.createNetworkServiceProviderResponse(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CloneNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CloneNetworkOfferingCmd.java
new file mode 100644
index 000000000000..19760ffaaa10
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CloneNetworkOfferingCmd.java
@@ -0,0 +1,113 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.network;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.NetworkOfferingResponse;
+
+import com.cloud.offering.NetworkOffering;
+
+@APICommand(name = "cloneNetworkOffering",
+ description = "Clones a network offering. All parameters are copied from the source offering unless explicitly overridden. " +
+ "Use 'addServices' and 'dropServices' to modify the service list without respecifying everything.",
+ responseObject = NetworkOfferingResponse.class,
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ since = "4.23.0")
+public class CloneNetworkOfferingCmd extends NetworkOfferingBaseCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.SOURCE_OFFERING_ID,
+ type = BaseCmd.CommandType.UUID,
+ entityType = NetworkOfferingResponse.class,
+ required = true,
+ description = "The ID of the source network offering to clone from")
+ private Long sourceOfferingId;
+
+ @Parameter(name = "addservices",
+ type = CommandType.LIST,
+ collectionType = CommandType.STRING,
+ description = "Services to add to the cloned offering (in addition to source offering services). " +
+ "If specified along with 'supportedservices', this parameter is ignored.")
+ private List addServices;
+
+ @Parameter(name = "dropservices",
+ type = CommandType.LIST,
+ collectionType = CommandType.STRING,
+ description = "Services to remove from the cloned offering (that exist in source offering). " +
+ "If specified along with 'supportedservices', this parameter is ignored.")
+ private List dropServices;
+
+ @Parameter(name = ApiConstants.TRAFFIC_TYPE,
+ type = CommandType.STRING,
+ description = "The traffic type for the network offering. Supported type in current release is GUEST only")
+ private String traffictype;
+
+ @Parameter(name = ApiConstants.GUEST_IP_TYPE, type = CommandType.STRING, description = "Guest type of the network offering: Shared or Isolated")
+ private String guestIptype;
+
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getSourceOfferingId() {
+ return sourceOfferingId;
+ }
+
+ public List getAddServices() {
+ return addServices;
+ }
+
+ public List getDropServices() {
+ return dropServices;
+ }
+
+ public String getGuestIpType() {
+ return guestIptype;
+ }
+
+ public String getTraffictype() {
+ return traffictype;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public void execute() {
+ NetworkOffering result = _configService.cloneNetworkOffering(this);
+ if (result != null) {
+ NetworkOfferingResponse response = _responseGenerator.createNetworkOfferingResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to clone network offering");
+ }
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateGuestNetworkIpv6PrefixCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateGuestNetworkIpv6PrefixCmd.java
index f6b035c57837..614dcf9d0751 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateGuestNetworkIpv6PrefixCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateGuestNetworkIpv6PrefixCmd.java
@@ -83,7 +83,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Creating guest IPv6 prefix " + getPrefix() + " for zone=" + getZoneId();
+ return "Creating guest IPv6 prefix " + getPrefix() + " for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmd.java
index a482cb1d4f27..4d645376a909 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmd.java
@@ -85,7 +85,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Creating guest IPv4 subnet " + getSubnet() + " in zone subnet=" + getParentId();
+ return "Creating guest IPv4 subnet " + getSubnet() + " in zone subnet: " + getResourceUuid(ApiConstants.PARENT_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmd.java
index 5f48cf9c6327..48a6002fb5c0 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmd.java
@@ -102,7 +102,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Creating guest IPv4 subnet " + getSubnet() + " for zone=" + getZoneId();
+ return "Creating guest IPv4 subnet " + getSubnet() + " for zone: " + getResourceUuid(ApiConstants.ZONE_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java
index 85cfddfb714f..2780c4eaf050 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java
@@ -34,6 +34,7 @@
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
+import com.cloud.utils.StringUtils;
@APICommand(name = "createManagementNetworkIpRange",
description = "Creates a Management network IP range.",
@@ -118,7 +119,7 @@ public Boolean isForSystemVms() {
}
public String getVlan() {
- if (vlan == null || vlan.isEmpty()) {
+ if (StringUtils.isBlank(vlan)) {
vlan = "untagged";
}
return vlan;
@@ -131,7 +132,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Creating management ip range from " + getStartIp() + " to " + getEndIp() + " and gateway=" + getGateWay() + ", netmask=" + getNetmask() + " of pod=" + getPodId();
+ return "Creating management IP range from " + getStartIp() + " to " + getEndIp() + ", with gateway: " + getGateWay() + ", netmask:" + getNetmask() + " on pod:" + getPodId();
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java
index d8b57f79528c..57d1d4fad116 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java
@@ -31,24 +31,24 @@
import java.util.List;
-@APICommand(name = "createNetwork", description = "Creates a network", responseObject = NetworkResponse.class, responseView = ResponseView.Full, entityType = {Network.class},
+@APICommand(name = "createNetwork", description = "Creates a Network", responseObject = NetworkResponse.class, responseView = ResponseView.Full, entityType = {Network.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class CreateNetworkCmdByAdmin extends CreateNetworkCmd implements AdminCmd {
- @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network")
+ @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description = "The ID or VID of the network")
private String vlan;
- @Parameter(name=ApiConstants.BYPASS_VLAN_OVERLAP_CHECK, type=CommandType.BOOLEAN, description="when true bypasses VLAN id/range overlap check during network creation for shared and L2 networks")
+ @Parameter(name=ApiConstants.BYPASS_VLAN_OVERLAP_CHECK, type=CommandType.BOOLEAN, description = "When true bypasses VLAN ID/range overlap check during Network creation for shared and L2 Networks")
private Boolean bypassVlanOverlapCheck;
- @Parameter(name=ApiConstants.HIDE_IP_ADDRESS_USAGE, type=CommandType.BOOLEAN, description="when true ip address usage for the network will not be exported by the listUsageRecords API")
+ @Parameter(name=ApiConstants.HIDE_IP_ADDRESS_USAGE, type=CommandType.BOOLEAN, description = "When true IP address usage for the Network will not be exported by the listUsageRecords API")
private Boolean hideIpAddressUsage;
- @Parameter(name = ApiConstants.ROUTER_IP, type = CommandType.STRING, description = "IPV4 address to be assigned to a router in a shared network", since = "4.16",
+ @Parameter(name = ApiConstants.ROUTER_IP, type = CommandType.STRING, description = "IPv4 address to be assigned to a router in a shared Network", since = "4.16",
validations = {ApiArgValidator.NotNullOrEmpty})
private String routerIp;
- @Parameter(name = ApiConstants.ROUTER_IPV6, type = CommandType.STRING, description = "IPV6 address to be assigned to a router in a shared network", since = "4.16",
+ @Parameter(name = ApiConstants.ROUTER_IPV6, type = CommandType.STRING, description = "IPv6 address to be assigned to a router in a shared Network", since = "4.16",
validations = {ApiArgValidator.NotNullOrEmpty})
private String routerIpv6;
@@ -56,7 +56,7 @@ public class CreateNetworkCmdByAdmin extends CreateNetworkCmd implements AdminCm
type = CommandType.LIST,
collectionType = CommandType.UUID,
entityType = BgpPeerResponse.class,
- description = "Ids of the Bgp Peer for the network",
+ description = "IDs of the Bgp Peer for the Network",
since = "4.20.0")
private List bgpPeerIds;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
index 56333f4081b0..5c39060f9fa3 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
@@ -16,505 +16,47 @@
// under the License.
package org.apache.cloudstack.api.command.admin.network;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import com.cloud.network.Network;
-import com.cloud.network.VirtualRouterProvider;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.BooleanUtils;
-import org.apache.commons.lang3.StringUtils;
-
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.Service;
import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.NetworkOffering.Availability;
-import com.cloud.user.Account;
-
-import static com.cloud.network.Network.Service.Dhcp;
-import static com.cloud.network.Network.Service.Dns;
-import static com.cloud.network.Network.Service.Lb;
-import static com.cloud.network.Network.Service.StaticNat;
-import static com.cloud.network.Network.Service.SourceNat;
-import static com.cloud.network.Network.Service.PortForwarding;
-import static com.cloud.network.Network.Service.NetworkACL;
-import static com.cloud.network.Network.Service.UserData;
-import static com.cloud.network.Network.Service.Firewall;
-
-import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNetrisNatted;
-import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNetrisRouted;
-import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNsxWithoutLb;
@APICommand(name = "createNetworkOffering", description = "Creates a network offering.", responseObject = NetworkOfferingResponse.class, since = "3.0.0",
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateNetworkOfferingCmd extends BaseCmd {
+public class CreateNetworkOfferingCmd extends NetworkOfferingBaseCmd {
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the network offering")
- private String networkOfferingName;
-
- @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "the display text of the network offering, defaults to the value of 'name'.")
- private String displayText;
-
@Parameter(name = ApiConstants.TRAFFIC_TYPE,
type = CommandType.STRING,
required = true,
- description = "the traffic type for the network offering. Supported type in current release is GUEST only")
+ description = "The traffic type for the network offering. Supported type in current release is GUEST only")
private String traffictype;
- @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "the tags for the network offering.", length = 4096)
- private String tags;
-
- @Parameter(name = ApiConstants.SPECIFY_VLAN, type = CommandType.BOOLEAN, description = "true if network offering supports vlans")
- private Boolean specifyVlan;
-
- @Parameter(name = ApiConstants.AVAILABILITY, type = CommandType.STRING, description = "the availability of network offering. The default value is Optional. "
- + " Another value is Required, which will make it as the default network offering for new networks ")
- private String availability;
-
- @Parameter(name = ApiConstants.NETWORKRATE, type = CommandType.INTEGER, description = "data transfer rate in megabits per second allowed")
- private Integer networkRate;
-
- @Parameter(name = ApiConstants.CONSERVE_MODE, type = CommandType.BOOLEAN, description = "true if the network offering is IP conserve mode enabled")
- private Boolean conserveMode;
-
- @Parameter(name = ApiConstants.SERVICE_OFFERING_ID,
- type = CommandType.UUID,
- entityType = ServiceOfferingResponse.class,
- description = "the service offering ID used by virtual router provider")
- private Long serviceOfferingId;
-
- @Parameter(name = ApiConstants.GUEST_IP_TYPE, type = CommandType.STRING, required = true, description = "guest type of the network offering: Shared or Isolated")
+ @Parameter(name = ApiConstants.GUEST_IP_TYPE, type = CommandType.STRING, required = true, description = "Guest type of the network offering: Shared or Isolated")
private String guestIptype;
- @Parameter(name = ApiConstants.INTERNET_PROTOCOL,
- type = CommandType.STRING,
- description = "The internet protocol of network offering. Options are ipv4 and dualstack. Default is ipv4. dualstack will create a network offering that supports both IPv4 and IPv6",
- since = "4.17.0")
- private String internetProtocol;
-
- @Parameter(name = ApiConstants.SUPPORTED_SERVICES,
- type = CommandType.LIST,
- collectionType = CommandType.STRING,
- description = "services supported by the network offering")
- private List supportedServices;
-
- @Parameter(name = ApiConstants.SERVICE_PROVIDER_LIST,
- type = CommandType.MAP,
- description = "provider to service mapping. If not specified, the provider for the service will be mapped to the default provider on the physical network")
- private Map serviceProviderList;
-
- @Parameter(name = ApiConstants.SERVICE_CAPABILITY_LIST, type = CommandType.MAP, description = "desired service capabilities as part of network offering")
- private Map serviceCapabilitystList;
-
- @Parameter(name = ApiConstants.SPECIFY_IP_RANGES,
- type = CommandType.BOOLEAN,
- description = "true if network offering supports specifying ip ranges; defaulted to false if not specified")
- private Boolean specifyIpRanges;
-
- @Parameter(name = ApiConstants.IS_PERSISTENT,
- type = CommandType.BOOLEAN,
- description = "true if network offering supports persistent networks; defaulted to false if not specified")
- private Boolean isPersistent;
-
- @Parameter(name = ApiConstants.FOR_VPC,
- type = CommandType.BOOLEAN,
- description = "true if network offering is meant to be used for VPC, false otherwise.")
- private Boolean forVpc;
-
- @Deprecated
- @Parameter(name = ApiConstants.FOR_NSX,
- type = CommandType.BOOLEAN,
- description = "true if network offering is meant to be used for NSX, false otherwise.",
- since = "4.20.0")
- private Boolean forNsx;
-
- @Parameter(name = ApiConstants.PROVIDER,
- type = CommandType.STRING,
- description = "Name of the provider providing the service",
- since = "4.21.0")
- private String provider;
-
- @Parameter(name = ApiConstants.NSX_SUPPORT_LB,
- type = CommandType.BOOLEAN,
- description = "true if network offering for NSX network offering supports Load balancer service.",
- since = "4.20.0")
- private Boolean nsxSupportsLbService;
-
- @Parameter(name = ApiConstants.NSX_SUPPORTS_INTERNAL_LB,
- type = CommandType.BOOLEAN,
- description = "true if network offering for NSX network offering supports Internal Load balancer service.",
- since = "4.20.0")
- private Boolean nsxSupportsInternalLbService;
-
- @Parameter(name = ApiConstants.NETWORK_MODE,
- type = CommandType.STRING,
- description = "Indicates the mode with which the network will operate. Valid option: NATTED or ROUTED",
- since = "4.20.0")
- private String networkMode;
-
- @Parameter(name = ApiConstants.FOR_TUNGSTEN,
- type = CommandType.BOOLEAN,
- description = "true if network offering is meant to be used for Tungsten-Fabric, false otherwise.")
- private Boolean forTungsten;
-
- @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, since = "4.2.0", description = "Network offering details in key/value pairs."
- + " Supported keys are internallbprovider/publiclbprovider with service provider as a value, and"
- + " promiscuousmode/macaddresschanges/forgedtransmits with true/false as value to accept/reject the security settings if available for a nic/portgroup")
- protected Map details;
-
- @Parameter(name = ApiConstants.EGRESS_DEFAULT_POLICY,
- type = CommandType.BOOLEAN,
- description = "true if guest network default egress policy is allow; false if default egress policy is deny")
- private Boolean egressDefaultPolicy;
-
- @Parameter(name = ApiConstants.KEEPALIVE_ENABLED,
- type = CommandType.BOOLEAN,
- required = false,
- description = "if true keepalive will be turned on in the loadbalancer. At the time of writing this has only an effect on haproxy; the mode http and httpclose options are unset in the haproxy conf file.")
- private Boolean keepAliveEnabled;
-
- @Parameter(name = ApiConstants.MAX_CONNECTIONS,
- type = CommandType.INTEGER,
- description = "maximum number of concurrent connections supported by the network offering")
- private Integer maxConnections;
-
- @Parameter(name = ApiConstants.DOMAIN_ID,
- type = CommandType.LIST,
- collectionType = CommandType.UUID,
- entityType = DomainResponse.class,
- description = "the ID of the containing domain(s), null for public offerings")
- private List domainIds;
-
- @Parameter(name = ApiConstants.ZONE_ID,
- type = CommandType.LIST,
- collectionType = CommandType.UUID,
- entityType = ZoneResponse.class,
- description = "the ID of the containing zone(s), null for public offerings",
- since = "4.13")
- private List zoneIds;
-
- @Parameter(name = ApiConstants.ENABLE,
- type = CommandType.BOOLEAN,
- description = "set to true if the offering is to be enabled during creation. Default is false",
- since = "4.16")
- private Boolean enable;
-
- @Parameter(name = ApiConstants.SPECIFY_AS_NUMBER, type = CommandType.BOOLEAN, since = "4.20.0",
- description = "true if network offering supports choosing AS number")
- private Boolean specifyAsNumber;
-
- @Parameter(name = ApiConstants.ROUTING_MODE,
- type = CommandType.STRING,
- since = "4.20.0",
- description = "the routing mode for the network offering. Supported types are: Static or Dynamic.")
- private String routingMode;
-
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
- public String getNetworkOfferingName() {
- return networkOfferingName;
- }
-
- public String getDisplayText() {
- return StringUtils.isEmpty(displayText) ? networkOfferingName : displayText;
- }
-
- public String getTags() {
- return tags;
- }
-
public String getTraffictype() {
return traffictype;
}
- public Boolean getSpecifyVlan() {
- return specifyVlan == null ? false : specifyVlan;
- }
-
- public String getAvailability() {
- return availability == null ? Availability.Optional.toString() : availability;
- }
-
- public Integer getNetworkRate() {
- return networkRate;
- }
-
- public Long getServiceOfferingId() {
- return serviceOfferingId;
- }
-
- public boolean isExternalNetworkProvider() {
- return Arrays.asList("NSX", "Netris").stream()
- .anyMatch(s -> provider != null && s.equalsIgnoreCase(provider));
- }
-
- public boolean isForNsx() {
- return provider != null && provider.equalsIgnoreCase("NSX");
- }
-
- public boolean isForNetris() {
- return provider != null && provider.equalsIgnoreCase("Netris");
- }
-
- public String getProvider() {
- return provider;
- }
-
- public List getSupportedServices() {
- if (!isExternalNetworkProvider()) {
- return supportedServices == null ? new ArrayList() : supportedServices;
- } else {
- List services = new ArrayList<>(List.of(
- Dhcp.getName(),
- Dns.getName(),
- UserData.getName()
- ));
- if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode())) {
- services.addAll(Arrays.asList(
- StaticNat.getName(),
- SourceNat.getName(),
- PortForwarding.getName()));
- }
- if (getNsxSupportsLbService() || (provider != null && isNetrisNatted(getProvider(), getNetworkMode()))) {
- services.add(Lb.getName());
- }
- if (Boolean.TRUE.equals(forVpc)) {
- services.add(NetworkACL.getName());
- } else {
- services.add(Firewall.getName());
- }
- return services;
- }
- }
-
public String getGuestIpType() {
return guestIptype;
}
- public String getInternetProtocol() {
- return internetProtocol;
- }
-
- public Boolean getSpecifyIpRanges() {
- return specifyIpRanges == null ? false : specifyIpRanges;
- }
-
- public Boolean getConserveMode() {
- if (conserveMode == null) {
- return true;
- }
- return conserveMode;
- }
-
- public Boolean getIsPersistent() {
- return isPersistent == null ? false : isPersistent;
- }
-
- public Boolean getForVpc() {
- return forVpc;
- }
-
- public String getNetworkMode() {
- return networkMode;
- }
-
- public boolean getNsxSupportsLbService() {
- return BooleanUtils.isTrue(nsxSupportsLbService);
- }
-
- public boolean getNsxSupportsInternalLbService() {
- return BooleanUtils.isTrue(nsxSupportsInternalLbService);
- }
-
- public Boolean getForTungsten() {
- return forTungsten;
- }
-
- public Boolean getEgressDefaultPolicy() {
- if (egressDefaultPolicy == null) {
- return true;
- }
- return egressDefaultPolicy;
- }
-
- public Boolean getKeepAliveEnabled() {
- return keepAliveEnabled;
- }
-
- public Integer getMaxconnections() {
- return maxConnections;
- }
-
- public Map> getServiceProviders() {
- Map> serviceProviderMap = new HashMap<>();
- if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isExternalNetworkProvider()) {
- Collection servicesCollection = serviceProviderList.values();
- Iterator iter = servicesCollection.iterator();
- while (iter.hasNext()) {
- HashMap services = (HashMap) iter.next();
- String service = services.get("service");
- String provider = services.get("provider");
- List providerList = null;
- if (serviceProviderMap.containsKey(service)) {
- providerList = serviceProviderMap.get(service);
- } else {
- providerList = new ArrayList();
- }
- providerList.add(provider);
- serviceProviderMap.put(service, providerList);
- }
- } else if (isExternalNetworkProvider()) {
- getServiceProviderMapForExternalProvider(serviceProviderMap, Network.Provider.getProvider(provider).getName());
- }
- return serviceProviderMap;
- }
-
- private void getServiceProviderMapForExternalProvider(Map> serviceProviderMap, String provider) {
- String routerProvider = Boolean.TRUE.equals(getForVpc()) ? VirtualRouterProvider.Type.VPCVirtualRouter.name() :
- VirtualRouterProvider.Type.VirtualRouter.name();
- List unsupportedServices = new ArrayList<>(List.of("Vpn", "Gateway", "SecurityGroup", "Connectivity", "BaremetalPxeService"));
- List routerSupported = List.of("Dhcp", "Dns", "UserData");
- List allServices = Service.listAllServices().stream().map(Service::getName).collect(Collectors.toList());
- if (routerProvider.equals(VirtualRouterProvider.Type.VPCVirtualRouter.name())) {
- unsupportedServices.add("Firewall");
- } else {
- unsupportedServices.add("NetworkACL");
- }
- for (String service : allServices) {
- if (unsupportedServices.contains(service))
- continue;
- if (routerSupported.contains(service))
- serviceProviderMap.put(service, List.of(routerProvider));
- else if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode()) || NetworkACL.getName().equalsIgnoreCase(service)) {
- serviceProviderMap.put(service, List.of(provider));
- }
- if (isNsxWithoutLb(getProvider(), getNsxSupportsLbService()) || isNetrisRouted(getProvider(), getNetworkMode())) {
- serviceProviderMap.remove(Lb.getName());
- }
- }
- }
-
- public Map getServiceCapabilities(Service service) {
- Map capabilityMap = null;
-
- if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
- capabilityMap = new HashMap();
- Collection serviceCapabilityCollection = serviceCapabilitystList.values();
- Iterator iter = serviceCapabilityCollection.iterator();
- while (iter.hasNext()) {
- HashMap svcCapabilityMap = (HashMap) iter.next();
- Capability capability = null;
- String svc = svcCapabilityMap.get("service");
- String capabilityName = svcCapabilityMap.get("capabilitytype");
- String capabilityValue = svcCapabilityMap.get("capabilityvalue");
-
- if (capabilityName != null) {
- capability = Capability.getCapability(capabilityName);
- }
-
- if ((capability == null) || (capabilityName == null) || (capabilityValue == null)) {
- throw new InvalidParameterValueException("Invalid capability:" + capabilityName + " capability value:" + capabilityValue);
- }
-
- if (svc.equalsIgnoreCase(service.getName())) {
- capabilityMap.put(capability, capabilityValue);
- } else {
- //throw new InvalidParameterValueException("Service is not equal ")
- }
- }
- }
-
- return capabilityMap;
- }
-
- public Map getDetails() {
- if (details == null || details.isEmpty()) {
- return null;
- }
-
- Collection paramsCollection = details.values();
- Object objlist[] = paramsCollection.toArray();
- Map params = (Map) (objlist[0]);
- for (int i = 1; i < objlist.length; i++) {
- params.putAll((Map) (objlist[i]));
- }
-
- return params;
- }
-
- public String getServicePackageId() {
- Map data = getDetails();
- if (data == null)
- return null;
- return data.get(NetworkOffering.Detail.servicepackageuuid + "");
- }
-
- public List getDomainIds() {
- if (CollectionUtils.isNotEmpty(domainIds)) {
- Set set = new LinkedHashSet<>(domainIds);
- domainIds.clear();
- domainIds.addAll(set);
- }
- return domainIds;
- }
-
- public List getZoneIds() {
- if (CollectionUtils.isNotEmpty(zoneIds)) {
- Set set = new LinkedHashSet<>(zoneIds);
- zoneIds.clear();
- zoneIds.addAll(set);
- }
- return zoneIds;
- }
-
- public Boolean getEnable() {
- if (enable != null) {
- return enable;
- }
- return false;
- }
-
- public boolean getSpecifyAsNumber() {
- return BooleanUtils.toBoolean(specifyAsNumber);
- }
-
- public String getRoutingMode() {
- return routingMode;
- }
-
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
- @Override
- public long getEntityOwnerId() {
- return Account.ACCOUNT_ID_SYSTEM;
- }
@Override
public void execute() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java
index 7eb52b92456c..097b8a5b5458 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java
@@ -36,7 +36,7 @@
import com.cloud.network.PhysicalNetwork;
import com.cloud.user.Account;
-@APICommand(name = "createPhysicalNetwork", description = "Creates a physical network", responseObject = PhysicalNetworkResponse.class, since = "3.0.0",
+@APICommand(name = "createPhysicalNetwork", description = "Creates a physical Network", responseObject = PhysicalNetworkResponse.class, since = "3.0.0",
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class CreatePhysicalNetworkCmd extends BaseAsyncCreateCmd {
@@ -49,36 +49,36 @@ public class CreatePhysicalNetworkCmd extends BaseAsyncCreateCmd {
type = CommandType.UUID,
entityType = ZoneResponse.class,
required = true,
- description = "the Zone ID for the physical network")
+ description = "The Zone ID for the physical Network")
private Long zoneId;
- @Parameter(name = ApiConstants.VLAN, type = CommandType.STRING, description = "the VLAN for the physical network")
+ @Parameter(name = ApiConstants.VLAN, type = CommandType.STRING, description = "The VLAN for the physical Network")
private String vlan;
- @Parameter(name = ApiConstants.NETWORK_SPEED, type = CommandType.STRING, description = "the speed for the physical network[1G/10G]")
+ @Parameter(name = ApiConstants.NETWORK_SPEED, type = CommandType.STRING, description = "The speed for the physical Network[1G/10G]")
private String speed;
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.UUID,
entityType = DomainResponse.class,
- description = "domain ID of the account owning a physical network")
+ description = "Domain ID of the Account owning a physical Network")
private Long domainId;
@Parameter(name = ApiConstants.BROADCAST_DOMAIN_RANGE,
type = CommandType.STRING,
- description = "the broadcast domain range for the physical network[Pod or Zone]. In Acton release it can be Zone only in Advance zone, and Pod in Basic")
+ description = "The broadcast domain range for the physical Network[Pod or Zone]. In Acton release it can be Zone only in Advance zone, and Pod in Basic")
private String broadcastDomainRange;
- @Parameter(name = ApiConstants.TAGS, type = CommandType.LIST, collectionType = CommandType.STRING, description = "Tag the physical network")
+ @Parameter(name = ApiConstants.TAGS, type = CommandType.LIST, collectionType = CommandType.STRING, description = "Tag the physical Network")
private List tags;
@Parameter(name = ApiConstants.ISOLATION_METHODS,
type = CommandType.LIST,
collectionType = CommandType.STRING,
- description = "the isolation method for the physical network[VLAN/L3/GRE]")
+ description = "The isolation method for the physical Network[VLAN/VXLAN/GRE/STT/BCF_SEGMENT/SSP/ODL/L3VPN/VCS/NSX/NETRIS]")
private List isolationMethods;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the physical network")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "The name of the physical Network")
private String networkName;
/////////////////////////////////////////////////////
@@ -139,7 +139,7 @@ public String getCreateEventDescription() {
@Override
public String getEventDescription() {
- return "creating Physical Network. Id: " + getEntityId();
+ return "Creating Physical Network. ID: " + getEntityId();
}
/////////////////////////////////////////////////////
@@ -148,14 +148,14 @@ public String getEventDescription() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Physical Network Id: " + getEntityId());
+ CallContext.current().setEventDetails("Physical Network ID: " + getEntityUuid());
PhysicalNetwork result = _networkService.getCreatedPhysicalNetwork(getEntityId());
if (result != null) {
PhysicalNetworkResponse response = _responseGenerator.createPhysicalNetworkResponse(result);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create physical network");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create physical Network");
}
}
@@ -168,7 +168,7 @@ public void create() throws ResourceAllocationException {
setEntityId(result.getId());
setEntityUuid(result.getUuid());
} else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create physical network entity");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create physical Network entity");
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateStorageNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateStorageNetworkIpRangeCmd.java
index 42262cc2bf15..439edcbf8f99 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateStorageNetworkIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateStorageNetworkIpRangeCmd.java
@@ -50,24 +50,24 @@ public class CreateStorageNetworkIpRangeCmd extends BaseAsyncCmd {
type = CommandType.UUID,
entityType = PodResponse.class,
required = true,
- description = "UUID of pod where the ip range belongs to")
+ description = "ID of pod where the IP range belongs to")
private Long podId;
- @Parameter(name = ApiConstants.START_IP, type = CommandType.STRING, required = true, description = "the beginning IP address")
+ @Parameter(name = ApiConstants.START_IP, type = CommandType.STRING, required = true, description = "The starting IP address")
private String startIp;
- @Parameter(name = ApiConstants.END_IP, type = CommandType.STRING, description = "the ending IP address")
+ @Parameter(name = ApiConstants.END_IP, type = CommandType.STRING, description = "The ending IP address")
private String endIp;
@Parameter(name = ApiConstants.VLAN,
type = CommandType.INTEGER,
- description = "Optional. The vlan the ip range sits on, default to Null when it is not specified which means your network is not on any Vlan. This is mainly for Vmware as other hypervisors can directly retrieve bridge from physical network traffic type table")
+ description = "Optional. The VLAN the IP range sits on, default to Null when it is not specified which means your network is not on any VLAN. This is mainly for VMware as other hypervisors can directly retrieve bridge from physical network traffic type table")
private Integer vlan;
- @Parameter(name = ApiConstants.NETMASK, type = CommandType.STRING, required = true, description = "the netmask for storage network")
+ @Parameter(name = ApiConstants.NETMASK, type = CommandType.STRING, required = true, description = "The netmask for storage network")
private String netmask;
- @Parameter(name = ApiConstants.GATEWAY, type = CommandType.STRING, required = true, description = "the gateway for storage network")
+ @Parameter(name = ApiConstants.GATEWAY, type = CommandType.STRING, required = true, description = "The gateway for storage network")
private String gateway;
/////////////////////////////////////////////////////
@@ -105,7 +105,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Creating storage ip range from " + getStartIp() + " to " + getEndIp() + " with vlan " + getVlan();
+ return "Creating storage IP range from " + getStartIp() + " to " + getEndIp() + " with VLAN " + getVlan();
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateGuestVlanRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateGuestVlanRangeCmd.java
index 355f738679e0..dcc1fa51dcee 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateGuestVlanRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateGuestVlanRangeCmd.java
@@ -44,23 +44,23 @@ public class DedicateGuestVlanRangeCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.VLAN_RANGE, type = CommandType.STRING, required = true, description = "guest vlan range to be dedicated")
+ @Parameter(name = ApiConstants.VLAN_RANGE, type = CommandType.STRING, required = true, description = "Guest VLAN range to be dedicated")
private String vlan;
- @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "account who will own the VLAN")
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Account who will own the VLAN")
private String accountName;
- @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "project who will own the VLAN")
+ @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Project who will own the VLAN")
private Long projectId;
- @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "domain ID of the account owning a VLAN")
+ @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "Domain ID of the Account owning a VLAN")
private Long domainId;
@Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID,
type = CommandType.UUID,
entityType = PhysicalNetworkResponse.class,
required = true,
- description = "physical network ID of the vlan")
+ description = "Physical Network ID of the VLAN")
private Long physicalNetworkId;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmd.java
index 2df032c559c5..cc76b284e24a 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmd.java
@@ -82,7 +82,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Dedicating zone IPv4 subnet " + getId();
+ return "Dedicating zone's IPv4 subnet with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteGuestNetworkIpv6PrefixCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteGuestNetworkIpv6PrefixCmd.java
index e2ada4191a82..405bbb594edb 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteGuestNetworkIpv6PrefixCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteGuestNetworkIpv6PrefixCmd.java
@@ -63,7 +63,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting guest IPv6 prefix " + getId();
+ return "Deleting guest IPv6 prefix with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmd.java
index 28a646f9d036..f6b22f79dfc7 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmd.java
@@ -59,7 +59,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting guest IPv4 subnet " + getId();
+ return "Deleting guest IPv4 subnet with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmd.java
index 222bc1bad98d..0ff2a9ad70b8 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmd.java
@@ -59,7 +59,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting zone IPv4 subnet " + getId();
+ return "Deleting zone IPv4 subnet with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java
index 41cf5e518b34..1e69aaa6c440 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java
@@ -100,7 +100,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting management ip range from " + getStartIp() + " to " + getEndIp() + " of Pod: " + getPodId();
+ return "Deleting management IP range from " + getStartIp() + " to " + getEndIp() + " from Pod: " + getResourceUuid(ApiConstants.POD_ID);
}
@Override
@@ -116,7 +116,7 @@ public void execute() {
logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (Exception e) {
- logger.warn("Failed to delete management ip range from " + getStartIp() + " to " + getEndIp() + " of Pod: " + getPodId(), e);
+ logger.warn("Failed to delete management ip range from {} to {} of Pod: {}", getStartIp(), getEndIp(), getPodId(), e);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkOfferingCmd.java
index e0598b71ea17..a24fc0dc3714 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkOfferingCmd.java
@@ -40,7 +40,7 @@ public class DeleteNetworkOfferingCmd extends BaseCmd {
type = CommandType.UUID,
entityType = NetworkOfferingResponse.class,
required = true,
- description = "the ID of the network offering")
+ description = "The ID of the network offering")
private Long id;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java
index 4b56612fddaa..2573e92b9860 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java
@@ -45,7 +45,7 @@ public class DeleteNetworkServiceProviderCmd extends BaseAsyncCmd {
type = CommandType.UUID,
entityType = ProviderResponse.class,
required = true,
- description = "the ID of the network service provider")
+ description = "The ID of the network service provider")
private Long id;
/////////////////////////////////////////////////////
@@ -91,7 +91,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting Physical network ServiceProvider: " + getId();
+ return "Deleting Physical network ServiceProvider with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java
index 3233130211c4..9994e8e391d7 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java
@@ -43,7 +43,7 @@ public class DeletePhysicalNetworkCmd extends BaseAsyncCmd {
type = CommandType.UUID,
entityType = PhysicalNetworkResponse.class,
required = true,
- description = "the ID of the Physical network")
+ description = "The ID of the Physical network")
private Long id;
/////////////////////////////////////////////////////
@@ -65,7 +65,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Physical Network Id: " + id);
+ CallContext.current().setEventDetails("Physical Network Id: " + getResourceUuid(ApiConstants.ID));
boolean result = _networkService.deletePhysicalNetwork(getId());
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
@@ -77,7 +77,7 @@ public void execute() {
@Override
public String getEventDescription() {
- return "Deleting Physical network: " + getId();
+ return "Deleting Physical network with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java
index 454dfba92f20..dcab38561408 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java
@@ -46,7 +46,7 @@ public class DeleteStorageNetworkIpRangeCmd extends BaseAsyncCmd {
type = CommandType.UUID,
entityType = StorageNetworkIpRangeResponse.class,
required = true,
- description = "the uuid of the storage network ip range")
+ description = "The UUID of the storage network IP range")
private Long id;
/////////////////////////////////////////////////////
@@ -64,7 +64,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting storage ip range " + getId();
+ return "Deleting storage IP range with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
@@ -75,7 +75,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} catch (Exception e) {
- logger.warn("Failed to delete storage network ip range " + getId(), e);
+ logger.warn("Failed to delete storage network ip range {}", getId(), e);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListDedicatedGuestVlanRangesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListDedicatedGuestVlanRangesCmd.java
index 0247a3069212..a5edbfdce4a9 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListDedicatedGuestVlanRangesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListDedicatedGuestVlanRangesCmd.java
@@ -44,33 +44,33 @@ public class ListDedicatedGuestVlanRangesCmd extends BaseListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = GuestVlanRangeResponse.class, description = "list dedicated guest vlan ranges by id")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = GuestVlanRangeResponse.class, description = "List dedicated guest VLAN ranges by ID")
private Long id;
@Parameter(name = ApiConstants.ACCOUNT,
type = CommandType.STRING,
- description = "the account with which the guest VLAN range is associated. Must be used with the domainId parameter.")
+ description = "The account with which the guest VLAN range is associated. Must be used with the domainId parameter.")
private String accountName;
- @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "project who will own the guest VLAN range")
+ @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Project who will own the guest VLAN range")
private Long projectId;
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.UUID,
entityType = DomainResponse.class,
- description = "the domain ID with which the guest VLAN range is associated. If used with the account parameter, returns all guest VLAN ranges for that account in the specified domain.")
+ description = "The domain ID with which the guest VLAN range is associated. If used with the account parameter, returns all guest VLAN ranges for that account in the specified domain.")
private Long domainId;
- @Parameter(name = ApiConstants.GUEST_VLAN_RANGE, type = CommandType.STRING, description = "the dedicated guest vlan range")
+ @Parameter(name = ApiConstants.GUEST_VLAN_RANGE, type = CommandType.STRING, description = "The dedicated guest vlan range")
private String guestVlanRange;
@Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID,
type = CommandType.UUID,
entityType = PhysicalNetworkResponse.class,
- description = "physical network id of the guest VLAN range")
+ description = "Physical network ID of the guest VLAN range")
private Long physicalNetworkId;
- @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "zone of the guest VLAN range")
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "Zone of the guest VLAN range")
private Long zoneId;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListGuestVlansCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListGuestVlansCmd.java
index 4b368f5e0341..80c9540a8486 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListGuestVlansCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListGuestVlansCmd.java
@@ -44,19 +44,19 @@ public class ListGuestVlansCmd extends BaseListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = false, description = "list guest vlan by id")
+ @Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = false, description = "List guest VLAN by ID")
private Long id;
- @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = false, description = "list guest vlan by zone")
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = false, description = "List guest VLAN by zone")
private Long zoneId;
- @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, required = false, description = "list guest vlan by physical network")
+ @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, required = false, description = "List guest VLAN by physical network")
private Long physicalNetworkId;
- @Parameter(name = ApiConstants.VNET, type = CommandType.STRING, required = false, description = "list guest vlan by vnet")
+ @Parameter(name = ApiConstants.VNET, type = CommandType.STRING, required = false, description = "List guest VLAN by vnet")
private String vnet;
- @Parameter(name = ApiConstants.ALLOCATED_ONLY, type = CommandType.BOOLEAN, required = false, description = "limits search results to allocated guest vlan. false by default.")
+ @Parameter(name = ApiConstants.ALLOCATED_ONLY, type = CommandType.BOOLEAN, required = false, description = "Limits search results to allocated guest VLAN. False by default.")
private Boolean allocatedOnly;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkDeviceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkDeviceCmd.java
index 768bab641087..ace635376eb4 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkDeviceCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkDeviceCmd.java
@@ -57,7 +57,7 @@ public class ListNetworkDeviceCmd extends BaseListCmd {
description = "Network device type, now supports ExternalDhcp, PxeServer, NetscalerMPXLoadBalancer, NetscalerVPXLoadBalancer, NetscalerSDXLoadBalancer, F5BigIpLoadBalancer, JuniperSRXFirewall, PaloAltoFirewall")
private String type;
- @Parameter(name = ApiConstants.NETWORK_DEVICE_PARAMETER_LIST, type = CommandType.MAP, description = "parameters for network device")
+ @Parameter(name = ApiConstants.NETWORK_DEVICE_PARAMETER_LIST, type = CommandType.MAP, description = "Parameters for network device")
private Map paramList;
public String getDeviceType() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkServiceProvidersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkServiceProvidersCmd.java
index 68495a62215f..95071e41f6c0 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkServiceProvidersCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkServiceProvidersCmd.java
@@ -44,13 +44,13 @@ public class ListNetworkServiceProvidersCmd extends BaseListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, description = "the Physical Network ID")
+ @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, description = "The Physical Network ID")
private Long physicalNetworkId;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "list providers by name")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "List providers by name")
private String name;
- @Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "list providers by state")
+ @Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "List providers by state")
private String state;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworksCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworksCmdByAdmin.java
index 8df1133d5e7c..bb564f1c3ded 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworksCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworksCmdByAdmin.java
@@ -30,7 +30,7 @@
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListNetworksCmdByAdmin extends ListNetworksCmd implements AdminCmd {
- @Parameter(name= ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network", since = "4.17.0")
+ @Parameter(name= ApiConstants.VLAN, type=CommandType.STRING, description = "The ID or VID of the network", since = "4.17.0")
private String vlan;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListPhysicalNetworksCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListPhysicalNetworksCmd.java
index 51a6ddabd9f1..27319ff3d671 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListPhysicalNetworksCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListPhysicalNetworksCmd.java
@@ -43,13 +43,13 @@ public class ListPhysicalNetworksCmd extends BaseListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, description = "list physical network by id")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, description = "List physical network by id")
private Long id;
- @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the Zone ID for the physical network")
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "The Zone ID for the physical network")
private Long zoneId;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "search by name")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Search by name")
private String networkName;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListStorageNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListStorageNetworkIpRangeCmd.java
index 556162ca360d..3e32bed3d500 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListStorageNetworkIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListStorageNetworkIpRangeCmd.java
@@ -51,19 +51,19 @@ public class ListStorageNetworkIpRangeCmd extends BaseListCmd {
@Parameter(name = ApiConstants.ID,
type = CommandType.UUID,
entityType = StorageNetworkIpRangeResponse.class,
- description = "optional parameter. Storaget network IP range uuid, if specicied, using it to search the range.")
+ description = "Optional parameter. Storage network IP range UUID, if specified, using it to search the range.")
private Long rangeId;
@Parameter(name = ApiConstants.POD_ID,
type = CommandType.UUID,
entityType = PodResponse.class,
- description = "optional parameter. Pod uuid, if specicied and range uuid is absent, using it to search the range.")
+ description = "Optional parameter. Pod UUID, if specified and range UUID is absent, using it to search the range.")
private Long podId;
@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.UUID,
entityType = ZoneResponse.class,
- description = "optional parameter. Zone uuid, if specicied and both pod uuid and range uuid are absent, using it to search the range.")
+ description = "Optional parameter. Zone UUID, if specified and both pod UUID and range UUID are absent, using it to search the range.")
private Long zoneId;
/////////////////////////////////////////////////////
@@ -97,7 +97,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
response.setResponseName(getCommandName());
this.setResponseObject(response);
} catch (Exception e) {
- logger.warn("Failed to list storage network ip range for rangeId=" + getRangeId() + " podId=" + getPodId() + " zoneId=" + getZoneId());
+ logger.warn("Failed to list storage Network IP range for rangeId={} podId={} zoneId={}", getRangeId(), getPodId(), getZoneId());
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListSupportedNetworkServicesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListSupportedNetworkServicesCmd.java
index 120c6af41ad6..227e9b684526 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListSupportedNetworkServicesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListSupportedNetworkServicesCmd.java
@@ -40,10 +40,10 @@
responseHasSensitiveInfo = false)
public class ListSupportedNetworkServicesCmd extends BaseListCmd {
- @Parameter(name = ApiConstants.PROVIDER, type = CommandType.STRING, description = "network service provider name")
+ @Parameter(name = ApiConstants.PROVIDER, type = CommandType.STRING, description = "Network service provider name")
private String providerName;
- @Parameter(name = ApiConstants.SERVICE, type = CommandType.STRING, description = "network service name to list providers and capabilities of")
+ @Parameter(name = ApiConstants.SERVICE, type = CommandType.STRING, description = "Network service name to list providers and capabilities of")
private String serviceName;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java
index 8ef853b99da8..ad78bd3b406c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java
@@ -38,7 +38,7 @@
import com.cloud.user.Account;
import com.cloud.user.User;
-@APICommand(name = "migrateNetwork", description = "moves a network to another physical network",
+@APICommand(name = "migrateNetwork", description = "Moves a network to another physical network",
responseObject = NetworkResponse.class,
responseView = ResponseView.Restricted,
entityType = {Network.class},
@@ -53,13 +53,13 @@ public class MigrateNetworkCmd extends BaseAsyncCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@ACL(accessType = AccessType.OperateEntry)
- @Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, required = true, description = "the ID of the network")
+ @Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, required = true, description = "The ID of the network")
protected Long id;
- @Parameter(name = ApiConstants.NETWORK_OFFERING_ID, type = CommandType.UUID, entityType = NetworkOfferingResponse.class, required = true, description = "network offering ID")
+ @Parameter(name = ApiConstants.NETWORK_OFFERING_ID, type = CommandType.UUID, entityType = NetworkOfferingResponse.class, required = true, description = "Network offering ID")
private Long networkOfferingId;
- @Parameter(name = ApiConstants.RESUME, type = CommandType.BOOLEAN, description = "true if previous network migration cmd failed")
+ @Parameter(name = ApiConstants.RESUME, type = CommandType.BOOLEAN, description = "True if previous network migration cmd failed")
private Boolean resume;
/////////////////////////////////////////////////////
@@ -115,7 +115,7 @@ public void execute() {
@Override
public String getEventDescription() {
- StringBuilder eventMsg = new StringBuilder("Migrating network: " + getId());
+ String description = "Migrating Network with ID: " + getResourceUuid(ApiConstants.NETWORK_ID);
if (getNetworkOfferingId() != null) {
Network network = _networkService.getNetwork(getId());
if (network == null) {
@@ -128,11 +128,11 @@ public String getEventDescription() {
throw new InvalidParameterValueException("Network offering id supplied is invalid");
}
- eventMsg.append(". Original network offering id: " + oldOff.getUuid() + ", new network offering id: " + newOff.getUuid());
+ description += ". Original Network Offering id: " + oldOff.getUuid() + ", new Network Offering id: " + newOff.getUuid();
}
}
- return eventMsg.toString();
+ return description;
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java
index 3e0801be40b1..2973fea33c6a 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java
@@ -40,7 +40,7 @@
import com.cloud.user.User;
@APICommand(name = "migrateVPC",
- description = "moves a vpc to another physical network",
+ description = "Moves a VPC to another physical network",
responseObject = VpcResponse.class,
responseView = ResponseObject.ResponseView.Restricted,
entityType = {Vpc.class},
@@ -56,16 +56,16 @@ public class MigrateVPCCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
@ACL(accessType = SecurityChecker.AccessType.OperateEntry)
@Parameter(name= ApiConstants.VPC_ID, type=CommandType.UUID, entityType = VpcResponse.class,
- required=true, description = "the ID of the vpc")
+ required=true, description = "The ID of the VPC ")
protected Long id;
- @Parameter(name = ApiConstants.VPC_OFF_ID, type = CommandType.UUID, entityType = VpcOfferingResponse.class, required=true, description = "vpc offering ID")
+ @Parameter(name = ApiConstants.VPC_OFF_ID, type = CommandType.UUID, entityType = VpcOfferingResponse.class, required=true, description = "VPC offering ID")
private Long vpcOfferingId;
- @Parameter(name = ApiConstants.TIER_NETWORK_OFFERINGS, type = CommandType.MAP, description = "network offering ids for each network in the vpc. Example: tierNetworkOfferings[0].networkId=networkId1&tierNetworkOfferings[0].networkOfferingId=newNetworkofferingId1&tierNetworkOfferings[1].networkId=networkId2&tierNetworkOfferings[1].networkOfferingId=newNetworkofferingId2")
+ @Parameter(name = ApiConstants.TIER_NETWORK_OFFERINGS, type = CommandType.MAP, description = "Network offering IDs for each network in the VPC. Example: tierNetworkOfferings[0].networkId=networkId1&tierNetworkOfferings[0].networkOfferingId=newNetworkofferingId1&tierNetworkOfferings[1].networkId=networkId2&tierNetworkOfferings[1].networkOfferingId=newNetworkofferingId2")
private Map> tierNetworkOfferings;
- @Parameter(name = ApiConstants.RESUME, type = CommandType.BOOLEAN, description = "true if previous network migration cmd failed")
+ @Parameter(name = ApiConstants.RESUME, type = CommandType.BOOLEAN, description = "True if previous network migration cmd failed")
private Boolean resume;
/////////////////////////////////////////////////////
@@ -115,12 +115,12 @@ public void execute() {
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate vpc");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate VPC");
}
}
@Override
- public String getEventDescription() { return "Migrating vpc: " + getId() + " to new vpc offering (" + vpcOfferingId + ")"; }
+ public String getEventDescription() { return "Migrating VPC with ID: " + getResourceUuid(ApiConstants.VPC_ID) + " to new VPC offering with ID: " + getResourceUuid(ApiConstants.VPC_OFF_ID);}
@Override
public String getEventType() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/NetworkOfferingBaseCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/NetworkOfferingBaseCmd.java
new file mode 100644
index 000000000000..1c832b7217ef
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/NetworkOfferingBaseCmd.java
@@ -0,0 +1,493 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.network;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.VirtualRouterProvider;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.cloud.network.Network.Service.Dhcp;
+import static com.cloud.network.Network.Service.Dns;
+import static com.cloud.network.Network.Service.Firewall;
+import static com.cloud.network.Network.Service.Lb;
+import static com.cloud.network.Network.Service.NetworkACL;
+import static com.cloud.network.Network.Service.PortForwarding;
+import static com.cloud.network.Network.Service.SourceNat;
+import static com.cloud.network.Network.Service.StaticNat;
+import static com.cloud.network.Network.Service.UserData;
+
+import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNsxWithoutLb;
+import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNetrisNatted;
+import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNetrisRouted;
+
+public abstract class NetworkOfferingBaseCmd extends BaseCmd {
+
+ public abstract String getGuestIpType();
+ public abstract String getTraffictype();
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "The name of the network offering")
+ private String networkOfferingName;
+
+ @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "The display text of the network offering, defaults to the value of 'name'.")
+ private String displayText;
+
+ @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "The tags for the network offering.", length = 4096)
+ private String tags;
+
+ @Parameter(name = ApiConstants.SPECIFY_VLAN, type = CommandType.BOOLEAN, description = "True if network offering supports VLANs")
+ private Boolean specifyVlan;
+
+ @Parameter(name = ApiConstants.AVAILABILITY, type = CommandType.STRING, description = "The availability of network offering. The default value is Optional. "
+ + " Another value is Required, which will make it as the default network offering for new networks ")
+ private String availability;
+
+ @Parameter(name = ApiConstants.NETWORKRATE, type = CommandType.INTEGER, description = "Data transfer rate in megabits per second allowed")
+ private Integer networkRate;
+
+ @Parameter(name = ApiConstants.CONSERVE_MODE, type = CommandType.BOOLEAN, description = "True if the network offering is IP conserve mode enabled")
+ private Boolean conserveMode;
+
+ @Parameter(name = ApiConstants.SERVICE_OFFERING_ID,
+ type = CommandType.UUID,
+ entityType = ServiceOfferingResponse.class,
+ description = "The service offering ID used by virtual router provider")
+ private Long serviceOfferingId;
+
+ @Parameter(name = ApiConstants.INTERNET_PROTOCOL,
+ type = CommandType.STRING,
+ description = "The internet protocol of network offering. Options are IPv4 and dualstack. Default is IPv4. dualstack will create a network offering that supports both IPv4 and IPv6",
+ since = "4.17.0")
+ private String internetProtocol;
+
+ @Parameter(name = ApiConstants.SUPPORTED_SERVICES,
+ type = CommandType.LIST,
+ collectionType = CommandType.STRING,
+ description = "Services supported by the network offering")
+ private List supportedServices;
+
+ @Parameter(name = ApiConstants.SERVICE_PROVIDER_LIST,
+ type = CommandType.MAP,
+ description = "Provider to service mapping. If not specified, the provider for the service will be mapped to the default provider on the physical network")
+ private Map serviceProviderList;
+
+ @Parameter(name = ApiConstants.SERVICE_CAPABILITY_LIST, type = CommandType.MAP, description = "Desired service capabilities as part of network offering")
+ private Map serviceCapabilitiesList;
+
+ @Parameter(name = ApiConstants.SPECIFY_IP_RANGES,
+ type = CommandType.BOOLEAN,
+ description = "True if network offering supports specifying ip ranges; defaulted to false if not specified")
+ private Boolean specifyIpRanges;
+
+ @Parameter(name = ApiConstants.IS_PERSISTENT,
+ type = CommandType.BOOLEAN,
+ description = "True if network offering supports persistent networks; defaulted to false if not specified")
+ private Boolean isPersistent;
+
+ @Parameter(name = ApiConstants.FOR_VPC,
+ type = CommandType.BOOLEAN,
+ description = "True if network offering is meant to be used for VPC, false otherwise.")
+ private Boolean forVpc;
+
+ @Deprecated
+ @Parameter(name = ApiConstants.FOR_NSX,
+ type = CommandType.BOOLEAN,
+ description = "true if network offering is meant to be used for NSX, false otherwise.",
+ since = "4.20.0")
+ private Boolean forNsx;
+
+ @Parameter(name = ApiConstants.PROVIDER,
+ type = CommandType.STRING,
+ description = "Name of the provider providing the service",
+ since = "4.21.0")
+ private String provider;
+
+ @Parameter(name = ApiConstants.NSX_SUPPORT_LB,
+ type = CommandType.BOOLEAN,
+ description = "True if network offering for NSX network offering supports Load balancer service.",
+ since = "4.20.0")
+ private Boolean nsxSupportsLbService;
+
+ @Parameter(name = ApiConstants.NSX_SUPPORTS_INTERNAL_LB,
+ type = CommandType.BOOLEAN,
+ description = "True if network offering for NSX network offering supports Internal Load balancer service.",
+ since = "4.20.0")
+ private Boolean nsxSupportsInternalLbService;
+
+ @Parameter(name = ApiConstants.NETWORK_MODE,
+ type = CommandType.STRING,
+ description = "Indicates the mode with which the network will operate. Valid option: NATTED or ROUTED",
+ since = "4.20.0")
+ private String networkMode;
+
+ @Parameter(name = ApiConstants.FOR_TUNGSTEN,
+ type = CommandType.BOOLEAN,
+ description = "True if network offering is meant to be used for Tungsten-Fabric, false otherwise.")
+ private Boolean forTungsten;
+
+ @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, since = "4.2.0", description = "Network offering details in key/value pairs."
+ + " Supported keys are internallbprovider/publiclbprovider with service provider as a value, and"
+ + " promiscuousmode/macaddresschanges/forgedtransmits with true/false as value to accept/reject the security settings if available for a nic/portgroup")
+ protected Map details;
+
+ @Parameter(name = ApiConstants.EGRESS_DEFAULT_POLICY,
+ type = CommandType.BOOLEAN,
+ description = "True if guest network default egress policy is allow; false if default egress policy is deny")
+ private Boolean egressDefaultPolicy;
+
+ @Parameter(name = ApiConstants.KEEPALIVE_ENABLED,
+ type = CommandType.BOOLEAN,
+ required = false,
+ description = "If true keepalive will be turned on in the loadbalancer. At the time of writing this has only an effect on haproxy; the mode http and httpclose options are unset in the haproxy conf file.")
+ private Boolean keepAliveEnabled;
+
+ @Parameter(name = ApiConstants.MAX_CONNECTIONS,
+ type = CommandType.INTEGER,
+ description = "Maximum number of concurrent connections supported by the Network offering")
+ private Integer maxConnections;
+
+ @Parameter(name = ApiConstants.DOMAIN_ID,
+ type = CommandType.LIST,
+ collectionType = CommandType.UUID,
+ entityType = DomainResponse.class,
+ description = "The ID of the containing domain(s), null for public offerings")
+ private List domainIds;
+
+ @Parameter(name = ApiConstants.ZONE_ID,
+ type = CommandType.LIST,
+ collectionType = CommandType.UUID,
+ entityType = ZoneResponse.class,
+ description = "The ID of the containing zone(s), null for public offerings",
+ since = "4.13")
+ private List zoneIds;
+
+ @Parameter(name = ApiConstants.ENABLE,
+ type = CommandType.BOOLEAN,
+ description = "Set to true if the offering is to be enabled during creation. Default is false",
+ since = "4.16")
+ private Boolean enable;
+
+ @Parameter(name = ApiConstants.SPECIFY_AS_NUMBER, type = CommandType.BOOLEAN, since = "4.20.0",
+ description = "true if network offering supports choosing AS number")
+ private Boolean specifyAsNumber;
+
+ @Parameter(name = ApiConstants.ROUTING_MODE,
+ type = CommandType.STRING,
+ since = "4.20.0",
+ description = "the routing mode for the network offering. Supported types are: Static or Dynamic.")
+ private String routingMode;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public String getNetworkOfferingName() {
+ return networkOfferingName;
+ }
+
+ public String getDisplayText() {
+ return StringUtils.isEmpty(displayText) ? networkOfferingName : displayText;
+ }
+
+ public String getTags() {
+ return tags;
+ }
+
+ public Boolean getSpecifyVlan() {
+ return specifyVlan == null ? false : specifyVlan;
+ }
+
+ public String getAvailability() {
+ return availability == null ? NetworkOffering.Availability.Optional.toString() : availability;
+ }
+
+ public Integer getNetworkRate() {
+ return networkRate;
+ }
+
+ public Long getServiceOfferingId() {
+ return serviceOfferingId;
+ }
+
+ public boolean isExternalNetworkProvider() {
+ return Arrays.asList("NSX", "Netris").stream()
+ .anyMatch(s -> provider != null && s.equalsIgnoreCase(provider));
+ }
+
+ public boolean isForNsx() {
+ return provider != null && provider.equalsIgnoreCase("NSX");
+ }
+
+ public boolean isForNetris() {
+ return provider != null && provider.equalsIgnoreCase("Netris");
+ }
+
+ public String getProvider() {
+ return provider;
+ }
+
+ public List getSupportedServices() {
+ if (!isExternalNetworkProvider()) {
+ return supportedServices == null ? new ArrayList() : supportedServices;
+ } else {
+ List services = new ArrayList<>(List.of(
+ Dhcp.getName(),
+ Dns.getName(),
+ UserData.getName()
+ ));
+ if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode())) {
+ services.addAll(Arrays.asList(
+ StaticNat.getName(),
+ SourceNat.getName(),
+ PortForwarding.getName()));
+ }
+ if (getNsxSupportsLbService() || (provider != null && isNetrisNatted(getProvider(), getNetworkMode()))) {
+ services.add(Lb.getName());
+ }
+ if (Boolean.TRUE.equals(forVpc)) {
+ services.add(NetworkACL.getName());
+ } else {
+ services.add(Firewall.getName());
+ }
+ return services;
+ }
+ }
+
+ public String getInternetProtocol() {
+ return internetProtocol;
+ }
+
+ public Boolean getSpecifyIpRanges() {
+ return specifyIpRanges == null ? false : specifyIpRanges;
+ }
+
+ public Boolean getConserveMode() {
+ if (conserveMode == null) {
+ return true;
+ }
+ return conserveMode;
+ }
+
+ public Boolean getIsPersistent() {
+ return isPersistent == null ? false : isPersistent;
+ }
+
+ public Boolean getForVpc() {
+ return forVpc;
+ }
+
+ public String getNetworkMode() {
+ return networkMode;
+ }
+
+ public boolean getNsxSupportsLbService() {
+ return BooleanUtils.isTrue(nsxSupportsLbService);
+ }
+
+ public boolean getNsxSupportsInternalLbService() {
+ return BooleanUtils.isTrue(nsxSupportsInternalLbService);
+ }
+
+ public Boolean getForTungsten() {
+ return forTungsten;
+ }
+
+ public Boolean getEgressDefaultPolicy() {
+ if (egressDefaultPolicy == null) {
+ return true;
+ }
+ return egressDefaultPolicy;
+ }
+
+ public Boolean getKeepAliveEnabled() {
+ return keepAliveEnabled;
+ }
+
+ public Integer getMaxconnections() {
+ return maxConnections;
+ }
+
+ public Map> getServiceProviders() {
+ Map> serviceProviderMap = new HashMap<>();
+ if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isExternalNetworkProvider()) {
+ Collection servicesCollection = serviceProviderList.values();
+ Iterator iter = servicesCollection.iterator();
+ while (iter.hasNext()) {
+ HashMap services = (HashMap) iter.next();
+ String service = services.get("service");
+ String provider = services.get("provider");
+ List providerList = null;
+ if (serviceProviderMap.containsKey(service)) {
+ providerList = serviceProviderMap.get(service);
+ } else {
+ providerList = new ArrayList();
+ }
+ providerList.add(provider);
+ serviceProviderMap.put(service, providerList);
+ }
+ } else if (isExternalNetworkProvider()) {
+ getServiceProviderMapForExternalProvider(serviceProviderMap, Network.Provider.getProvider(provider).getName());
+ }
+ return serviceProviderMap;
+ }
+
+ private void getServiceProviderMapForExternalProvider(Map> serviceProviderMap, String provider) {
+ String routerProvider = Boolean.TRUE.equals(getForVpc()) ? VirtualRouterProvider.Type.VPCVirtualRouter.name() :
+ VirtualRouterProvider.Type.VirtualRouter.name();
+ List unsupportedServices = new ArrayList<>(List.of("Vpn", "Gateway", "SecurityGroup", "Connectivity", "BaremetalPxeService"));
+ List routerSupported = List.of("Dhcp", "Dns", "UserData");
+ List allServices = Network.Service.listAllServices().stream().map(Network.Service::getName).collect(Collectors.toList());
+ if (routerProvider.equals(VirtualRouterProvider.Type.VPCVirtualRouter.name())) {
+ unsupportedServices.add("Firewall");
+ } else {
+ unsupportedServices.add("NetworkACL");
+ }
+ for (String service : allServices) {
+ if (unsupportedServices.contains(service))
+ continue;
+ if (routerSupported.contains(service))
+ serviceProviderMap.put(service, List.of(routerProvider));
+ else if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode()) || NetworkACL.getName().equalsIgnoreCase(service)) {
+ serviceProviderMap.put(service, List.of(provider));
+ }
+ if (isNsxWithoutLb(getProvider(), getNsxSupportsLbService()) || isNetrisRouted(getProvider(), getNetworkMode())) {
+ serviceProviderMap.remove(Lb.getName());
+ }
+ }
+ }
+
+ public Map getServiceCapabilities(Network.Service service) {
+ Map capabilityMap = null;
+
+ if (serviceCapabilitiesList != null && !serviceCapabilitiesList.isEmpty()) {
+ capabilityMap = new HashMap();
+ Collection serviceCapabilityCollection = serviceCapabilitiesList.values();
+ Iterator iter = serviceCapabilityCollection.iterator();
+ while (iter.hasNext()) {
+ HashMap svcCapabilityMap = (HashMap) iter.next();
+ Network.Capability capability = null;
+ String svc = svcCapabilityMap.get("service");
+ String capabilityName = svcCapabilityMap.get("capabilitytype");
+ String capabilityValue = svcCapabilityMap.get("capabilityvalue");
+
+ if (capabilityName != null) {
+ capability = Network.Capability.getCapability(capabilityName);
+ }
+
+ if ((capability == null) || (capabilityName == null) || (capabilityValue == null)) {
+ throw new InvalidParameterValueException("Invalid capability:" + capabilityName + " capability value:" + capabilityValue);
+ }
+
+ if (svc.equalsIgnoreCase(service.getName())) {
+ capabilityMap.put(capability, capabilityValue);
+ } else {
+ //throw new InvalidParameterValueException("Service is not equal ")
+ }
+ }
+ }
+
+ return capabilityMap;
+ }
+
+ public Map getDetails() {
+ if (details == null || details.isEmpty()) {
+ return null;
+ }
+
+ Collection paramsCollection = details.values();
+ Object objlist[] = paramsCollection.toArray();
+ Map params = (Map) (objlist[0]);
+ for (int i = 1; i < objlist.length; i++) {
+ params.putAll((Map) (objlist[i]));
+ }
+
+ return params;
+ }
+
+ public String getServicePackageId() {
+ Map data = getDetails();
+ if (data == null)
+ return null;
+ return data.get(NetworkOffering.Detail.servicepackageuuid + "");
+ }
+
+ public List getDomainIds() {
+ if (CollectionUtils.isNotEmpty(domainIds)) {
+ Set set = new LinkedHashSet<>(domainIds);
+ domainIds.clear();
+ domainIds.addAll(set);
+ }
+ return domainIds;
+ }
+
+ public List getZoneIds() {
+ if (CollectionUtils.isNotEmpty(zoneIds)) {
+ Set set = new LinkedHashSet<>(zoneIds);
+ zoneIds.clear();
+ zoneIds.addAll(set);
+ }
+ return zoneIds;
+ }
+
+ public Boolean getEnable() {
+ if (enable != null) {
+ return enable;
+ }
+ return false;
+ }
+
+ public boolean getSpecifyAsNumber() {
+ return BooleanUtils.toBoolean(specifyAsNumber);
+ }
+
+ public String getRoutingMode() {
+ return routingMode;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedGuestVlanRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedGuestVlanRangeCmd.java
index b3125ec36680..56d042719f68 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedGuestVlanRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedGuestVlanRangeCmd.java
@@ -44,7 +44,7 @@ public class ReleaseDedicatedGuestVlanRangeCmd extends BaseAsyncCmd {
type = CommandType.UUID,
entityType = GuestVlanRangeResponse.class,
required = true,
- description = "the ID of the dedicated guest vlan range")
+ description = "The ID of the dedicated guest VLAN range")
private Long id;
// ///////////////////////////////////////////////////
@@ -72,7 +72,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Releasing a dedicated guest vlan range.";
+ return "Releasing dedicated guest VLAN range with ID: " + getResourceUuid(ApiConstants.ID);
}
// ///////////////////////////////////////////////////
@@ -81,7 +81,7 @@ public String getEventDescription() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Dedicated guest vlan range Id: " + id);
+ CallContext.current().setEventDetails("Dedicated guest VLAN range ID: " + getResourceUuid(ApiConstants.ID));
boolean result = _networkService.releaseDedicatedGuestVlanRange(getId());
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedIpv4SubnetForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedIpv4SubnetForZoneCmd.java
index 3e151b9b58f4..a5e763c0cb00 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedIpv4SubnetForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedIpv4SubnetForZoneCmd.java
@@ -59,7 +59,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Releasing a dedicated zone IPv4 subnet " + getId();
+ return "Releasing dedicated zone IPv4 subnet with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateIpv4SubnetForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateIpv4SubnetForZoneCmd.java
index da7a23f50d9c..db5daa505bee 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateIpv4SubnetForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateIpv4SubnetForZoneCmd.java
@@ -69,7 +69,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Updating zone IPv4 subnet " + getId();
+ return "Updating zone IPv4 subnet with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkCmdByAdmin.java
index b3088a48840e..5879a998b36e 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkCmdByAdmin.java
@@ -29,7 +29,7 @@
@APICommand(name = "updateNetwork", description = "Updates a network", responseObject = NetworkResponse.class, responseView = ResponseView.Full, entityType = {Network.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class UpdateNetworkCmdByAdmin extends UpdateNetworkCmd implements AdminCmd {
- @Parameter(name= ApiConstants.HIDE_IP_ADDRESS_USAGE, type=CommandType.BOOLEAN, description="when true ip address usage for the network will not be exported by the listUsageRecords API")
+ @Parameter(name= ApiConstants.HIDE_IP_ADDRESS_USAGE, type=CommandType.BOOLEAN, description = "When true IP address usage for the Network will not be exported by the listUsageRecords API")
private Boolean hideIpAddressUsage;
public Boolean getHideIpAddressUsage() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java
index 75fb45e1f115..df9f6ad0664d 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java
@@ -16,7 +16,6 @@
// under the License.
package org.apache.cloudstack.api.command.admin.network;
-import java.util.ArrayList;
import java.util.List;
import org.apache.cloudstack.api.APICommand;
@@ -26,64 +25,63 @@
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.offering.DomainAndZoneIdResolver;
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
-import org.apache.commons.lang3.StringUtils;
-import com.cloud.dc.DataCenter;
-import com.cloud.domain.Domain;
-import com.cloud.exception.InvalidParameterValueException;
+
import com.cloud.offering.NetworkOffering;
import com.cloud.user.Account;
@APICommand(name = "updateNetworkOffering", description = "Updates a network offering.", responseObject = NetworkOfferingResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class UpdateNetworkOfferingCmd extends BaseCmd {
+public class UpdateNetworkOfferingCmd extends BaseCmd implements DomainAndZoneIdResolver {
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = NetworkOfferingResponse.class, description = "the id of the network offering")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = NetworkOfferingResponse.class, description = "The ID of the network offering")
private Long id;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the network offering")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "The name of the network offering")
private String networkOfferingName;
- @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "the display text of the network offering")
+ @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "The display text of the network offering")
private String displayText;
- @Parameter(name = ApiConstants.AVAILABILITY, type = CommandType.STRING, description = "the availability of network offering."
+ @Parameter(name = ApiConstants.AVAILABILITY, type = CommandType.STRING, description = "The availability of network offering."
+ " The value is Required makes this network offering default for Guest Virtual Networks. Only one network offering can have the value Required ")
private String availability;
- @Parameter(name = ApiConstants.SORT_KEY, type = CommandType.INTEGER, description = "sort key of the network offering, integer")
+ @Parameter(name = ApiConstants.SORT_KEY, type = CommandType.INTEGER, description = "Sort key of the network offering, integer")
private Integer sortKey;
- @Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "update state for the network offering")
+ @Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "Update state for the network offering")
private String state;
@Parameter(name = ApiConstants.KEEPALIVE_ENABLED,
type = CommandType.BOOLEAN,
required = false,
- description = "if true keepalive will be turned on in the loadbalancer. At the time of writing this has only an effect on haproxy; the mode http and httpclose options are unset in the haproxy conf file.")
+ description = "If true keepalive will be turned on in the loadbalancer. At the time of writing this has only an effect on haproxy; the mode http and httpclose options are unset in the haproxy conf file.")
private Boolean keepAliveEnabled;
@Parameter(name = ApiConstants.MAX_CONNECTIONS,
type = CommandType.INTEGER,
- description = "maximum number of concurrent connections supported by the network offering")
+ description = "Maximum number of concurrent connections supported by the network offering")
private Integer maxConnections;
- @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "the tags for the network offering.", length = 4096)
+ @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "The tags for the network offering.", length = 4096)
private String tags;
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.STRING,
- description = "the ID of the containing domain(s) as comma separated string, public for public offerings")
+ length = 4096,
+ description = "The ID of the containing domain(s) as comma separated string, public for public offerings")
private String domainIds;
@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.STRING,
- description = "the ID of the containing zone(s) as comma separated string, all for all zones offerings",
+ description = "The ID of the containing zone(s) as comma separated string, all for all zones offerings",
since = "4.13",
length = 4096)
private String zoneIds;
@@ -129,63 +127,11 @@ public String getTags() {
}
public List getDomainIds() {
- List validDomainIds = new ArrayList<>();
- if (StringUtils.isNotEmpty(domainIds)) {
- if (domainIds.contains(",")) {
- String[] domains = domainIds.split(",");
- for (String domain : domains) {
- Domain validDomain = _entityMgr.findByUuid(Domain.class, domain.trim());
- if (validDomain != null) {
- validDomainIds.add(validDomain.getId());
- } else {
- throw new InvalidParameterValueException("Failed to create network offering because invalid domain has been specified.");
- }
- }
- } else {
- domainIds = domainIds.trim();
- if (!domainIds.matches("public")) {
- Domain validDomain = _entityMgr.findByUuid(Domain.class, domainIds.trim());
- if (validDomain != null) {
- validDomainIds.add(validDomain.getId());
- } else {
- throw new InvalidParameterValueException("Failed to create network offering because invalid domain has been specified.");
- }
- }
- }
- } else {
- validDomainIds.addAll(_configService.getNetworkOfferingDomains(id));
- }
- return validDomainIds;
+ return resolveDomainIds(domainIds, id, _configService::getNetworkOfferingDomains, "network offering");
}
public List getZoneIds() {
- List validZoneIds = new ArrayList<>();
- if (StringUtils.isNotEmpty(zoneIds)) {
- if (zoneIds.contains(",")) {
- String[] zones = zoneIds.split(",");
- for (String zone : zones) {
- DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zone.trim());
- if (validZone != null) {
- validZoneIds.add(validZone.getId());
- } else {
- throw new InvalidParameterValueException("Failed to create network offering because invalid zone has been specified.");
- }
- }
- } else {
- zoneIds = zoneIds.trim();
- if (!zoneIds.matches("all")) {
- DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zoneIds.trim());
- if (validZone != null) {
- validZoneIds.add(validZone.getId());
- } else {
- throw new InvalidParameterValueException("Failed to create network offering because invalid zone has been specified.");
- }
- }
- }
- } else {
- validZoneIds.addAll(_configService.getNetworkOfferingZones(id));
- }
- return validZoneIds;
+ return resolveZoneIds(zoneIds, id, _configService::getNetworkOfferingZones, "network offering");
}
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkServiceProviderCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkServiceProviderCmd.java
index b4801d9368eb..e0ce0aade1ee 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkServiceProviderCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkServiceProviderCmd.java
@@ -47,13 +47,13 @@ public class UpdateNetworkServiceProviderCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "Enabled/Disabled/Shutdown the physical network service provider")
private String state;
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ProviderResponse.class, required = true, description = "network service provider id")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ProviderResponse.class, required = true, description = "Network service provider ID")
private Long id;
@Parameter(name = ApiConstants.SERVICE_LIST,
type = CommandType.LIST,
collectionType = CommandType.STRING,
- description = "the list of services to be enabled for this physical network service provider")
+ description = "The list of services to be enabled for this physical network service provider")
private List enabledServices;
/////////////////////////////////////////////////////
@@ -100,7 +100,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Updating physical network ServiceProvider: " + getId();
+ return "Updating Physical Network ServiceProvider with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java
index 162116470bd5..6a6264e418ce 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java
@@ -38,19 +38,19 @@ public class UpdatePhysicalNetworkCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, required = true, description = "physical network id")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, required = true, description = "Physical Network ID")
private Long id;
- @Parameter(name = ApiConstants.NETWORK_SPEED, type = CommandType.STRING, description = "the speed for the physical network[1G/10G]")
+ @Parameter(name = ApiConstants.NETWORK_SPEED, type = CommandType.STRING, description = "The speed for the physical Network[1G/10G]")
private String speed;
- @Parameter(name = ApiConstants.TAGS, type = CommandType.LIST, collectionType = CommandType.STRING, description = "Tag the physical network")
+ @Parameter(name = ApiConstants.TAGS, type = CommandType.LIST, collectionType = CommandType.STRING, description = "Tag the physical Network")
private List tags;
@Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "Enabled/Disabled")
private String state;
- @Parameter(name = ApiConstants.VLAN, type = CommandType.STRING, description = "the VLAN for the physical network")
+ @Parameter(name = ApiConstants.VLAN, type = CommandType.STRING, description = "The VLAN for the physical Network")
private String vlan;
/////////////////////////////////////////////////////
@@ -98,7 +98,7 @@ public void execute() {
@Override
public String getEventDescription() {
- return "Updating Physical network: " + getId();
+ return "Updating Physical Network with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePodManagementNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePodManagementNetworkIpRangeCmd.java
index 6f90a070f0d1..0dfa83a68289 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePodManagementNetworkIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePodManagementNetworkIpRangeCmd.java
@@ -113,7 +113,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Updating pod management IP range " + getNewStartIP() + "-" + getNewEndIP() + " of Pod: " + getPodId();
+ return "Updating pod management IP range " + getNewStartIP() + "-" + getNewEndIP() + " of Pod: " + getResourceUuid(ApiConstants.POD_ID);
}
@Override
@@ -139,7 +139,7 @@ public void execute() {
logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (Exception e) {
- logger.warn("Failed to update pod management IP range " + getNewStartIP() + "-" + getNewEndIP() + " of Pod: " + getPodId(), e);
+ logger.warn("Failed to update pod management IP range {}-{} of Pod: {}", getNewStartIP(), getNewEndIP(), getPodId(), e);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateStorageNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateStorageNetworkIpRangeCmd.java
index 65e2437417de..978e94a783a9 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateStorageNetworkIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateStorageNetworkIpRangeCmd.java
@@ -51,16 +51,16 @@ public class UpdateStorageNetworkIpRangeCmd extends BaseAsyncCmd {
description = "UUID of storage network ip range")
private Long id;
- @Parameter(name = ApiConstants.START_IP, type = CommandType.STRING, description = "the beginning IP address")
+ @Parameter(name = ApiConstants.START_IP, type = CommandType.STRING, description = "The beginning IP address")
private String startIp;
- @Parameter(name = ApiConstants.END_IP, type = CommandType.STRING, description = "the ending IP address")
+ @Parameter(name = ApiConstants.END_IP, type = CommandType.STRING, description = "The ending IP address")
private String endIp;
@Parameter(name = ApiConstants.VLAN, type = CommandType.INTEGER, description = "Optional. the vlan the ip range sits on")
private Integer vlan;
- @Parameter(name = ApiConstants.NETMASK, type = CommandType.STRING, description = "the netmask for storage network")
+ @Parameter(name = ApiConstants.NETMASK, type = CommandType.STRING, description = "The netmask for storage network")
private String netmask;
/////////////////////////////////////////////////////
@@ -93,7 +93,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Update storage ip range " + getId() + " [StartIp=" + getStartIp() + ", EndIp=" + getEndIp() + ", vlan=" + getVlan() + ", netmask=" + getNetmask() + ']';
+ return "Updating storage IP range " + getResourceUuid(ApiConstants.ID) + " [StartIp=" + getStartIp() + ", EndIp=" + getEndIp() + ", VLAN=" + getVlan() + ", netmask=" + getNetmask() + ']';
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForNetworkCmd.java
index 1d6bffca342e..3c58cbb3c532 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForNetworkCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForNetworkCmd.java
@@ -80,7 +80,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Changing Bgp Peers for network " + getNetworkId();
+ return "Changing BGP Peers for Network with ID: " + getResourceUuid(ApiConstants.NETWORK_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForVpcCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForVpcCmd.java
index 0c89f3f1d43c..8784f0672790 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForVpcCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForVpcCmd.java
@@ -80,7 +80,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Changing Bgp Peers for VPC " + getVpcId();
+ return "Changing BGP Peers for VPC with ID: " + getResourceUuid(ApiConstants.VPC_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmd.java
index 80642124938a..f1d9b6723091 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmd.java
@@ -145,7 +145,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Creating Bgp Peer " + getAsNumber() + " for zone=" + getZoneId();
+ return "Creating BGP Peer " + getAsNumber() + " for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DedicateBgpPeerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DedicateBgpPeerCmd.java
index ec3d0ea11629..f1ef963e9872 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DedicateBgpPeerCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DedicateBgpPeerCmd.java
@@ -82,7 +82,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Dedicating Bgp Peer " + getId();
+ return "Dedicating BGP Peer with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DeleteBgpPeerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DeleteBgpPeerCmd.java
index a01711efa44f..a412e91bc48e 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DeleteBgpPeerCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DeleteBgpPeerCmd.java
@@ -59,7 +59,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting Bgp Peer " + getId();
+ return "Deleting BGP Peer with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ReleaseDedicatedBgpPeerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ReleaseDedicatedBgpPeerCmd.java
index 92610c233ef0..c754d443c051 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ReleaseDedicatedBgpPeerCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ReleaseDedicatedBgpPeerCmd.java
@@ -59,7 +59,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Releasing a dedicated Bgp Peer " + getId();
+ return "Releasing dedicated BGP Peer with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmd.java
index ae44330ea033..f45c1ee5a2f3 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmd.java
@@ -120,7 +120,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Updating Bgp Peer " + getId();
+ return "Updating BGP Peer with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CloneDiskOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CloneDiskOfferingCmd.java
new file mode 100644
index 000000000000..8d822be203ad
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CloneDiskOfferingCmd.java
@@ -0,0 +1,73 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.offering;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+
+import com.cloud.offering.DiskOffering;
+
+@APICommand(name = "cloneDiskOffering",
+ description = "Clones a disk offering. All parameters from createDiskOffering are available. If not specified, values will be copied from the source offering.",
+ responseObject = DiskOfferingResponse.class,
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ since = "4.23.0",
+ authorized = {RoleType.Admin, RoleType.DomainAdmin})
+public class CloneDiskOfferingCmd extends CreateDiskOfferingCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.SOURCE_OFFERING_ID,
+ type = BaseCmd.CommandType.UUID,
+ entityType = DiskOfferingResponse.class,
+ required = true,
+ description = "The ID of the source disk offering to clone from")
+ private Long sourceOfferingId;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getSourceOfferingId() {
+ return sourceOfferingId;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public void execute() {
+ DiskOffering result = _configService.cloneDiskOffering(this);
+ if (result != null) {
+ DiskOfferingResponse response = _responseGenerator.createDiskOfferingResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to clone disk offering");
+ }
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CloneServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CloneServiceOfferingCmd.java
new file mode 100644
index 000000000000..d01ca4c195da
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CloneServiceOfferingCmd.java
@@ -0,0 +1,79 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.offering;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+
+import com.cloud.offering.ServiceOffering;
+
+@APICommand(name = "cloneServiceOffering",
+ description = "Clones a service offering. All parameters from createServiceOffering are available. If not specified, values will be copied from the source offering.",
+ responseObject = ServiceOfferingResponse.class,
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ since = "4.23.0",
+ authorized = {RoleType.Admin, RoleType.DomainAdmin})
+public class CloneServiceOfferingCmd extends CreateServiceOfferingCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.SOURCE_OFFERING_ID,
+ type = CommandType.UUID,
+ entityType = ServiceOfferingResponse.class,
+ required = true,
+ description = "The ID of the source service offering to clone from")
+ private Long sourceOfferingId;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getSourceOfferingId() {
+ return sourceOfferingId;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+
+ @Override
+ public void execute() {
+ try {
+ ServiceOffering result = _configService.cloneServiceOffering(this);
+ if (result != null) {
+ ServiceOfferingResponse response = _responseGenerator.createServiceOfferingResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to clone service offering");
+ }
+ } catch (com.cloud.exception.InvalidParameterValueException e) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
+ } catch (com.cloud.utils.exception.CloudRuntimeException e) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+ }
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
index 557c76d63c36..e1ff90e4bd89 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
@@ -52,106 +52,105 @@ public class CreateDiskOfferingCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.DISK_SIZE, type = CommandType.LONG, required = false, description = "size of the disk offering in GB (1GB = 1,073,741,824 bytes)")
+ @Parameter(name = ApiConstants.DISK_SIZE, type = CommandType.LONG, required = false, description = "Size of the disk offering in GB (1GB = 1,073,741,824 bytes)")
private Long diskSize;
@Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "An alternate display text of the disk offering, defaults to 'name'.", length = 4096)
private String displayText;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "name of the disk offering")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Name of the disk offering")
private String offeringName;
- @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "tags for the disk offering", length = 4096)
+ @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "Tags for the disk offering", length = 4096)
private String tags;
- @Parameter(name = ApiConstants.CUSTOMIZED, type = CommandType.BOOLEAN, description = "whether disk offering size is custom or not")
+ @Parameter(name = ApiConstants.CUSTOMIZED, type = CommandType.BOOLEAN, description = "Whether disk offering size is custom or not")
private Boolean customized;
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.LIST,
collectionType = CommandType.UUID,
entityType = DomainResponse.class,
- description = "the ID of the containing domain(s), null for public offerings")
+ description = "The ID of the containing domain(s), null for public offerings")
private List domainIds;
@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.LIST,
collectionType = CommandType.UUID,
entityType = ZoneResponse.class,
- description = "the ID of the containing zone(s), null for public offerings",
+ description = "The ID of the containing zone(s), null for public offerings",
since = "4.13")
private List zoneIds;
- @Parameter(name = ApiConstants.STORAGE_TYPE, type = CommandType.STRING, description = "the storage type of the disk offering. Values are local and shared.")
+ @Parameter(name = ApiConstants.STORAGE_TYPE, type = CommandType.STRING, description = "The storage type of the disk offering. Values are local and shared.")
private String storageType = ServiceOffering.StorageType.shared.toString();
@Parameter(name = ApiConstants.PROVISIONINGTYPE,
type = CommandType.STRING,
- description = "provisioning type used to create volumes. Valid values are thin, sparse, fat.")
+ description = "Provisioning type used to create volumes. Valid values are thin, sparse, fat.")
private String provisioningType = ProvisioningType.THIN.toString();
@Parameter(name = ApiConstants.DISPLAY_OFFERING,
type = CommandType.BOOLEAN,
- description = "an optional field, whether to display the offering to the end user or not.")
+ description = "An optional field, whether to display the offering to the end user or not.")
private Boolean displayOffering;
- @Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, required = false, description = "bytes read rate of the disk offering")
+ @Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, required = false, description = "Bytes read rate of the disk offering")
private Long bytesReadRate;
- @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "burst bytes read rate of the disk offering")
+ @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "Burst bytes read rate of the disk offering")
private Long bytesReadRateMax;
- @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+ @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "Length (in seconds) of the burst")
private Long bytesReadRateMaxLength;
- @Parameter(name = ApiConstants.BYTES_WRITE_RATE, type = CommandType.LONG, required = false, description = "bytes write rate of the disk offering")
+ @Parameter(name = ApiConstants.BYTES_WRITE_RATE, type = CommandType.LONG, required = false, description = "Bytes write rate of the disk offering")
private Long bytesWriteRate;
- @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "burst bytes write rate of the disk offering")
+ @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "Burst bytes write rate of the disk offering")
private Long bytesWriteRateMax;
- @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+ @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "Length (in seconds) of the burst")
private Long bytesWriteRateMaxLength;
- @Parameter(name = ApiConstants.IOPS_READ_RATE, type = CommandType.LONG, required = false, description = "io requests read rate of the disk offering")
+ @Parameter(name = ApiConstants.IOPS_READ_RATE, type = CommandType.LONG, required = false, description = "I/O requests read rate of the disk offering")
private Long iopsReadRate;
- @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "burst requests read rate of the disk offering")
+ @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "Burst requests read rate of the disk offering")
private Long iopsReadRateMax;
- @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+ @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "Length (in seconds) of the burst")
private Long iopsReadRateMaxLength;
- @Parameter(name = ApiConstants.IOPS_WRITE_RATE, type = CommandType.LONG, required = false, description = "io requests write rate of the disk offering")
+ @Parameter(name = ApiConstants.IOPS_WRITE_RATE, type = CommandType.LONG, required = false, description = "I/O requests write rate of the disk offering")
private Long iopsWriteRate;
- @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "burst io requests write rate of the disk offering")
+ @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "Burst I/O requests write rate of the disk offering")
private Long iopsWriteRateMax;
- @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+ @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "Length (in seconds) of the burst")
private Long iopsWriteRateMaxLength;
- @Parameter(name = ApiConstants.CUSTOMIZED_IOPS, type = CommandType.BOOLEAN, required = false, description = "whether disk offering iops is custom or not")
+ @Parameter(name = ApiConstants.CUSTOMIZED_IOPS, type = CommandType.BOOLEAN, required = false, description = "Whether disk offering IOPS is custom or not")
private Boolean customizedIops;
- @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "min iops of the disk offering")
+ @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "Min IOPS of the disk offering")
private Long minIops;
- @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "max iops of the disk offering")
+ @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "Max IOPS of the disk offering")
private Long maxIops;
@Parameter(name = ApiConstants.HYPERVISOR_SNAPSHOT_RESERVE,
type = CommandType.INTEGER,
required = false,
- description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)")
+ description = "Hypervisor Snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)")
private Integer hypervisorSnapshotReserve;
@Parameter(name = ApiConstants.CACHE_MODE,
type = CommandType.STRING,
- required = false,
- description = "the cache mode to use for this disk offering. none, writeback, writethrough or hypervisor default. If the hypervisor default cache mode is used on other hypervisors than KVM, it will fall back to none cache mode",
+ description = "The cache mode to use for this disk offering. none, writeback, writethrough or hypervisor default. If the hypervisor default cache mode is used on other hypervisors than KVM, it will fall back to none cache mode",
since = "4.14")
private String cacheMode;
@@ -164,7 +163,7 @@ public class CreateDiskOfferingCmd extends BaseCmd {
@Parameter(name = ApiConstants.ENCRYPT, type = CommandType.BOOLEAN, required=false, description = "Volumes using this offering should be encrypted", since = "4.18")
private Boolean encrypt;
- @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "details to specify disk offering parameters", since = "4.16")
+ @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Details to specify disk offering parameters", since = "4.16")
private Map details;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
index ec109a2a4f37..4363d6861ba1 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
@@ -54,143 +54,142 @@ public class CreateServiceOfferingCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.CPU_NUMBER, type = CommandType.INTEGER, required = false, description = "the CPU number of the service offering")
+ @Parameter(name = ApiConstants.CPU_NUMBER, type = CommandType.INTEGER, required = false, description = "The CPU number of the service offering")
private Integer cpuNumber;
@Parameter(name = ApiConstants.CPU_SPEED, type = CommandType.INTEGER, required = false, description = "For VMware and Xen based hypervisors this is the CPU speed of the service offering in MHz.\n" +
"For the KVM hypervisor," +
" the values of the parameters cpuSpeed and cpuNumber will be used to calculate the `shares` value. This value is used by the KVM hypervisor to calculate how much time" +
- " the VM will have access to the host's CPU. The `shares` value does not have a unit, and its purpose is being a weight value for the host to compare between its guest" +
- " VMs. For more information, see https://libvirt.org/formatdomain.html#cpu-tuning.")
+ " the Instance will have access to the host's CPU. The `shares` value does not have a unit, and its purpose is being a weight value for the host to compare between its guest" +
+ " Instances. For more information, see https://libvirt.org/formatdomain.html#cpu-tuning.")
private Integer cpuSpeed;
@Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "The display text of the service offering, defaults to 'name'.")
private String displayText;
- @Parameter(name = ApiConstants.PROVISIONINGTYPE, type = CommandType.STRING, description = "provisioning type used to create volumes. Valid values are thin, sparse, fat.")
+ @Parameter(name = ApiConstants.PROVISIONINGTYPE, type = CommandType.STRING, description = "Provisioning type used to create volumes. Valid values are thin, sparse, fat.")
private String provisioningType = Storage.ProvisioningType.THIN.toString();
- @Parameter(name = ApiConstants.MEMORY, type = CommandType.INTEGER, required = false, description = "the total memory of the service offering in MB")
+ @Parameter(name = ApiConstants.MEMORY, type = CommandType.INTEGER, required = false, description = "The total memory of the service offering in MB")
private Integer memory;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the service offering")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "The name of the service offering")
private String serviceOfferingName;
- @Parameter(name = ApiConstants.OFFER_HA, type = CommandType.BOOLEAN, description = "the HA for the service offering")
+ @Parameter(name = ApiConstants.OFFER_HA, type = CommandType.BOOLEAN, description = "The HA for the service offering")
private Boolean offerHa;
- @Parameter(name = ApiConstants.LIMIT_CPU_USE, type = CommandType.BOOLEAN, description = "restrict the CPU usage to committed service offering")
+ @Parameter(name = ApiConstants.LIMIT_CPU_USE, type = CommandType.BOOLEAN, description = "Restrict the CPU usage to committed service offering")
private Boolean limitCpuUse;
@Parameter(name = ApiConstants.IS_VOLATILE,
type = CommandType.BOOLEAN,
- description = "true if the virtual machine needs to be volatile so that on every reboot of VM, original root disk is dettached then destroyed and a fresh root disk is created and attached to VM")
+ description = "True if the Instance needs to be volatile so that on every reboot, the original root disk is detached, then destroyed and a fresh root disk is created and attached to the Instance")
private Boolean isVolatile;
- @Parameter(name = ApiConstants.STORAGE_TYPE, type = CommandType.STRING, description = "the storage type of the service offering. Values are local and shared.")
+ @Parameter(name = ApiConstants.STORAGE_TYPE, type = CommandType.STRING, description = "The storage type of the service offering. Values are local and shared.")
private String storageType;
- @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "the tags for this service offering.")
+ @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "The tags for this service offering.")
private String tags;
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.LIST,
collectionType = CommandType.UUID,
entityType = DomainResponse.class,
- description = "the ID of the containing domain(s), null for public offerings")
+ description = "The ID of the containing domain(s), null for public offerings")
private List domainIds;
@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.LIST,
collectionType = CommandType.UUID,
entityType = ZoneResponse.class,
- description = "the ID of the containing zone(s), null for public offerings",
+ description = "The ID of the containing zone(s), null for public offerings",
since = "4.13")
private List zoneIds;
- @Parameter(name = ApiConstants.HOST_TAGS, type = CommandType.STRING, description = "the host tag for this service offering.")
+ @Parameter(name = ApiConstants.HOST_TAGS, type = CommandType.STRING, description = "The host tag for this service offering.")
private String hostTag;
- @Parameter(name = ApiConstants.IS_SYSTEM_OFFERING, type = CommandType.BOOLEAN, description = "is this a system vm offering")
+ @Parameter(name = ApiConstants.IS_SYSTEM_OFFERING, type = CommandType.BOOLEAN, description = "Is this a system vm offering")
private Boolean isSystem;
@Parameter(name = ApiConstants.SYSTEM_VM_TYPE,
type = CommandType.STRING,
- description = "the system VM type. Possible types are \"domainrouter\", \"consoleproxy\" and \"secondarystoragevm\".")
+ description = "The system VM type. Possible types are \"domainrouter\", \"consoleproxy\" and \"secondarystoragevm\".")
private String systemVmType;
@Parameter(name = ApiConstants.NETWORKRATE,
type = CommandType.INTEGER,
- description = "data transfer rate in megabits per second allowed. Supported only for non-System offering and system offerings having \"domainrouter\" systemvmtype")
+ description = "Data transfer rate in megabits per second allowed. Supported only for non-System offering and system offerings having \"domainrouter\" systemvmtype")
private Integer networkRate;
@Parameter(name = ApiConstants.DEPLOYMENT_PLANNER,
type = CommandType.STRING,
- description = "The deployment planner heuristics used to deploy a VM of this offering. If null, value of global config vm.deployment.planner is used")
+ description = "The deployment planner heuristics used to deploy an Instance of this offering. If null, value of global config vm.deployment.planner is used")
private String deploymentPlanner;
- @Parameter(name = ApiConstants.SERVICE_OFFERING_DETAILS, type = CommandType.MAP, description = "details for planner, used to store specific parameters")
+ @Parameter(name = ApiConstants.SERVICE_OFFERING_DETAILS, type = CommandType.MAP, description = "Details for planner, used to store specific parameters")
private Map details;
- @Parameter(name = ApiConstants.ROOT_DISK_SIZE, type = CommandType.LONG, since = "4.15", description = "the Root disk size in GB.")
+ @Parameter(name = ApiConstants.ROOT_DISK_SIZE, type = CommandType.LONG, since = "4.15", description = "The Root disk size in GB.")
private Long rootDiskSize;
- @Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, required = false, description = "bytes read rate of the disk offering")
+ @Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, required = false, description = "Bytes read rate of the disk offering")
private Long bytesReadRate;
- @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "burst bytes read rate of the disk offering")
+ @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "Burst bytes read rate of the disk offering")
private Long bytesReadRateMax;
- @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+ @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "Length (in seconds) of the burst")
private Long bytesReadRateMaxLength;
- @Parameter(name = ApiConstants.BYTES_WRITE_RATE, type = CommandType.LONG, required = false, description = "bytes write rate of the disk offering")
+ @Parameter(name = ApiConstants.BYTES_WRITE_RATE, type = CommandType.LONG, required = false, description = "Bytes write rate of the disk offering")
private Long bytesWriteRate;
- @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "burst bytes write rate of the disk offering")
+ @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "Burst bytes write rate of the disk offering")
private Long bytesWriteRateMax;
- @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+ @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "Length (in seconds) of the burst")
private Long bytesWriteRateMaxLength;
- @Parameter(name = ApiConstants.IOPS_READ_RATE, type = CommandType.LONG, required = false, description = "io requests read rate of the disk offering")
+ @Parameter(name = ApiConstants.IOPS_READ_RATE, type = CommandType.LONG, required = false, description = "I/O requests read rate of the disk offering")
private Long iopsReadRate;
- @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "burst requests read rate of the disk offering")
+ @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "Burst requests read rate of the disk offering")
private Long iopsReadRateMax;
- @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+ @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "Length (in seconds) of the burst")
private Long iopsReadRateMaxLength;
- @Parameter(name = ApiConstants.IOPS_WRITE_RATE, type = CommandType.LONG, required = false, description = "io requests write rate of the disk offering")
+ @Parameter(name = ApiConstants.IOPS_WRITE_RATE, type = CommandType.LONG, required = false, description = "I/O requests write rate of the disk offering")
private Long iopsWriteRate;
- @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "burst io requests write rate of the disk offering")
+ @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "Burst io requests write rate of the disk offering")
private Long iopsWriteRateMax;
- @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+ @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "Length (in seconds) of the burst")
private Long iopsWriteRateMaxLength;
- @Parameter(name = ApiConstants.CUSTOMIZED_IOPS, type = CommandType.BOOLEAN, required = false, description = "whether compute offering iops is custom or not", since = "4.4")
+ @Parameter(name = ApiConstants.CUSTOMIZED_IOPS, type = CommandType.BOOLEAN, required = false, description = "Whether compute offering iops is custom or not", since = "4.4")
private Boolean customizedIops;
- @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "min iops of the compute offering", since = "4.4")
+ @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "Min iops of the compute offering", since = "4.4")
private Long minIops;
- @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "max iops of the compute offering", since = "4.4")
+ @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "Max iops of the compute offering", since = "4.4")
private Long maxIops;
@Parameter(name = ApiConstants.HYPERVISOR_SNAPSHOT_RESERVE,
type = CommandType.INTEGER,
required = false,
- description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)",
+ description = "Hypervisor Snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)",
since = "4.4")
private Integer hypervisorSnapshotReserve;
@Parameter(name = ApiConstants.CACHE_MODE,
type = CommandType.STRING,
- required = false,
- description = "the cache mode to use for this disk offering. none, writeback, writethrough or hypervisor default. If the hypervisor default cache mode is used on other hypervisors than KVM, it will fall back to none cache mode",
+ description = "The cache mode to use for this disk offering. none, writeback, writethrough or hypervisor default. If the hypervisor default cache mode is used on other hypervisors than KVM, it will fall back to none cache mode",
since = "4.14")
private String cacheMode;
@@ -229,14 +228,14 @@ public class CreateServiceOfferingCmd extends BaseCmd {
private Long storagePolicy;
@Parameter(name = ApiConstants.DYNAMIC_SCALING_ENABLED, type = CommandType.BOOLEAN, since = "4.16",
- description = "true if virtual machine needs to be dynamically scalable of cpu or memory")
+ description = "True if Instance needs to be dynamically scalable of cpu or memory")
protected Boolean isDynamicScalingEnabled;
@Parameter(name = ApiConstants.DISK_OFFERING_ID,
required = false,
type = CommandType.UUID,
entityType = DiskOfferingResponse.class,
- description = "the ID of the disk offering to which service offering should be mapped",
+ description = "The ID of the disk offering to which service offering should be mapped",
since = "4.17")
private Long diskOfferingId;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/DeleteServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/DeleteServiceOfferingCmd.java
index 19203289d104..d08b4f144c26 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/DeleteServiceOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/DeleteServiceOfferingCmd.java
@@ -40,7 +40,7 @@ public class DeleteServiceOfferingCmd extends BaseCmd {
type = CommandType.UUID,
entityType = ServiceOfferingResponse.class,
required = true,
- description = "the ID of the service offering")
+ description = "The ID of the service offering")
private Long id;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/IsAccountAllowedToCreateOfferingsWithTagsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/IsAccountAllowedToCreateOfferingsWithTagsCmd.java
index fcd6b03d3e59..4b1cd2ff7255 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/IsAccountAllowedToCreateOfferingsWithTagsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/IsAccountAllowedToCreateOfferingsWithTagsCmd.java
@@ -26,7 +26,8 @@
import org.apache.cloudstack.api.response.IsAccountAllowedToCreateOfferingsWithTagsResponse;
@APICommand(name = "isAccountAllowedToCreateOfferingsWithTags", description = "Return true if the specified account is allowed to create offerings with tags.",
- responseObject = IsAccountAllowedToCreateOfferingsWithTagsResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+ responseObject = IsAccountAllowedToCreateOfferingsWithTagsResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+ httpMethod = "GET")
public class IsAccountAllowedToCreateOfferingsWithTagsCmd extends BaseCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "Account UUID", required = true)
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java
index 370453804cfc..4d48327eeb77 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java
@@ -16,7 +16,6 @@
// under the License.
package org.apache.cloudstack.api.command.admin.offering;
-import java.util.ArrayList;
import java.util.List;
import com.cloud.offering.DiskOffering.State;
@@ -27,19 +26,18 @@
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.offering.DomainAndZoneIdResolver;
import org.apache.cloudstack.api.response.DiskOfferingResponse;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
-import com.cloud.dc.DataCenter;
-import com.cloud.domain.Domain;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.offering.DiskOffering;
import com.cloud.user.Account;
@APICommand(name = "updateDiskOffering", description = "Updates a disk offering.", responseObject = DiskOfferingResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class UpdateDiskOfferingCmd extends BaseCmd {
+public class UpdateDiskOfferingCmd extends BaseCmd implements DomainAndZoneIdResolver {
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
@@ -47,80 +45,81 @@ public class UpdateDiskOfferingCmd extends BaseCmd {
@Parameter(name = ApiConstants.DISPLAY_TEXT,
type = CommandType.STRING,
- description = "updates alternate display text of the disk offering with this value",
+ description = "Updates alternate display text of the disk offering with this value",
length = 4096)
private String displayText;
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DiskOfferingResponse.class, required = true, description = "ID of the disk offering")
private Long id;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "updates name of the disk offering with this value")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Updates name of the disk offering with this value")
private String diskOfferingName;
- @Parameter(name = ApiConstants.SORT_KEY, type = CommandType.INTEGER, description = "sort key of the disk offering, integer")
+ @Parameter(name = ApiConstants.SORT_KEY, type = CommandType.INTEGER, description = "Sort key of the disk offering, integer")
private Integer sortKey;
@Parameter(name = ApiConstants.DISPLAY_OFFERING,
type = CommandType.BOOLEAN,
- description = "an optional field, whether to display the offering to the end user or not.")
+ description = "An optional field, whether to display the offering to the end user or not.")
private Boolean displayOffering;
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.STRING,
- description = "the ID of the containing domain(s) as comma separated string, public for public offerings",
+ description = "The ID of the containing domain(s) as comma separated string, public for public offerings",
since = "4.13",
length = 4096)
private String domainIds;
@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.STRING,
- description = "the ID of the containing zone(s) as comma separated string, all for all zones offerings",
+ description = "The ID of the containing zone(s) as comma separated string, all for all zones offerings",
+ length = 4096,
since = "4.13")
private String zoneIds;
@Parameter(name = ApiConstants.TAGS,
type = CommandType.STRING,
- description = "comma-separated list of tags for the disk offering, tags should match with existing storage pool tags",
+ description = "Comma-separated list of tags for the disk offering, tags should match with existing storage pool tags",
since = "4.15")
private String tags;
- @Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, description = "bytes read rate of the disk offering", since = "4.15")
+ @Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, description = "Bytes read rate of the disk offering", since = "4.15")
private Long bytesReadRate;
- @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX, type = CommandType.LONG, description = "burst bytes read rate of the disk offering", since = "4.15")
+ @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX, type = CommandType.LONG, description = "Burst bytes read rate of the disk offering", since = "4.15")
private Long bytesReadRateMax;
- @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX_LENGTH, type = CommandType.LONG, description = "length (in seconds) of the burst", since = "4.15")
+ @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX_LENGTH, type = CommandType.LONG, description = "Length (in seconds) of the burst", since = "4.15")
private Long bytesReadRateMaxLength;
- @Parameter(name = ApiConstants.BYTES_WRITE_RATE, type = CommandType.LONG, description = "bytes write rate of the disk offering", since = "4.15")
+ @Parameter(name = ApiConstants.BYTES_WRITE_RATE, type = CommandType.LONG, description = "Bytes write rate of the disk offering", since = "4.15")
private Long bytesWriteRate;
- @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX, type = CommandType.LONG, description = "burst bytes write rate of the disk offering", since = "4.15")
+ @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX, type = CommandType.LONG, description = "Burst bytes write rate of the disk offering", since = "4.15")
private Long bytesWriteRateMax;
- @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, description = "length (in seconds) of the burst", since = "4.15")
+ @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, description = "Length (in seconds) of the burst", since = "4.15")
private Long bytesWriteRateMaxLength;
- @Parameter(name = ApiConstants.IOPS_READ_RATE, type = CommandType.LONG, description = "io requests read rate of the disk offering", since = "4.15")
+ @Parameter(name = ApiConstants.IOPS_READ_RATE, type = CommandType.LONG, description = "I/O requests read rate of the disk offering", since = "4.15")
private Long iopsReadRate;
- @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX, type = CommandType.LONG, description = "burst requests read rate of the disk offering", since = "4.15")
+ @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX, type = CommandType.LONG, description = "Burst requests read rate of the disk offering", since = "4.15")
private Long iopsReadRateMax;
- @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX_LENGTH, type = CommandType.LONG, description = "length (in seconds) of the burst", since = "4.15")
+ @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX_LENGTH, type = CommandType.LONG, description = "Length (in seconds) of the burst", since = "4.15")
private Long iopsReadRateMaxLength;
- @Parameter(name = ApiConstants.IOPS_WRITE_RATE, type = CommandType.LONG, description = "io requests write rate of the disk offering", since = "4.15")
+ @Parameter(name = ApiConstants.IOPS_WRITE_RATE, type = CommandType.LONG, description = "I/O requests write rate of the disk offering", since = "4.15")
private Long iopsWriteRate;
- @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX, type = CommandType.LONG, description = "burst io requests write rate of the disk offering", since = "4.15")
+ @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX, type = CommandType.LONG, description = "Burst io requests write rate of the disk offering", since = "4.15")
private Long iopsWriteRateMax;
- @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, description = "length (in seconds) of the burst", since = "4.15")
+ @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, description = "Length (in seconds) of the burst", since = "4.15")
private Long iopsWriteRateMaxLength;
- @Parameter(name = ApiConstants.CACHE_MODE, type = CommandType.STRING, description = "the cache mode to use for this disk offering", since = "4.15")
+ @Parameter(name = ApiConstants.CACHE_MODE, type = CommandType.STRING, description = "The cache mode to use for this disk offering", since = "4.15")
private String cacheMode;
@Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "state of the disk offering")
@@ -151,63 +150,11 @@ public Boolean getDisplayOffering() {
}
public List getDomainIds() {
- List validDomainIds = new ArrayList<>();
- if (StringUtils.isNotEmpty(domainIds)) {
- if (domainIds.contains(",")) {
- String[] domains = domainIds.split(",");
- for (String domain : domains) {
- Domain validDomain = _entityMgr.findByUuid(Domain.class, domain.trim());
- if (validDomain != null) {
- validDomainIds.add(validDomain.getId());
- } else {
- throw new InvalidParameterValueException("Failed to create disk offering because invalid domain has been specified.");
- }
- }
- } else {
- domainIds = domainIds.trim();
- if (!domainIds.matches("public")) {
- Domain validDomain = _entityMgr.findByUuid(Domain.class, domainIds.trim());
- if (validDomain != null) {
- validDomainIds.add(validDomain.getId());
- } else {
- throw new InvalidParameterValueException("Failed to create disk offering because invalid domain has been specified.");
- }
- }
- }
- } else {
- validDomainIds.addAll(_configService.getDiskOfferingDomains(id));
- }
- return validDomainIds;
+ return resolveDomainIds(domainIds, id, _configService::getDiskOfferingDomains, "disk offering");
}
public List getZoneIds() {
- List validZoneIds = new ArrayList<>();
- if (StringUtils.isNotEmpty(zoneIds)) {
- if (zoneIds.contains(",")) {
- String[] zones = zoneIds.split(",");
- for (String zone : zones) {
- DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zone.trim());
- if (validZone != null) {
- validZoneIds.add(validZone.getId());
- } else {
- throw new InvalidParameterValueException("Failed to create disk offering because invalid zone has been specified.");
- }
- }
- } else {
- zoneIds = zoneIds.trim();
- if (!zoneIds.matches("all")) {
- DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zoneIds.trim());
- if (validZone != null) {
- validZoneIds.add(validZone.getId());
- } else {
- throw new InvalidParameterValueException("Failed to create disk offering because invalid zone has been specified.");
- }
- }
- }
- } else {
- validZoneIds.addAll(_configService.getDiskOfferingZones(id));
- }
- return validZoneIds;
+ return resolveZoneIds(zoneIds, id, _configService::getDiskOfferingZones, "disk offering");
}
public String getTags() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java
index 9d973dfc524b..8e37499c95ed 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java
@@ -16,7 +16,6 @@
// under the License.
package org.apache.cloudstack.api.command.admin.offering;
-import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -28,19 +27,18 @@
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.offering.DomainAndZoneIdResolver;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
-import com.cloud.dc.DataCenter;
-import com.cloud.domain.Domain;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.offering.ServiceOffering;
import com.cloud.user.Account;
@APICommand(name = "updateServiceOffering", description = "Updates a service offering.", responseObject = ServiceOfferingResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class UpdateServiceOfferingCmd extends BaseCmd {
+public class UpdateServiceOfferingCmd extends BaseCmd implements DomainAndZoneIdResolver {
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
@@ -49,39 +47,40 @@ public class UpdateServiceOfferingCmd extends BaseCmd {
type = CommandType.UUID,
entityType = ServiceOfferingResponse.class,
required = true,
- description = "the ID of the service offering to be updated")
+ description = "The ID of the service offering to be updated")
private Long id;
- @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "the display text of the service offering to be updated")
+ @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "The display text of the service offering to be updated")
private String displayText;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the service offering to be updated")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "The name of the service offering to be updated")
private String serviceOfferingName;
- @Parameter(name = ApiConstants.SORT_KEY, type = CommandType.INTEGER, description = "sort key of the service offering, integer")
+ @Parameter(name = ApiConstants.SORT_KEY, type = CommandType.INTEGER, description = "Sort key of the service offering, integer")
private Integer sortKey;
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.STRING,
- description = "the ID of the containing domain(s) as comma separated string, public for public offerings",
+ description = "The ID of the containing domain(s) as comma separated string, public for public offerings",
length = 4096)
private String domainIds;
@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.STRING,
- description = "the ID of the containing zone(s) as comma separated string, all for all zones offerings",
+ description = "The ID of the containing zone(s) as comma separated string, all for all zones offerings",
+ length = 4096,
since = "4.13")
private String zoneIds;
@Parameter(name = ApiConstants.STORAGE_TAGS,
type = CommandType.STRING,
- description = "comma-separated list of tags for the service offering, tags should match with existing storage pool tags",
+ description = "Comma-separated list of tags for the service offering, tags should match with existing storage pool tags",
since = "4.16")
private String storageTags;
@Parameter(name = ApiConstants.HOST_TAGS,
type = CommandType.STRING,
- description = "the host tag for this service offering.",
+ description = "The host tag for this service offering.",
since = "4.16")
private String hostTags;
@@ -130,63 +129,11 @@ public Integer getSortKey() {
}
public List getDomainIds() {
- List validDomainIds = new ArrayList<>();
- if (StringUtils.isNotEmpty(domainIds)) {
- if (domainIds.contains(",")) {
- String[] domains = domainIds.split(",");
- for (String domain : domains) {
- Domain validDomain = _entityMgr.findByUuid(Domain.class, domain.trim());
- if (validDomain != null) {
- validDomainIds.add(validDomain.getId());
- } else {
- throw new InvalidParameterValueException("Failed to create service offering because invalid domain has been specified.");
- }
- }
- } else {
- domainIds = domainIds.trim();
- if (!domainIds.matches("public")) {
- Domain validDomain = _entityMgr.findByUuid(Domain.class, domainIds.trim());
- if (validDomain != null) {
- validDomainIds.add(validDomain.getId());
- } else {
- throw new InvalidParameterValueException("Failed to create service offering because invalid domain has been specified.");
- }
- }
- }
- } else {
- validDomainIds.addAll(_configService.getServiceOfferingDomains(id));
- }
- return validDomainIds;
+ return resolveDomainIds(domainIds, id, _configService::getServiceOfferingDomains, "service offering");
}
public List getZoneIds() {
- List validZoneIds = new ArrayList<>();
- if (StringUtils.isNotEmpty(zoneIds)) {
- if (zoneIds.contains(",")) {
- String[] zones = zoneIds.split(",");
- for (String zone : zones) {
- DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zone.trim());
- if (validZone != null) {
- validZoneIds.add(validZone.getId());
- } else {
- throw new InvalidParameterValueException("Failed to create service offering because invalid zone has been specified.");
- }
- }
- } else {
- zoneIds = zoneIds.trim();
- if (!zoneIds.matches("all")) {
- DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zoneIds.trim());
- if (validZone != null) {
- validZoneIds.add(validZone.getId());
- } else {
- throw new InvalidParameterValueException("Failed to create service offering because invalid zone has been specified.");
- }
- }
- }
- } else {
- validZoneIds.addAll(_configService.getServiceOfferingZones(id));
- }
- return validZoneIds;
+ return resolveZoneIds(zoneIds, id, _configService::getServiceOfferingZones, "service offering");
}
public String getStorageTags() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ChangeOutOfBandManagementPasswordCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ChangeOutOfBandManagementPasswordCmd.java
index e2c31d6cf072..b9a729bc1b77 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ChangeOutOfBandManagementPasswordCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ChangeOutOfBandManagementPasswordCmd.java
@@ -53,10 +53,10 @@ public class ChangeOutOfBandManagementPasswordCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, required = true,
- validations = {ApiArgValidator.PositiveNumber}, description = "the ID of the host")
+ validations = {ApiArgValidator.PositiveNumber}, description = "The ID of the host")
private Long hostId;
- @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "the new host management interface password of maximum length 16, if none is provided a random password would be used")
+ @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The new host management interface password of maximum length 16, if none is provided a random password would be used")
private String password;
/////////////////////////////////////////////////////
@@ -70,7 +70,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to find host by ID: " + getHostId());
}
- CallContext.current().setEventDetails("Host Id: " + host.getId() + " Password: " + getPassword().charAt(0) + "****");
+ CallContext.current().setEventDetails("Host ID: " + host.getUuid() + " Password: " + getPassword().charAt(0) + "****");
CallContext.current().putContextParameter(Host.class, host.getUuid());
final OutOfBandManagementResponse response = outOfBandManagementService.changePassword(host, getPassword());
@@ -101,7 +101,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "change out-of-band management password for host: " + getHostId();
+ return "Changing out-of-band management password for host with ID: " + getResourceUuid(ApiConstants.HOST_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ConfigureOutOfBandManagementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ConfigureOutOfBandManagementCmd.java
index 157d3c627db5..4052539a51d7 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ConfigureOutOfBandManagementCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ConfigureOutOfBandManagementCmd.java
@@ -54,22 +54,22 @@ public class ConfigureOutOfBandManagementCmd extends BaseCmd {
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, required = true,
- validations = {ApiArgValidator.PositiveNumber}, description = "the ID of the host")
+ validations = {ApiArgValidator.PositiveNumber}, description = "The ID of the host")
private Long hostId;
- @Parameter(name = ApiConstants.DRIVER, type = CommandType.STRING, required = true, description = "the host management interface driver, for example: ipmitool")
+ @Parameter(name = ApiConstants.DRIVER, type = CommandType.STRING, required = true, description = "The host management interface driver, for example: ipmitool")
private String driver;
- @Parameter(name = ApiConstants.ADDRESS, type = CommandType.STRING, required = true, description = "the host management interface IP address")
+ @Parameter(name = ApiConstants.ADDRESS, type = CommandType.STRING, required = true, description = "The host management interface IP address")
private String address;
- @Parameter(name = ApiConstants.PORT, type = CommandType.STRING, required = true, description = "the host management interface port")
+ @Parameter(name = ApiConstants.PORT, type = CommandType.STRING, required = true, description = "The host management interface port")
private String port;
- @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "the host management interface user")
+ @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "The host management interface user")
private String username;
- @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "the host management interface password")
+ @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "The host management interface password")
private String password;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForClusterCmd.java
index 445e7b92665c..5b0f3a802071 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForClusterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForClusterCmd.java
@@ -54,7 +54,7 @@ public class DisableOutOfBandManagementForClusterCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.CLUSTER_ID, type = BaseCmd.CommandType.UUID, required = true, entityType = ClusterResponse.class,
- validations = {ApiArgValidator.PositiveNumber}, description = "the ID of the cluster")
+ validations = {ApiArgValidator.PositiveNumber}, description = "The ID of the cluster")
private Long clusterId;
/////////////////////////////////////////////////////
@@ -70,7 +70,7 @@ final public void execute() throws ResourceUnavailableException, InsufficientCap
OutOfBandManagementResponse response = outOfBandManagementService.disableOutOfBandManagement(cluster);
- CallContext.current().setEventDetails("Cluster Id:" + cluster.getId() + " out-of-band management enabled: false");
+ CallContext.current().setEventDetails("Cluster ID:" + cluster.getUuid() + " out-of-band management enabled: false");
CallContext.current().putContextParameter(Cluster.class, cluster.getUuid());
response.setResponseName(getCommandName());
@@ -93,7 +93,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "disable out-of-band management password for cluster: " + getClusterId();
+ return "Disabling out-of-band management password for cluster with ID: " + getResourceUuid(ApiConstants.CLUSTER_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForHostCmd.java
index 7e4444e93fbd..c70622134531 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForHostCmd.java
@@ -54,7 +54,7 @@ public class DisableOutOfBandManagementForHostCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.HOST_ID, type = BaseCmd.CommandType.UUID, required = true, entityType = HostResponse.class,
- validations = {ApiArgValidator.PositiveNumber}, description = "the ID of the host")
+ validations = {ApiArgValidator.PositiveNumber}, description = "The ID of the host")
private Long hostId;
/////////////////////////////////////////////////////
@@ -70,7 +70,7 @@ final public void execute() throws ResourceUnavailableException, InsufficientCap
OutOfBandManagementResponse response = outOfBandManagementService.disableOutOfBandManagement(host);
- CallContext.current().setEventDetails("Host Id:" + host.getId() + " out-of-band management enabled: false");
+ CallContext.current().setEventDetails("Host ID:" + host.getUuid() + " out-of-band management enabled: false");
CallContext.current().putContextParameter(Host.class, host.getUuid());
response.setId(host.getUuid());
@@ -94,7 +94,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "disable out-of-band management password for host: " + getHostId();
+ return "Disabling out-of-band management password for host with ID: " + getResourceUuid(ApiConstants.HOST_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForZoneCmd.java
index 2028f8fc2a07..2f2750580516 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForZoneCmd.java
@@ -54,7 +54,7 @@ public class DisableOutOfBandManagementForZoneCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, required = true, entityType = ZoneResponse.class,
- validations = {ApiArgValidator.PositiveNumber}, description = "the ID of the zone")
+ validations = {ApiArgValidator.PositiveNumber}, description = "The ID of the zone")
private Long zoneId;
/////////////////////////////////////////////////////
@@ -70,7 +70,7 @@ final public void execute() throws ResourceUnavailableException, InsufficientCap
OutOfBandManagementResponse response = outOfBandManagementService.disableOutOfBandManagement(zone);
- CallContext.current().setEventDetails("Zone Id:" + zone.getId() + " out-of-band management enabled: false");
+ CallContext.current().setEventDetails("Zone ID:" + zone.getUuid() + " out-of-band management enabled: false");
CallContext.current().putContextParameter(DataCenter.class, zone.getUuid());
response.setResponseName(getCommandName());
@@ -93,7 +93,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "disable out-of-band management password for zone: " + getZoneId();
+ return "Disabling out-of-band management password for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForClusterCmd.java
index 549743b31728..4419ed18ee59 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForClusterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForClusterCmd.java
@@ -54,7 +54,7 @@ public class EnableOutOfBandManagementForClusterCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.CLUSTER_ID, type = BaseCmd.CommandType.UUID, required = true, entityType = ClusterResponse.class,
- validations = {ApiArgValidator.PositiveNumber}, description = "the ID of the cluster")
+ validations = {ApiArgValidator.PositiveNumber}, description = "The ID of the cluster")
private Long clusterId;
/////////////////////////////////////////////////////
@@ -70,7 +70,7 @@ final public void execute() throws ResourceUnavailableException, InsufficientCap
OutOfBandManagementResponse response = outOfBandManagementService.enableOutOfBandManagement(cluster);
- CallContext.current().setEventDetails("Cluster Id:" + cluster.getId() + " out-of-band management enabled: true");
+ CallContext.current().setEventDetails("Cluster ID:" + cluster.getUuid() + " out-of-band management enabled: true");
CallContext.current().putContextParameter(Cluster.class, cluster.getUuid());
response.setResponseName(getCommandName());
@@ -93,7 +93,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "enable out-of-band management password for cluster: " + getClusterId();
+ return "Enabling out-of-band management password for cluster with ID: " + getResourceUuid(ApiConstants.CLUSTER_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForHostCmd.java
index 834181a5e1c5..b3f2e8aaf821 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForHostCmd.java
@@ -54,7 +54,7 @@ public class EnableOutOfBandManagementForHostCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.HOST_ID, type = BaseCmd.CommandType.UUID, required = true, entityType = HostResponse.class,
- validations = {ApiArgValidator.PositiveNumber}, description = "the ID of the host")
+ validations = {ApiArgValidator.PositiveNumber}, description = "The ID of the host")
private Long hostId;
/////////////////////////////////////////////////////
@@ -70,7 +70,7 @@ final public void execute() throws ResourceUnavailableException, InsufficientCap
OutOfBandManagementResponse response = outOfBandManagementService.enableOutOfBandManagement(host);
- CallContext.current().setEventDetails("Host Id:" + host.getId() + " out-of-band management enabled: true");
+ CallContext.current().setEventDetails("Host ID:" + host.getUuid() + " out-of-band management enabled: true");
CallContext.current().putContextParameter(Host.class, host.getUuid());
response.setId(host.getUuid());
@@ -94,7 +94,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "enable out-of-band management password for host: " + getHostId();
+ return "Enabling out-of-band management password for host with ID: " + getResourceUuid(ApiConstants.HOST_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForZoneCmd.java
index de4c4d801de1..8f6eb2dc3500 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForZoneCmd.java
@@ -54,7 +54,7 @@ public class EnableOutOfBandManagementForZoneCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, required = true, entityType = ZoneResponse.class,
- validations = {ApiArgValidator.PositiveNumber}, description = "the ID of the zone")
+ validations = {ApiArgValidator.PositiveNumber}, description = "The ID of the zone")
private Long zoneId;
/////////////////////////////////////////////////////
@@ -70,7 +70,7 @@ final public void execute() throws ResourceUnavailableException, InsufficientCap
OutOfBandManagementResponse response = outOfBandManagementService.enableOutOfBandManagement(zone);
- CallContext.current().setEventDetails("Zone Id:" + zone.getId() + " out-of-band management enabled: true");
+ CallContext.current().setEventDetails("Zone ID:" + zone.getUuid() + " out-of-band management enabled: true");
CallContext.current().putContextParameter(DataCenter.class, zone.getUuid());
response.setResponseName(getCommandName());
@@ -93,7 +93,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "enable out-of-band management password for zone: " + getZoneId();
+ return "Enabling out-of-band management password for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/IssueOutOfBandManagementPowerActionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/IssueOutOfBandManagementPowerActionCmd.java
index 97a813c9d476..bba3fee6ceca 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/IssueOutOfBandManagementPowerActionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/IssueOutOfBandManagementPowerActionCmd.java
@@ -53,14 +53,14 @@ public class IssueOutOfBandManagementPowerActionCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, required = true,
- validations = {ApiArgValidator.PositiveNumber}, description = "the ID of the host")
+ validations = {ApiArgValidator.PositiveNumber}, description = "The ID of the host")
private Long hostId;
- @Parameter(name = ApiConstants.TIMEOUT, type = CommandType.LONG, description = "optional operation timeout in seconds that overrides the global or cluster-level out-of-band management timeout setting")
+ @Parameter(name = ApiConstants.TIMEOUT, type = CommandType.LONG, description = "Optional operation timeout in seconds that overrides the global or cluster-level out-of-band management timeout setting")
private Long actionTimeout;
@Parameter(name = ApiConstants.ACTION, type = CommandType.STRING, required = true,
- description = "out-of-band management power actions, valid actions are: ON, OFF, CYCLE, RESET, SOFT, STATUS")
+ description = "Out-of-band management power actions, valid actions are: ON, OFF, CYCLE, RESET, SOFT, STATUS")
private String powerAction;
/////////////////////////////////////////////////////
@@ -75,7 +75,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
}
final PowerOperation powerOperation = PowerOperation.valueOf(getPowerAction());
- CallContext.current().setEventDetails("Host Id: " + host.getId() + " Action: " + powerOperation.toString());
+ CallContext.current().setEventDetails("Host ID: " + host.getUuid() + " Action: " + powerOperation.toString());
CallContext.current().putContextParameter(Host.class, host.getUuid());
final OutOfBandManagementResponse response = outOfBandManagementService.executePowerOperation(host, powerOperation, getActionTimeout());
@@ -107,7 +107,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "issue out-out-band management power action: " + getPowerAction() + " on host: " + getHostId();
+ return "Issuing out-out-band management power action: " + getPowerAction() + " to host: " + getResourceUuid(ApiConstants.HOST_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/CreatePodCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/CreatePodCmd.java
index 36ad00e6e4ab..6a178b64d876 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/CreatePodCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/CreatePodCmd.java
@@ -40,26 +40,26 @@ public class CreatePodCmd extends BaseCmd {
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the Pod")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "The name of the Pod")
private String podName;
@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.UUID,
entityType = ZoneResponse.class,
required = true,
- description = "the Zone ID in which the Pod will be created")
+ description = "The Zone ID in which the Pod will be created")
private Long zoneId;
- @Parameter(name = ApiConstants.START_IP, type = CommandType.STRING, description = "the starting IP address for the Pod")
+ @Parameter(name = ApiConstants.START_IP, type = CommandType.STRING, description = "The starting IP address for the Pod")
private String startIp;
- @Parameter(name = ApiConstants.END_IP, type = CommandType.STRING, description = "the ending IP address for the Pod")
+ @Parameter(name = ApiConstants.END_IP, type = CommandType.STRING, description = "The ending IP address for the Pod")
private String endIp;
- @Parameter(name = ApiConstants.NETMASK, type = CommandType.STRING, description = "the netmask for the Pod")
+ @Parameter(name = ApiConstants.NETMASK, type = CommandType.STRING, description = "The netmask for the Pod")
private String netmask;
- @Parameter(name = ApiConstants.GATEWAY, type = CommandType.STRING, description = "the gateway for the Pod")
+ @Parameter(name = ApiConstants.GATEWAY, type = CommandType.STRING, description = "The gateway for the Pod")
private String gateway;
@Parameter(name = ApiConstants.ALLOCATION_STATE, type = CommandType.STRING, description = "Allocation state of this Pod for allocation of new resources")
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/DeletePodCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/DeletePodCmd.java
index c1de800d745b..953fcc91fa71 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/DeletePodCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/DeletePodCmd.java
@@ -38,7 +38,7 @@ public class DeletePodCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = PodResponse.class, required = true, description = "the ID of the Pod")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = PodResponse.class, required = true, description = "The ID of the Pod")
private Long id;
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java
index 264e5263c4d7..a19bc3caf8b5 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java
@@ -40,19 +40,19 @@ public class ListPodsByCmd extends BaseListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = PodResponse.class, description = "list Pods by ID")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = PodResponse.class, description = "List Pods by ID")
private Long id;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "list Pods by name")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "List Pods by name")
private String podName;
- @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "list Pods by Zone ID")
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "List Pods by Zone ID")
private Long zoneId;
- @Parameter(name = ApiConstants.ALLOCATION_STATE, type = CommandType.STRING, description = "list pods by allocation state")
+ @Parameter(name = ApiConstants.ALLOCATION_STATE, type = CommandType.STRING, description = "List pods by allocation state")
private String allocationState;
- @Parameter(name = ApiConstants.SHOW_CAPACITIES, type = CommandType.BOOLEAN, description = "flag to display the capacity of the pods")
+ @Parameter(name = ApiConstants.SHOW_CAPACITIES, type = CommandType.BOOLEAN, description = "Flag to display the capacity of the pods")
private Boolean showCapacities;
@Parameter(name = ApiConstants.STORAGE_ACCESS_GROUP, type = CommandType.STRING,
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/UpdatePodCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/UpdatePodCmd.java
index 7dae6f4c7cf0..24a549c623ad 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/UpdatePodCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/UpdatePodCmd.java
@@ -38,22 +38,22 @@ public class UpdatePodCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = PodResponse.class, required = true, description = "the ID of the Pod")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = PodResponse.class, required = true, description = "The ID of the Pod")
private Long id;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the Pod")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "The name of the Pod")
private String podName;
- @Parameter(name = ApiConstants.START_IP, type = CommandType.STRING, description = "the starting IP address for the Pod")
+ @Parameter(name = ApiConstants.START_IP, type = CommandType.STRING, description = "The starting IP address for the Pod")
private String startIp;
- @Parameter(name = ApiConstants.END_IP, type = CommandType.STRING, description = "the ending IP address for the Pod")
+ @Parameter(name = ApiConstants.END_IP, type = CommandType.STRING, description = "The ending IP address for the Pod")
private String endIp;
- @Parameter(name = ApiConstants.NETMASK, type = CommandType.STRING, description = "the netmask of the Pod")
+ @Parameter(name = ApiConstants.NETMASK, type = CommandType.STRING, description = "The netmask of the Pod")
private String netmask;
- @Parameter(name = ApiConstants.GATEWAY, type = CommandType.STRING, description = "the gateway for the Pod")
+ @Parameter(name = ApiConstants.GATEWAY, type = CommandType.STRING, description = "The gateway for the Pod")
private String gateway;
@Parameter(name = ApiConstants.ALLOCATION_STATE, type = CommandType.STRING, description = "Allocation state of this cluster for allocation of new resources")
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/region/CreatePortableIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/CreatePortableIpRangeCmd.java
index fd103c838309..1142bdd3f43c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/region/CreatePortableIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/CreatePortableIpRangeCmd.java
@@ -36,7 +36,7 @@
@APICommand(name = "createPortableIpRange",
responseObject = PortableIpRangeResponse.class,
- description = "adds a range of portable public IP's to a region",
+ description = "Adds a range of portable public IP's to a region",
since = "4.2.0",
requestHasSensitiveInfo = false,
responseHasSensitiveInfo = false)
@@ -51,16 +51,16 @@ public class CreatePortableIpRangeCmd extends BaseAsyncCreateCmd {
@Parameter(name = ApiConstants.REGION_ID, type = CommandType.INTEGER, entityType = RegionResponse.class, required = true, description = "Id of the Region")
private Integer regionId;
- @Parameter(name = ApiConstants.START_IP, type = CommandType.STRING, required = true, description = "the beginning IP address in the portable IP range")
+ @Parameter(name = ApiConstants.START_IP, type = CommandType.STRING, required = true, description = "The beginning IP address in the portable IP range")
private String startIp;
- @Parameter(name = ApiConstants.END_IP, type = CommandType.STRING, required = true, description = "the ending IP address in the portable IP range")
+ @Parameter(name = ApiConstants.END_IP, type = CommandType.STRING, required = true, description = "The ending IP address in the portable IP range")
private String endIp;
- @Parameter(name = ApiConstants.GATEWAY, type = CommandType.STRING, required = true, description = "the gateway for the portable IP range")
+ @Parameter(name = ApiConstants.GATEWAY, type = CommandType.STRING, required = true, description = "The gateway for the portable IP range")
private String gateway;
- @Parameter(name = ApiConstants.NETMASK, type = CommandType.STRING, required = true, description = "the netmask of the portable IP range")
+ @Parameter(name = ApiConstants.NETMASK, type = CommandType.STRING, required = true, description = "The netmask of the portable IP range")
private String netmask;
@Parameter(name = ApiConstants.VLAN, type = CommandType.STRING, description = "VLAN id, if not specified defaulted to untagged")
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/region/DeletePortableIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/DeletePortableIpRangeCmd.java
index 3ff46fcc94d5..ac8fe66a8144 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/region/DeletePortableIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/DeletePortableIpRangeCmd.java
@@ -31,7 +31,7 @@
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
-@APICommand(name = "deletePortableIpRange", description = "deletes a range of portable public IP's associated with a region", responseObject = SuccessResponse.class,
+@APICommand(name = "deletePortableIpRange", description = "Deletes a range of portable public IP's associated with a region", responseObject = SuccessResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class DeletePortableIpRangeCmd extends BaseAsyncCmd {
@@ -83,7 +83,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "deleting a portable public ip range";
+ return "Deleting a portable public ip range with ID: " + getResourceUuid(ApiConstants.ID) ;
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java
index e654da6df449..92a1cc3822e9 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java
@@ -32,7 +32,7 @@
import com.cloud.user.Account;
-@APICommand(name = "listPortableIpRanges", description = "list portable IP ranges", responseObject = PortableIpRangeResponse.class,
+@APICommand(name = "listPortableIpRanges", description = "List portable IP ranges", responseObject = PortableIpRangeResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListPortableIpRangesCmd extends BaseListCmd {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/region/UpdateRegionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/UpdateRegionCmd.java
index 4267f6a2c286..ec5bfdabf5ec 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/region/UpdateRegionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/UpdateRegionCmd.java
@@ -42,10 +42,10 @@ public class UpdateRegionCmd extends BaseCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.INTEGER, required = true, description = "Id of region to update")
private Integer id;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "updates region with this name")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Updates region with this name")
private String regionName;
- @Parameter(name = ApiConstants.END_POINT, type = CommandType.STRING, description = "updates region with this end point")
+ @Parameter(name = ApiConstants.END_POINT, type = CommandType.STRING, description = "Updates region with this end point")
private String endPoint;
@Inject
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java
index dc8c15cf09df..e495a1683292 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java
@@ -46,18 +46,18 @@ public class ArchiveAlertsCmd extends BaseCmd {
type = CommandType.LIST,
collectionType = CommandType.UUID,
entityType = AlertResponse.class,
- description = "the IDs of the alerts")
+ description = "The IDs of the alerts")
private List ids;
- @Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, description = "end date range to archive alerts"
+ @Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, description = "End date range to archive alerts"
+ " (including) this date (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-ddThh:mm:ss\")")
private Date endDate;
- @Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, description = "start date range to archive alerts"
+ @Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, description = "Start date range to archive alerts"
+ " (including) this date (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-ddThh:mm:ss\")")
private Date startDate;
- @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "archive by alert type")
+ @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "Archive by alert type")
private String type;
// ///////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/CleanVMReservationsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/CleanVMReservationsCmd.java
index 1ae8c9441233..ba1b2be4008f 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/CleanVMReservationsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/CleanVMReservationsCmd.java
@@ -27,7 +27,7 @@
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
-@APICommand(name = "cleanVMReservations", description = "Cleanups VM reservations in the database.", responseObject = SuccessResponse.class,
+@APICommand(name = "cleanVMReservations", description = "Cleanups Instance reservations in the database.", responseObject = SuccessResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class CleanVMReservationsCmd extends BaseAsyncCmd {
@@ -63,7 +63,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "cleaning vm reservations in database";
+ return "Cleaning Instance reservations in database";
}
@Override
@@ -73,7 +73,7 @@ public void execute() {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} catch (Exception ex) {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to clean vm reservations");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to clean Instance reservations");
}
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java
index 9262a120f72c..f59a16d83733 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java
@@ -46,18 +46,18 @@ public class DeleteAlertsCmd extends BaseCmd {
type = CommandType.LIST,
collectionType = CommandType.UUID,
entityType = AlertResponse.class,
- description = "the IDs of the alerts")
+ description = "The IDs of the alerts")
private List ids;
- @Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, description = "end date range to delete alerts"
+ @Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, description = "End date range to delete alerts"
+ " (including) this date (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-ddThh:mm:ss\")")
private Date endDate;
- @Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, description = "start date range to delete alerts"
+ @Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, description = "Start date range to delete alerts"
+ " (including) this date (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-ddThh:mm:ss\")")
private Date startDate;
- @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "delete by alert type")
+ @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "Delete by alert type")
private String type;
// ///////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertTypesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertTypesCmd.java
index e7bfbdbc6254..dcd4f2c89ef2 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertTypesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertTypesCmd.java
@@ -16,7 +16,10 @@
// under the License.
package org.apache.cloudstack.api.command.admin.resource;
-import com.cloud.user.Account;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
import org.apache.cloudstack.alert.AlertService;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.BaseCmd;
@@ -24,9 +27,7 @@
import org.apache.cloudstack.api.response.AlertTypeResponse;
import org.apache.cloudstack.api.response.ListResponse;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
+import com.cloud.user.Account;
@APICommand(name = "listAlertTypes", description = "Lists all alerts types", responseObject = AlertResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@@ -43,7 +44,8 @@ public void execute() {
ListResponse response = new ListResponse<>();
List typeResponseList = new ArrayList<>();
for (AlertService.AlertType alertType : result) {
- AlertTypeResponse alertResponse = new AlertTypeResponse(alertType.getType(), alertType.getName());
+ AlertTypeResponse alertResponse = new AlertTypeResponse(alertType.getType(), alertType.getName(),
+ alertType.isRepetitionAllowed());
alertResponse.setObjectName("alerttype");
typeResponseList.add(alertResponse);
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java
index 64cf691e6a73..e88896703238 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java
@@ -39,13 +39,13 @@ public class ListAlertsCmd extends BaseListCmd {
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AlertResponse.class, description = "the ID of the alert")
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AlertResponse.class, description = "The ID of the alert")
private Long id;
- @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "list by alert type")
+ @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "List by alert type")
private String type;
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "list by alert name", since = "4.3")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "List by alert name", since = "4.3")
private String name;
// ///////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListCapacityCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListCapacityCmd.java
index f46cecdef504..ae98ca9dcd26 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListCapacityCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListCapacityCmd.java
@@ -46,23 +46,23 @@ public class ListCapacityCmd extends BaseListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "lists capacity by the Zone ID")
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "Lists capacity by the Zone ID")
private Long zoneId;
- @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, description = "lists capacity by the Pod ID")
+ @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, description = "Lists capacity by the Pod ID")
private Long podId;
@Parameter(name = ApiConstants.CLUSTER_ID,
type = CommandType.UUID,
entityType = ClusterResponse.class,
since = "3.0.0",
- description = "lists capacity by the Cluster ID")
+ description = "Lists capacity by the Cluster ID")
private Long clusterId;
- @Parameter(name = ApiConstants.FETCH_LATEST, type = CommandType.BOOLEAN, since = "3.0.0", description = "recalculate capacities and fetch the latest")
+ @Parameter(name = ApiConstants.FETCH_LATEST, type = CommandType.BOOLEAN, since = "3.0.0", description = "Recalculate capacities and fetch the latest")
private Boolean fetchLatest;
- @Parameter(name = ApiConstants.TYPE, type = CommandType.INTEGER, description = "lists capacity by type" + "* CAPACITY_TYPE_MEMORY = 0" + "* CAPACITY_TYPE_CPU = 1"
+ @Parameter(name = ApiConstants.TYPE, type = CommandType.INTEGER, description = "Lists capacity by type" + "* CAPACITY_TYPE_MEMORY = 0" + "* CAPACITY_TYPE_CPU = 1"
+ "* CAPACITY_TYPE_STORAGE = 2" + "* CAPACITY_TYPE_STORAGE_ALLOCATED = 3" + "* CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP = 4" + "* CAPACITY_TYPE_PRIVATE_IP = 5"
+ "* CAPACITY_TYPE_SECONDARY_STORAGE = 6" + "* CAPACITY_TYPE_VLAN = 7" + "* CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP = 8" + "* CAPACITY_TYPE_LOCAL_STORAGE = 9"
+ "* CAPACITY_TYPE_GPU = 19" + "* CAPACITY_TYPE_CPU_CORE = 90.")
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/StartRollingMaintenanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/StartRollingMaintenanceCmd.java
index 04fa1002611c..3869b9cdf957 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/StartRollingMaintenanceCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/StartRollingMaintenanceCmd.java
@@ -60,31 +60,31 @@ public class StartRollingMaintenanceCmd extends BaseAsyncCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.POD_IDS, type = CommandType.LIST, collectionType = CommandType.UUID,
- entityType = PodResponse.class, description = "the IDs of the pods to start maintenance on")
+ entityType = PodResponse.class, description = "The IDs of the pods to start maintenance on")
private List podIds;
@Parameter(name = ApiConstants.CLUSTER_IDS, type = CommandType.LIST, collectionType = CommandType.UUID,
- entityType = ClusterResponse.class, description = "the IDs of the clusters to start maintenance on")
+ entityType = ClusterResponse.class, description = "The IDs of the clusters to start maintenance on")
private List clusterIds;
@Parameter(name = ApiConstants.ZONE_ID_LIST, type = CommandType.LIST, collectionType = CommandType.UUID,
- entityType = ZoneResponse.class, description = "the IDs of the zones to start maintenance on")
+ entityType = ZoneResponse.class, description = "The IDs of the zones to start maintenance on")
private List zoneIds;
@Parameter(name = ApiConstants.HOST_IDS, type = CommandType.LIST, collectionType = CommandType.UUID,
- entityType = HostResponse.class, description = "the IDs of the hosts to start maintenance on")
+ entityType = HostResponse.class, description = "The IDs of the hosts to start maintenance on")
private List