diff --git a/.asf.yaml b/.asf.yaml
index 8c1a5d51fdf..4d979a18833 100644
--- a/.asf.yaml
+++ b/.asf.yaml
@@ -59,6 +59,7 @@ github:
- hsato03
- bernardodemarco
- abh1sar
+ - FelipeM525
protected_branches: ~
diff --git a/.github/linters/.flake8 b/.github/linters/.flake8
index f250719ca19..3364ad14f29 100644
--- a/.github/linters/.flake8
+++ b/.github/linters/.flake8
@@ -22,8 +22,11 @@
# E224 Tab after operator
# E227 Missing whitespace around bitwise or shift operator
# E242 Tab after ','
+# E271 Multiple spaces after keyword
+# E272 Multiple spaces before keyword
# E273 Tab after keyword
# E274 Tab before keyword
+# E713 Test for membership should be 'not in'
# E742 Do not define classes named 'I', 'O', or 'l'
# E743 Do not define functions named 'I', 'O', or 'l'
# E901 SyntaxError or IndentationError
@@ -37,4 +40,4 @@
exclude =
.git,
venv
-select = E112,E113,E133,E223,E224,E227,E242,E273,E274,E742,E743,E901,E902,W291,W292,W293,W391
+select = E112,E113,E133,E223,E224,E227,E242,E271,E272,E273,E274,E713,E742,E743,E901,E902,W291,W292,W293,W391
diff --git a/.github/linters/codespell.txt b/.github/linters/codespell.txt
new file mode 100644
index 00000000000..37b3e6de1cb
--- /dev/null
+++ b/.github/linters/codespell.txt
@@ -0,0 +1,526 @@
+accouns
+acheived
+acount
+actuall
+acuiring
+acumulate
+addreess
+addtion
+adminstrator
+afer
+afrer
+afterall
+againt
+ags
+aktive
+algoritm
+allo
+alloacate
+allocted
+alocation
+alogrithm
+alpha-numeric
+alue
+ammended
+ammount
+ans
+anull
+apche
+aplication
+apllication
+applicatio
+apporpriate
+appropritate
+aqcuire
+aqcuired
+aquire
+aquiring
+assiciate
+assigne
+assoication
+assosiate
+asssert
+astroid
+asynchroniously
+asyncronous
+atleast
+atomation
+attache
+attch
+attches
+authenciation
+authenitcation
+authenitication
+availiability
+avialable
+bais
+beacause
+beacuse
+becase
+becasue
+becaues
+behviour
+birdge
+bject
+boardcast
+bootstraper
+bu
+cant
+capabilites
+capablity
+capcity
+carrefully
+cavaet
+chaing
+checkd
+childs
+choosen
+chould
+clenup
+cliente
+clinet
+cluser
+cna
+collison
+comman
+commited
+comparision
+comparisions
+complient
+concious
+conectix
+confg
+configruation
+configuable
+conneciton
+connexion
+constrait
+constraits
+containg
+contex
+continuesly
+contro
+controler
+controles
+controll
+convienient
+convinience
+coputer
+correcponding
+correspoding
+correspoonds
+cosole
+coudl
+couldnt
+craete
+craeted
+crate
+crated
+createa
+createing
+credentail
+cros
+crresponding
+curren
+currentl
+datas
+decalared
+declatory
+decocdes
+decypher
+defalut
+defaut
+defered
+definiton
+deleteable
+dependancy
+dependant
+dependend
+deployement
+deply
+deplying
+dervied
+descktop
+descrption
+deserialzed
+desination
+detination
+detroy
+detroying
+dettach
+dettached
+dettaching
+diabling
+diasbled
+dictonary
+didnt
+differnet
+differnt
+direcotry
+directroy
+disale
+disbale
+discrepency
+disover
+dissapper
+dissassociated
+divice
+doesn'
+doesnot
+doesnt
+dont'
+doubleclick
+dows
+eanbled
+earch
+ect
+elemnt
+eles
+elments
+emmited
+enble
+encryted
+enebled
+enmpty
+entires
+enviornment
+environmnet
+equivalant
+erro
+erronous
+everthing
+everytime
+excetion
+excption
+excute
+execept
+execption
+execut
+executeable
+exeeded
+exisitng
+exisits
+existin
+existsing
+exitting
+expcted
+expection
+explaination
+explicitely
+faield
+faild
+failes
+falied
+fasion
+feild
+filenname
+fillled
+findout
+fisrt
+fo
+folowing
+fowarding
+frist
+fro
+frontent
+fuctionality
+genarate
+generallly
+gernerate
+get's
+gloabal
+gorry
+gracefull
+gradiant
+handeling
+hanling
+happend
+hasing
+hasnt
+hda
+hostanme
+hould
+hsould
+hte
+identifers
+identifyer
+identifyers
+igoring
+immediatley
+implememented
+implementor
+implementors
+implemnt
+implict
+implmeneted
+implmentation
+incase
+includeing
+incosistency
+indecates
+indien
+infor
+informations
+informaton
+infrastrcuture
+ingore
+inital
+initalize
+initator
+initilization
+inspite
+instace
+instal
+instnace
+intefaces
+intepret
+intereface
+interfer
+interpretted
+intialize
+intializes
+intializing
+invlaid
+invokation
+isnt
+ist
+klunky
+lable
+leve
+lief
+limite
+linke
+listner
+lokal
+lokales
+maintainence
+maintenace
+maintenence
+mamagement
+mambers
+manaully
+manuel
+maxium
+mehtod
+mergable
+mesage
+messge
+metatdata
+milisecond
+minumum
+mis
+modifers
+mor
+mot
+mulitply
+multipl
+multple
+mutliple
+nast
+nd
+neccessary
+necesary
+netowrk
+nin
+nodel
+nome
+noone
+nowe
+numbe
+numer
+occured
+occurence
+occuring
+offfering
+ofthe
+omited
+onother
+opeation
+optin
+orginal
+otherwse
+outter
+overriden
+overwritting
+paramater
+paramemeter
+paramenter
+paramete
+parametrs
+pararmeter
+parms
+parralels
+particualr
+passowrd
+perfromed
+permissble
+physcial
+plugable
+pluging
+polcies
+policys
+poluting
+possiblity
+potenial
+prefered
+preffered
+pressenter
+previleges
+primay
+priviledged
+procuct
+programatically
+progres
+properites
+propertie
+propertys
+propogate
+provison
+psudo
+pyhsical
+readabilty
+readd
+reccuring
+recevied
+recieved
+recursivelly
+redunant
+refference
+releease
+relese
+remaning
+remore
+remvoing
+renabling
+repeatly
+reponse
+reqest
+reqiured
+requieres
+requried
+reserv
+reserverd
+reseted
+reseting
+resorce
+responser
+resposne
+resturns
+retreive
+retreiving
+retrive
+retrived
+retriving
+retrun
+retuned
+returing
+re-use
+rever
+rocessor
+runing
+runnign
+sate
+scalled
+scipt
+scirpt
+scrip
+seconadry
+seconday
+seesion
+sepcified
+sepcify
+seprated
+ser
+servies
+seting
+settig
+sevices
+shoul
+shoule
+sie
+signle
+simplier
+singature
+skiping
+snaphsot
+snpashot
+specied
+specifed
+specifiy
+splitted
+spped
+standy
+statics
+stickyness
+stil
+stip
+storeage
+strat
+streched
+strutural
+succesfull
+successfull
+suceessful
+suces
+sucessfully
+suiteable
+suppots
+suppport
+syncronous
+syste
+tage
+te
+tempdate
+testng
+tha
+thats
+ther
+therefor
+theres
+theses
+thi
+thorugh
+throught
+ths
+tipically
+transction
+tring
+trough
+tyoe
+ue
+ues
+unavailibility
+uncommited
+uncompressible
+uneccessarily
+unexepected
+unexpect
+unknow
+unkonw
+unkown
+unneccessary
+unparseable
+unrecoginized
+unsupport
+unxpected
+updat
+uptodate
+usera
+usign
+usin
+utlization
+vaidate
+valiate
+valule
+valus
+varibles
+verfy
+verfying
+verifing
+virutal
+visable
+wakup
+wil
+wit
+wll
+wth
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 1c6c90a6183..fd3c8f8ac67 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -43,7 +43,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
- python-version: '3.8'
+ python-version: '3.10'
architecture: 'x64'
- name: Install Build Dependencies
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fac2d6266fa..ceffb42c79b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -35,6 +35,7 @@ jobs:
fail-fast: false
matrix:
tests: [ "smoke/test_accounts
+ smoke/test_account_access
smoke/test_affinity_groups
smoke/test_affinity_groups_projects
smoke/test_annotations
@@ -86,7 +87,9 @@ jobs:
smoke/test_migration
smoke/test_multipleips_per_nic
smoke/test_nested_virtualization
- smoke/test_set_sourcenat",
+ smoke/test_set_sourcenat
+ smoke/test_webhook_lifecycle
+ smoke/test_purge_expunged_vms",
"smoke/test_network
smoke/test_network_acl
smoke/test_network_ipv6
@@ -132,6 +135,7 @@ jobs:
smoke/test_usage
smoke/test_usage_events
smoke/test_vm_deployment_planner
+ smoke/test_vm_strict_host_tags
smoke/test_vm_schedule
smoke/test_vm_life_cycle
smoke/test_vm_lifecycle_unmanage_import
@@ -222,7 +226,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
- python-version: '3.8'
+ python-version: '3.10'
architecture: 'x64'
- name: Install Build Dependencies
@@ -280,7 +284,7 @@ jobs:
- name: Start CloudStack Management Server with Simulator
run: |
- export MAVEN_OPTS="-Xmx4096m -XX:MaxPermSize=800m -Djava.security.egd=file:/dev/urandom -javaagent:jacoco/lib/jacocoagent.jar=address=*,port=36320,output=tcpserver"
+ 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"
echo -e "\nStarting simulator"
set +e
mvn -Dsimulator -Dorg.eclipse.jetty.annotations.maxWait=120 -pl :cloud-client-ui jetty:run 2>&1 > /tmp/jetty-log || true &
diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml
index a8f923d708d..c77783746ca 100644
--- a/.github/workflows/codecov.yml
+++ b/.github/workflows/codecov.yml
@@ -36,11 +36,11 @@ jobs:
with:
fetch-depth: 0
- - name: Set up JDK11
+ - name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
- java-version: '11'
+ java-version: '17'
cache: 'maven'
- name: Build CloudStack with Quality Checks
diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml
index 784df0cf03c..b6c814a36f4 100644
--- a/.github/workflows/linter.yml
+++ b/.github/workflows/linter.yml
@@ -39,7 +39,7 @@ jobs:
pip install pre-commit
- name: Set PY
run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV
- - uses: actions/cache@v3
+ - uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
diff --git a/.github/workflows/main-sonar-check.yml b/.github/workflows/main-sonar-check.yml
index 66bb1093e04..8248e48022a 100644
--- a/.github/workflows/main-sonar-check.yml
+++ b/.github/workflows/main-sonar-check.yml
@@ -36,22 +36,22 @@ jobs:
with:
fetch-depth: 0
- - name: Set up JDK11
+ - name: Set up JDK17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
- java-version: '11'
+ java-version: '17'
cache: 'maven'
- name: Cache SonarCloud packages
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache local Maven repository
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
diff --git a/.github/workflows/rat.yml b/.github/workflows/rat.yml
index b8f83de8194..52ce343841b 100644
--- a/.github/workflows/rat.yml
+++ b/.github/workflows/rat.yml
@@ -31,10 +31,10 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- - name: Set up JDK 11
+ - name: Set up JDK 17
uses: actions/setup-java@v4
with:
- java-version: '11'
+ java-version: '17'
distribution: 'adopt'
architecture: x64
cache: maven
diff --git a/.github/workflows/sonar-check.yml b/.github/workflows/sonar-check.yml
index 2ebcf1fb2db..c36bceb2b90 100644
--- a/.github/workflows/sonar-check.yml
+++ b/.github/workflows/sonar-check.yml
@@ -38,22 +38,22 @@ jobs:
ref: "refs/pull/${{ github.event.number }}/merge"
fetch-depth: 0
- - name: Set up JDK11
+ - name: Set up JDK17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
- java-version: '11'
+ java-version: '17'
cache: 'maven'
- name: Cache SonarCloud packages
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache local Maven repository
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
diff --git a/.github/workflows/ui.yml b/.github/workflows/ui.yml
index 476526aff32..56f757133b7 100644
--- a/.github/workflows/ui.yml
+++ b/.github/workflows/ui.yml
@@ -36,7 +36,7 @@ jobs:
- name: Set up Node
uses: actions/setup-node@v3
with:
- node-version: 14
+ node-version: 16
- name: Env details
run: |
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 51ad34f2dbe..e8f3c6093a9 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -59,8 +59,17 @@ repos:
- id: mixed-line-ending
exclude: \.(cs|xml)$
- id: trailing-whitespace
- files: \.(in|java|md|py|rb|sh|vue|yaml|yml)$
+ files: \.(header|in|java|md|properties|py|rb|sh|sql|txt|vue|xml|yaml|yml)$
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.2.6
+ hooks:
+ - id: codespell
+ name: run codespell
+ description: Check spelling with codespell
+ args: [--ignore-words=.github/linters/codespell.txt]
+ exclude: ^ui/package\.json$|^ui/package-lock\.json$|^ui/public/js/less\.min\.js$|^ui/public/locales/.*[^n].*\.json$
- repo: https://github.com/pycqa/flake8
rev: 7.0.0
hooks:
diff --git a/INSTALL.md b/INSTALL.md
index 6586e4e57fc..e133e7d7b91 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -78,7 +78,7 @@ Clear old database (if any) and deploy the database schema:
Export the following variable if you need to run and debug the management server:
- $ export MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=500m -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"
+ $ export MAVEN_OPTS="-Xmx1024m -XX:MaxMetaspaceSize=500m -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"
Start the management server:
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
index 8293a22973a..e02cc651853 100644
--- a/PULL_REQUEST_TEMPLATE.md
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -23,6 +23,7 @@ This PR...
- [ ] Enhancement (improves an existing feature and functionality)
- [ ] Cleanup (Code refactoring and cleanup, that may add test cases)
- [ ] build/CI
+- [ ] test (unit or integration test code)
### Feature/Enhancement Scale or Bug Severity
diff --git a/agent/conf/cloudstack-agent.logrotate.in b/agent/conf/cloudstack-agent.logrotate.in
index 2b3dc87f253..9f22b4bab86 100644
--- a/agent/conf/cloudstack-agent.logrotate.in
+++ b/agent/conf/cloudstack-agent.logrotate.in
@@ -15,11 +15,13 @@
# specific language governing permissions and limitations
# under the License.
-/var/log/cloudstack/agent/security_group.log /var/log/cloudstack/agent/resizevolume.log /var/log/cloudstack/agent/rolling-maintenance.log {
+/var/log/cloudstack/agent/security_group.log /var/log/cloudstack/agent/resizevolume.log /var/log/cloudstack/agent/rolling-maintenance.log /var/log/cloudstack/agent/agent.out /var/log/cloudstack/agent/agent.err {
copytruncate
daily
rotate 5
compress
missingok
size 10M
+ dateext
+ dateformat -%Y-%m-%d
}
diff --git a/agent/conf/log4j-cloud.xml.in b/agent/conf/log4j-cloud.xml.in
index 44ebd1358af..84957edca03 100644
--- a/agent/conf/log4j-cloud.xml.in
+++ b/agent/conf/log4j-cloud.xml.in
@@ -30,7 +30,7 @@ under the License.
-
+
@@ -38,7 +38,7 @@ under the License.
-
+
diff --git a/agent/src/main/java/com/cloud/agent/Agent.java b/agent/src/main/java/com/cloud/agent/Agent.java
index 56732dad993..15f010808ac 100644
--- a/agent/src/main/java/com/cloud/agent/Agent.java
+++ b/agent/src/main/java/com/cloud/agent/Agent.java
@@ -504,6 +504,13 @@ public class Agent implements HandlerFactory, IAgentControl, AgentStatusUpdater
startup.setGuid(getResourceGuid());
startup.setResourceName(getResourceName());
startup.setVersion(getVersion());
+ startup.setArch(getAgentArch());
+ }
+
+ protected String getAgentArch() {
+ final Script command = new Script("/usr/bin/arch", 500, logger);
+ final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
+ return command.execute(parser);
}
@Override
@@ -858,11 +865,21 @@ public class Agent implements HandlerFactory, IAgentControl, AgentStatusUpdater
setId(ready.getHostId());
}
+ verifyAgentArch(ready.getArch());
processManagementServerList(ready.getMsHostList(), ready.getLbAlgorithm(), ready.getLbCheckInterval());
logger.info("Ready command is processed for agent id = {}", getId());
}
+ private void verifyAgentArch(String arch) {
+ if (StringUtils.isNotBlank(arch)) {
+ String agentArch = getAgentArch();
+ if (!arch.equals(agentArch)) {
+ logger.error("Unexpected arch {}, expected {}", agentArch, arch);
+ }
+ }
+ }
+
public void processOtherTask(final Task task) {
final Object obj = task.get();
if (obj instanceof Response) {
@@ -1127,6 +1144,12 @@ public class Agent implements HandlerFactory, IAgentControl, AgentStatusUpdater
logger.error("Error parsing task", e);
}
} 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
+ // wait 5 seconds before reconnecting
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ }
reconnect(task.getLink());
return;
} else if (task.getType() == Task.Type.OTHER) {
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 b27ba651e4f..8f97edc3935 100644
--- a/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java
+++ b/agent/src/main/java/com/cloud/agent/properties/AgentProperties.java
@@ -751,7 +751,7 @@ public class AgentProperties{
public static final Property IOTHREADS = new Property<>("iothreads", 1);
/**
- * Enable verbose mode for virt-v2v Instance Conversion from Vmware to KVM
+ * Enable verbose mode for virt-v2v Instance Conversion from VMware to KVM
* Data type: Boolean.
* Default value: false
*/
diff --git a/agent/src/test/java/com/cloud/agent/AgentShellTest.java b/agent/src/test/java/com/cloud/agent/AgentShellTest.java
index f7151779f58..4126692546f 100644
--- a/agent/src/test/java/com/cloud/agent/AgentShellTest.java
+++ b/agent/src/test/java/com/cloud/agent/AgentShellTest.java
@@ -350,4 +350,16 @@ public class AgentShellTest {
Mockito.verify(agentShellSpy).setHosts(expected);
}
+
+ @Test
+ public void updateAndGetConnectedHost() {
+ String expected = "test";
+
+ AgentShell shell = new AgentShell();
+ shell.setHosts("test");
+ shell.getNextHost();
+ shell.updateConnectedHost();
+
+ Assert.assertEquals(expected, shell.getConnectedHost());
+ }
}
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
new file mode 100644
index 00000000000..f7e4bfea80f
--- /dev/null
+++ b/api/src/main/java/com/cloud/agent/api/to/BucketTO.java
@@ -0,0 +1,50 @@
+// 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.agent.api.to;
+
+import org.apache.cloudstack.storage.object.Bucket;
+
+public final class BucketTO {
+
+ private String name;
+
+ private String accessKey;
+
+ private String secretKey;
+
+ public BucketTO(Bucket bucket) {
+ this.name = bucket.getName();
+ this.accessKey = bucket.getAccessKey();
+ this.secretKey = bucket.getSecretKey();
+ }
+
+ public BucketTO(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getAccessKey() {
+ return this.accessKey;
+ }
+
+ public String getSecretKey() {
+ return this.secretKey;
+ }
+}
diff --git a/api/src/main/java/com/cloud/agent/api/to/FirewallRuleTO.java b/api/src/main/java/com/cloud/agent/api/to/FirewallRuleTO.java
index d08884d1cbe..25c75001a3c 100644
--- a/api/src/main/java/com/cloud/agent/api/to/FirewallRuleTO.java
+++ b/api/src/main/java/com/cloud/agent/api/to/FirewallRuleTO.java
@@ -155,9 +155,7 @@ public class FirewallRuleTO implements InternalIdentity {
rule.getIcmpType(),
rule.getIcmpCode());
this.trafficType = trafficType;
- if (FirewallRule.Purpose.Ipv6Firewall.equals(purpose)) {
- this.destCidrList = rule.getDestinationCidrList();
- }
+ this.destCidrList = rule.getDestinationCidrList();
}
public FirewallRuleTO(FirewallRule rule, String srcVlanTag, String srcIp, FirewallRule.Purpose purpose, FirewallRule.TrafficType trafficType,
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 6e7aa8b21e2..d86eb2a3a7f 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
@@ -18,40 +18,39 @@
*/
package com.cloud.agent.api.to;
+import java.io.Serializable;
+
import com.cloud.agent.api.LogLevel;
import com.cloud.hypervisor.Hypervisor;
-import java.io.Serializable;
-
public class RemoteInstanceTO implements Serializable {
private Hypervisor.HypervisorType hypervisorType;
- private String hostName;
private String instanceName;
- // Vmware Remote Instances parameters
+ // VMware Remote Instances parameters (required for exporting OVA through ovftool)
// TODO: cloud.agent.transport.Request#getCommands() cannot handle gsoc decode for polymorphic classes
private String vcenterUsername;
@LogLevel(LogLevel.Log4jLevel.Off)
private String vcenterPassword;
private String vcenterHost;
private String datacenterName;
- private String clusterName;
public RemoteInstanceTO() {
}
- public RemoteInstanceTO(String hostName, String instanceName, String vcenterHost,
- String datacenterName, String clusterName,
- String vcenterUsername, String vcenterPassword) {
+ public RemoteInstanceTO(String instanceName) {
+ this.hypervisorType = Hypervisor.HypervisorType.VMware;
+ this.instanceName = instanceName;
+ }
+
+ public RemoteInstanceTO(String instanceName, String vcenterHost, String vcenterUsername, String vcenterPassword, String datacenterName) {
this.hypervisorType = Hypervisor.HypervisorType.VMware;
- this.hostName = hostName;
this.instanceName = instanceName;
this.vcenterHost = vcenterHost;
- this.datacenterName = datacenterName;
- this.clusterName = clusterName;
this.vcenterUsername = vcenterUsername;
this.vcenterPassword = vcenterPassword;
+ this.datacenterName = datacenterName;
}
public Hypervisor.HypervisorType getHypervisorType() {
@@ -62,10 +61,6 @@ public class RemoteInstanceTO implements Serializable {
return this.instanceName;
}
- public String getHostName() {
- return this.hostName;
- }
-
public String getVcenterUsername() {
return vcenterUsername;
}
@@ -81,8 +76,4 @@ public class RemoteInstanceTO implements Serializable {
public String getDatacenterName() {
return datacenterName;
}
-
- public String getClusterName() {
- return clusterName;
- }
}
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 b4f4619be9a..6f24b1cd6ca 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
@@ -84,6 +84,8 @@ public class VirtualMachineTO {
Map extraConfig = new HashMap<>();
Map networkIdToNetworkNameMap = new HashMap<>();
DeployAsIsInfoTO deployAsIsInfo;
+ String metadataManufacturer;
+ String metadataProductName;
public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader,
String os, boolean enableHA, boolean limitCpuUse, String vncPassword) {
@@ -429,6 +431,22 @@ public class VirtualMachineTO {
this.deployAsIsInfo = deployAsIsInfo;
}
+ public String getMetadataManufacturer() {
+ return metadataManufacturer;
+ }
+
+ public void setMetadataManufacturer(String metadataManufacturer) {
+ this.metadataManufacturer = metadataManufacturer;
+ }
+
+ public String getMetadataProductName() {
+ return metadataProductName;
+ }
+
+ public void setMetadataProductName(String metadataProductName) {
+ this.metadataProductName = metadataProductName;
+ }
+
@Override
public String toString() {
return String.format("VM {id: \"%s\", name: \"%s\", uuid: \"%s\", type: \"%s\"}", id, name, uuid, type);
diff --git a/api/src/main/java/com/cloud/bgp/ASNumber.java b/api/src/main/java/com/cloud/bgp/ASNumber.java
new file mode 100644
index 00000000000..b0e5394df75
--- /dev/null
+++ b/api/src/main/java/com/cloud/bgp/ASNumber.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 com.cloud.bgp;
+
+import org.apache.cloudstack.acl.InfrastructureEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+import java.util.Date;
+
+public interface ASNumber extends InfrastructureEntity, InternalIdentity, Identity {
+
+ Long getAccountId();
+ Long getDomainId();
+ long getAsNumber();
+ long getAsNumberRangeId();
+ long getDataCenterId();
+ Date getAllocatedTime();
+ boolean isAllocated();
+ Long getNetworkId();
+ Long getVpcId();
+ Date getCreated();
+ Date getRemoved();
+}
diff --git a/api/src/main/java/com/cloud/bgp/ASNumberRange.java b/api/src/main/java/com/cloud/bgp/ASNumberRange.java
new file mode 100644
index 00000000000..ae877ee60db
--- /dev/null
+++ b/api/src/main/java/com/cloud/bgp/ASNumberRange.java
@@ -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.
+package com.cloud.bgp;
+
+import org.apache.cloudstack.acl.InfrastructureEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+import java.util.Date;
+
+public interface ASNumberRange extends InfrastructureEntity, InternalIdentity, Identity {
+
+ long getStartASNumber();
+ long getEndASNumber();
+ long getDataCenterId();
+ Date getCreated();
+}
diff --git a/api/src/main/java/com/cloud/bgp/BGPService.java b/api/src/main/java/com/cloud/bgp/BGPService.java
new file mode 100644
index 00000000000..935237092dd
--- /dev/null
+++ b/api/src/main/java/com/cloud/bgp/BGPService.java
@@ -0,0 +1,39 @@
+// 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.bgp;
+
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.utils.Pair;
+import org.apache.cloudstack.api.command.user.bgp.ListASNumbersCmd;
+
+import java.util.List;
+
+public interface BGPService {
+
+ ASNumberRange createASNumberRange(long zoneId, long startASNumber, long endASNumber);
+ List listASNumberRanges(Long zoneId);
+ Pair, Integer> listASNumbers(ListASNumbersCmd cmd);
+ boolean allocateASNumber(long zoneId, Long asNumber, Long networkId, Long vpcId);
+ Pair releaseASNumber(long zoneId, long asNumber, boolean isReleaseNetworkDestroy);
+ boolean deleteASRange(long id);
+
+ boolean applyBgpPeers(Network network, boolean continueOnError) throws ResourceUnavailableException;
+
+ boolean applyBgpPeers(Vpc vpc, boolean continueOnError) throws ResourceUnavailableException;
+}
diff --git a/api/src/main/java/com/cloud/cpu/CPU.java b/api/src/main/java/com/cloud/cpu/CPU.java
new file mode 100644
index 00000000000..4e1b9f5a501
--- /dev/null
+++ b/api/src/main/java/com/cloud/cpu/CPU.java
@@ -0,0 +1,67 @@
+// 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.cpu;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class CPU {
+
+ public static final String archX86Identifier = "i686";
+ public static final String archX86_64Identifier = "x86_64";
+ public static final String archARM64Identifier = "aarch64";
+
+ public static class CPUArch {
+ private static final Map cpuArchMap = new LinkedHashMap<>();
+
+ public static final CPUArch archX86 = new CPUArch(archX86Identifier, 32);
+ public static final CPUArch amd64 = new CPUArch(archX86_64Identifier, 64);
+ public static final CPUArch arm64 = new CPUArch(archARM64Identifier, 64);
+
+ private String type;
+ private int bits;
+
+ public CPUArch(String type, int bits) {
+ this.type = type;
+ this.bits = bits;
+ cpuArchMap.put(type, this);
+ }
+
+ public String getType() {
+ return this.type;
+ }
+
+ public int getBits() {
+ return this.bits;
+ }
+
+ public static CPUArch fromType(String type) {
+ if (StringUtils.isBlank(type)) {
+ return amd64;
+ }
+ switch (type) {
+ case archX86Identifier: return archX86;
+ case archX86_64Identifier: return amd64;
+ case archARM64Identifier: return arm64;
+ default: throw new CloudRuntimeException(String.format("Unsupported arch type: %s", type));
+ }
+ }
+ }
+}
diff --git a/api/src/main/java/com/cloud/dc/DedicatedResources.java b/api/src/main/java/com/cloud/dc/DedicatedResources.java
index 63188ca0b0e..23e6cc88a1e 100644
--- a/api/src/main/java/com/cloud/dc/DedicatedResources.java
+++ b/api/src/main/java/com/cloud/dc/DedicatedResources.java
@@ -21,6 +21,10 @@ import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
public interface DedicatedResources extends InfrastructureEntity, InternalIdentity, Identity {
+ enum Type {
+ Zone, Pod, Cluster, Host
+ }
+
@Override
long getId();
diff --git a/api/src/main/java/com/cloud/event/EventTypes.java b/api/src/main/java/com/cloud/event/EventTypes.java
index 01ad12a71e0..5e5309965c1 100644
--- a/api/src/main/java/com/cloud/event/EventTypes.java
+++ b/api/src/main/java/com/cloud/event/EventTypes.java
@@ -28,10 +28,14 @@ import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.PodResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.config.Configuration;
+import org.apache.cloudstack.datacenter.DataCenterIpv4GuestSubnet;
import org.apache.cloudstack.ha.HAConfig;
+import org.apache.cloudstack.network.BgpPeer;
+import org.apache.cloudstack.network.Ipv4GuestSubnetNetworkMap;
+import org.apache.cloudstack.quota.QuotaTariff;
+import org.apache.cloudstack.storage.sharedfs.SharedFS;
import org.apache.cloudstack.storage.object.Bucket;
import org.apache.cloudstack.storage.object.ObjectStore;
-import org.apache.cloudstack.quota.QuotaTariff;
import org.apache.cloudstack.usage.Usage;
import org.apache.cloudstack.vm.schedule.VMSchedule;
@@ -242,6 +246,8 @@ public class EventTypes {
public static final String EVENT_ROLE_UPDATE = "ROLE.UPDATE";
public static final String EVENT_ROLE_DELETE = "ROLE.DELETE";
public static final String EVENT_ROLE_IMPORT = "ROLE.IMPORT";
+ public static final String EVENT_ROLE_ENABLE = "ROLE.ENABLE";
+ public static final String EVENT_ROLE_DISABLE = "ROLE.DISABLE";
public static final String EVENT_ROLE_PERMISSION_CREATE = "ROLE.PERMISSION.CREATE";
public static final String EVENT_ROLE_PERMISSION_UPDATE = "ROLE.PERMISSION.UPDATE";
public static final String EVENT_ROLE_PERMISSION_DELETE = "ROLE.PERMISSION.DELETE";
@@ -333,6 +339,7 @@ public class EventTypes {
public static final String EVENT_SNAPSHOT_OFF_PRIMARY = "SNAPSHOT.OFF_PRIMARY";
public static final String EVENT_SNAPSHOT_DELETE = "SNAPSHOT.DELETE";
public static final String EVENT_SNAPSHOT_REVERT = "SNAPSHOT.REVERT";
+ public static final String EVENT_SNAPSHOT_EXTRACT = "SNAPSHOT.EXTRACT";
public static final String EVENT_SNAPSHOT_POLICY_CREATE = "SNAPSHOTPOLICY.CREATE";
public static final String EVENT_SNAPSHOT_POLICY_UPDATE = "SNAPSHOTPOLICY.UPDATE";
public static final String EVENT_SNAPSHOT_POLICY_DELETE = "SNAPSHOTPOLICY.DELETE";
@@ -390,6 +397,11 @@ public class EventTypes {
public static final String EVENT_VLAN_IP_RANGE_RELEASE = "VLAN.IP.RANGE.RELEASE";
public static final String EVENT_VLAN_IP_RANGE_UPDATE = "VLAN.IP.RANGE.UPDATE";
+ // AS Number
+ public static final String EVENT_AS_RANGE_CREATE = "AS.RANGE.CREATE";
+ public static final String EVENT_AS_RANGE_DELETE = "AS.RANGE.DELETE";
+ public static final String EVENT_AS_NUMBER_RELEASE = "AS.NUMBER.RELEASE";
+
public static final String EVENT_MANAGEMENT_IP_RANGE_CREATE = "MANAGEMENT.IP.RANGE.CREATE";
public static final String EVENT_MANAGEMENT_IP_RANGE_DELETE = "MANAGEMENT.IP.RANGE.DELETE";
public static final String EVENT_MANAGEMENT_IP_RANGE_UPDATE = "MANAGEMENT.IP.RANGE.UPDATE";
@@ -448,9 +460,11 @@ public class EventTypes {
public static final String EVENT_MAINTENANCE_PREPARE_PRIMARY_STORAGE = "MAINT.PREPARE.PS";
// Primary storage pool
+ public static final String EVENT_UPDATE_PRIMARY_STORAGE = "UPDATE.PS";
public static final String EVENT_ENABLE_PRIMARY_STORAGE = "ENABLE.PS";
public static final String EVENT_DISABLE_PRIMARY_STORAGE = "DISABLE.PS";
public static final String EVENT_SYNC_STORAGE_POOL = "SYNC.STORAGE.POOL";
+ public static final String EVENT_CHANGE_STORAGE_POOL_SCOPE = "CHANGE.STORAGE.POOL.SCOPE";
// VPN
public static final String EVENT_REMOTE_ACCESS_VPN_CREATE = "VPN.REMOTE.ACCESS.CREATE";
@@ -721,6 +735,8 @@ public class EventTypes {
// SystemVM
public static final String EVENT_LIVE_PATCH_SYSTEMVM = "LIVE.PATCH.SYSTEM.VM";
+ //Purge resources
+ public static final String EVENT_PURGE_EXPUNGED_RESOURCES = "PURGE.EXPUNGED.RESOURCES";
// OBJECT STORE
public static final String EVENT_OBJECT_STORE_CREATE = "OBJECT.STORE.CREATE";
@@ -737,6 +753,37 @@ public class EventTypes {
public static final String EVENT_QUOTA_TARIFF_DELETE = "QUOTA.TARIFF.DELETE";
public static final String EVENT_QUOTA_TARIFF_UPDATE = "QUOTA.TARIFF.UPDATE";
+ // Routing
+ public static final String EVENT_ZONE_IP4_SUBNET_CREATE = "ZONE.IP4.SUBNET.CREATE";
+ public static final String EVENT_ZONE_IP4_SUBNET_UPDATE = "ZONE.IP4.SUBNET.UPDATE";
+ public static final String EVENT_ZONE_IP4_SUBNET_DELETE = "ZONE.IP4.SUBNET.DELETE";
+ public static final String EVENT_ZONE_IP4_SUBNET_DEDICATE = "ZONE.IP4.SUBNET.DEDICATE";
+ public static final String EVENT_ZONE_IP4_SUBNET_RELEASE = "ZONE.IP4.SUBNET.RELEASE";
+ public static final String EVENT_IP4_GUEST_SUBNET_CREATE = "IP4.GUEST.SUBNET.CREATE";
+ public static final String EVENT_IP4_GUEST_SUBNET_DELETE = "IP4.GUEST.SUBNET.DELETE";
+ public static final String EVENT_ROUTING_IPV4_FIREWALL_RULE_CREATE = "ROUTING.IPV4.FIREWALL.RULE.CREATE";
+ public static final String EVENT_ROUTING_IPV4_FIREWALL_RULE_UPDATE = "ROUTING.IPV4.FIREWALL.RULE.UPDATE";
+ public static final String EVENT_ROUTING_IPV4_FIREWALL_RULE_DELETE = "ROUTING.IPV4.FIREWALL.RULE.DELETE";
+ public static final String EVENT_BGP_PEER_CREATE = "BGP.PEER.CREATE";
+ public static final String EVENT_BGP_PEER_UPDATE = "BGP.PEER.UPDATE";
+ public static final String EVENT_BGP_PEER_DELETE = "BGP.PEER.DELETE";
+ public static final String EVENT_BGP_PEER_DEDICATE = "BGP.PEER.DEDICATE";
+ public static final String EVENT_BGP_PEER_RELEASE = "BGP.PEER.RELEASE";
+ public static final String EVENT_NETWORK_BGP_PEER_UPDATE = "NETWORK.BGP.PEER.UPDATE";
+ public static final String EVENT_VPC_BGP_PEER_UPDATE = "VPC.BGP.PEER.UPDATE";
+
+ // SharedFS
+ public static final String EVENT_SHAREDFS_CREATE = "SHAREDFS.CREATE";
+ public static final String EVENT_SHAREDFS_START = "SHAREDFS.START";
+ public static final String EVENT_SHAREDFS_UPDATE = "SHAREDFS.UPDATE";
+ public static final String EVENT_SHAREDFS_CHANGE_SERVICE_OFFERING = "SHAREDFS.CHANGE.SERVICE.OFFERING";
+ public static final String EVENT_SHAREDFS_CHANGE_DISK_OFFERING = "SHAREDFS.CHANGE.DISK.OFFERING";
+ public static final String EVENT_SHAREDFS_STOP = "SHAREDFS.STOP";
+ public static final String EVENT_SHAREDFS_RESTART = "SHAREDFS.RESTART";
+ public static final String EVENT_SHAREDFS_DESTROY = "SHAREDFS.DESTROY";
+ public static final String EVENT_SHAREDFS_EXPUNGE = "SHAREDFS.EXPUNGE";
+ public static final String EVENT_SHAREDFS_RECOVER = "SHAREDFS.RECOVER";
+
static {
// TODO: need a way to force author adding event types to declare the entity details as well, with out braking
@@ -838,6 +885,8 @@ public class EventTypes {
entityEventDetails.put(EVENT_ROLE_UPDATE, Role.class);
entityEventDetails.put(EVENT_ROLE_DELETE, Role.class);
entityEventDetails.put(EVENT_ROLE_IMPORT, Role.class);
+ entityEventDetails.put(EVENT_ROLE_ENABLE, Role.class);
+ entityEventDetails.put(EVENT_ROLE_DISABLE, Role.class);
entityEventDetails.put(EVENT_ROLE_PERMISSION_CREATE, RolePermission.class);
entityEventDetails.put(EVENT_ROLE_PERMISSION_UPDATE, RolePermission.class);
entityEventDetails.put(EVENT_ROLE_PERMISSION_DELETE, RolePermission.class);
@@ -894,6 +943,7 @@ public class EventTypes {
// Snapshots
entityEventDetails.put(EVENT_SNAPSHOT_CREATE, Snapshot.class);
entityEventDetails.put(EVENT_SNAPSHOT_DELETE, Snapshot.class);
+ entityEventDetails.put(EVENT_SNAPSHOT_EXTRACT, Snapshot.class);
entityEventDetails.put(EVENT_SNAPSHOT_ON_PRIMARY, Snapshot.class);
entityEventDetails.put(EVENT_SNAPSHOT_OFF_PRIMARY, Snapshot.class);
entityEventDetails.put(EVENT_SNAPSHOT_POLICY_CREATE, SnapshotPolicy.class);
@@ -998,8 +1048,10 @@ public class EventTypes {
entityEventDetails.put(EVENT_MAINTENANCE_PREPARE_PRIMARY_STORAGE, Host.class);
// Primary storage pool
+ entityEventDetails.put(EVENT_UPDATE_PRIMARY_STORAGE, StoragePool.class);
entityEventDetails.put(EVENT_ENABLE_PRIMARY_STORAGE, StoragePool.class);
entityEventDetails.put(EVENT_DISABLE_PRIMARY_STORAGE, StoragePool.class);
+ entityEventDetails.put(EVENT_CHANGE_STORAGE_POOL_SCOPE, StoragePool.class);
// VPN
entityEventDetails.put(EVENT_REMOTE_ACCESS_VPN_CREATE, RemoteAccessVpn.class);
@@ -1191,6 +1243,35 @@ public class EventTypes {
entityEventDetails.put(EVENT_QUOTA_TARIFF_CREATE, QuotaTariff.class);
entityEventDetails.put(EVENT_QUOTA_TARIFF_DELETE, QuotaTariff.class);
entityEventDetails.put(EVENT_QUOTA_TARIFF_UPDATE, QuotaTariff.class);
+
+ // Routing
+ entityEventDetails.put(EVENT_ZONE_IP4_SUBNET_CREATE, DataCenterIpv4GuestSubnet.class);
+ entityEventDetails.put(EVENT_ZONE_IP4_SUBNET_UPDATE, DataCenterIpv4GuestSubnet.class);
+ entityEventDetails.put(EVENT_ZONE_IP4_SUBNET_DELETE, DataCenterIpv4GuestSubnet.class);
+ entityEventDetails.put(EVENT_ZONE_IP4_SUBNET_DEDICATE, DataCenterIpv4GuestSubnet.class);
+ entityEventDetails.put(EVENT_ZONE_IP4_SUBNET_RELEASE, DataCenterIpv4GuestSubnet.class);
+ entityEventDetails.put(EVENT_IP4_GUEST_SUBNET_CREATE, Ipv4GuestSubnetNetworkMap.class);
+ entityEventDetails.put(EVENT_IP4_GUEST_SUBNET_DELETE, Ipv4GuestSubnetNetworkMap.class);
+ entityEventDetails.put(EVENT_ROUTING_IPV4_FIREWALL_RULE_CREATE, FirewallRule.class);
+ entityEventDetails.put(EVENT_ROUTING_IPV4_FIREWALL_RULE_UPDATE, FirewallRule.class);
+ entityEventDetails.put(EVENT_ROUTING_IPV4_FIREWALL_RULE_DELETE, FirewallRule.class);
+ entityEventDetails.put(EVENT_BGP_PEER_CREATE, BgpPeer.class);
+ entityEventDetails.put(EVENT_BGP_PEER_UPDATE, BgpPeer.class);
+ entityEventDetails.put(EVENT_BGP_PEER_DELETE, BgpPeer.class);
+ entityEventDetails.put(EVENT_BGP_PEER_DEDICATE, BgpPeer.class);
+ entityEventDetails.put(EVENT_BGP_PEER_RELEASE, BgpPeer.class);
+
+ // SharedFS
+ entityEventDetails.put(EVENT_SHAREDFS_CREATE, SharedFS.class);
+ entityEventDetails.put(EVENT_SHAREDFS_START, SharedFS.class);
+ entityEventDetails.put(EVENT_SHAREDFS_STOP, SharedFS.class);
+ entityEventDetails.put(EVENT_SHAREDFS_UPDATE, SharedFS.class);
+ entityEventDetails.put(EVENT_SHAREDFS_CHANGE_SERVICE_OFFERING, SharedFS.class);
+ entityEventDetails.put(EVENT_SHAREDFS_CHANGE_DISK_OFFERING, SharedFS.class);
+ entityEventDetails.put(EVENT_SHAREDFS_RESTART, SharedFS.class);
+ entityEventDetails.put(EVENT_SHAREDFS_DESTROY, SharedFS.class);
+ entityEventDetails.put(EVENT_SHAREDFS_EXPUNGE, SharedFS.class);
+ entityEventDetails.put(EVENT_SHAREDFS_RECOVER, SharedFS.class);
}
public static boolean isNetworkEvent(String eventType) {
@@ -1229,4 +1310,8 @@ public class EventTypes {
public static boolean isVpcEvent(String eventType) {
return EventTypes.EVENT_VPC_CREATE.equals(eventType) || EventTypes.EVENT_VPC_DELETE.equals(eventType);
}
+
+ public static void addEntityEventDetail(String event, Class> clazz) {
+ entityEventDetails.put(event, clazz);
+ }
}
diff --git a/api/src/main/java/com/cloud/host/Host.java b/api/src/main/java/com/cloud/host/Host.java
index 7563bc3b742..56b4ed75a31 100644
--- a/api/src/main/java/com/cloud/host/Host.java
+++ b/api/src/main/java/com/cloud/host/Host.java
@@ -16,6 +16,7 @@
// under the License.
package com.cloud.host;
+import com.cloud.cpu.CPU;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.resource.ResourceState;
import com.cloud.utils.fsm.StateObject;
@@ -54,6 +55,7 @@ public interface Host extends StateObject, Identity, Partition, HAResour
}
public static final String HOST_UEFI_ENABLE = "host.uefi.enable";
public static final String HOST_VOLUME_ENCRYPTION = "host.volume.encryption";
+ public static final String HOST_INSTANCE_CONVERSION = "host.instance.conversion";
/**
* @return name of the machine.
@@ -207,4 +209,6 @@ public interface Host extends StateObject, Identity, Partition, HAResour
boolean isDisabled();
ResourceState getResourceState();
+
+ CPU.CPUArch getArch();
}
diff --git a/api/src/main/java/com/cloud/hypervisor/HypervisorGuru.java b/api/src/main/java/com/cloud/hypervisor/HypervisorGuru.java
index 3c7dbac6442..0c821b4e36c 100644
--- a/api/src/main/java/com/cloud/hypervisor/HypervisorGuru.java
+++ b/api/src/main/java/com/cloud/hypervisor/HypervisorGuru.java
@@ -23,6 +23,7 @@ import org.apache.cloudstack.backup.Backup;
import org.apache.cloudstack.framework.config.ConfigKey;
import com.cloud.agent.api.Command;
+import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
@@ -101,21 +102,20 @@ public interface HypervisorGuru extends Adapter {
* Will generate commands to migrate a vm to a pool. For now this will only work for stopped VMs on Vmware.
*
* @param vm the stopped vm to migrate
- * @param destination the primary storage pool to migrate to
+ * @param volumeToPool the primary storage pools to migrate to
* @return a list of commands to perform for a successful migration
*/
List finalizeMigrate(VirtualMachine vm, Map volumeToPool);
/**
- * Will perform a clone of a VM on an external host (if the guru can handle)
+ * Will return the hypervisor VM (clone VM for PowerOn VMs), performs a clone of a VM if required on an external host (if the guru can handle)
* @param hostIp VM's source host IP
- * @param vmName name of the source VM to clone from
+ * @param vmName name of the source VM (clone VM name if cloned)
* @param params hypervisor specific additional parameters
- * @return a reference to the cloned VM
+ * @return a reference to the hypervisor or cloned VM, and cloned flag
*/
- UnmanagedInstanceTO cloneHypervisorVMOutOfBand(String hostIp, String vmName,
- Map params);
+ Pair getHypervisorVMOutOfBandAndCloneIfRequired(String hostIp, String vmName, Map params);
/**
* Removes a VM created as a clone of a VM on an external host
@@ -124,6 +124,23 @@ public interface HypervisorGuru extends Adapter {
* @param params hypervisor specific additional parameters
* @return true if the operation succeeds, false if not
*/
- boolean removeClonedHypervisorVMOutOfBand(String hostIp, String vmName,
- Map params);
+ boolean removeClonedHypervisorVMOutOfBand(String hostIp, String vmName, Map params);
+
+ /**
+ * Create an OVA/OVF template of a VM on an external host (if the guru can handle)
+ * @param hostIp VM's source host IP
+ * @param vmName name of the source VM to create template from
+ * @param params hypervisor specific additional parameters
+ * @param templateLocation datastore to create the template file
+ * @return the created template dir/name
+ */
+ String createVMTemplateOutOfBand(String hostIp, String vmName, Map params, DataStoreTO templateLocation, int threadsCountToExportOvf);
+
+ /**
+ * Removes the template on the location
+ * @param templateLocation datastore to remove the template file
+ * @param templateDir the template dir to remove from datastore
+ * @return true if the operation succeeds, false if not
+ */
+ boolean removeVMTemplateOutOfBand(DataStoreTO templateLocation, String templateDir);
}
diff --git a/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterHelper.java b/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java
similarity index 90%
rename from api/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterHelper.java
rename to api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java
index 9bc9cd38632..4d6dec1f08b 100644
--- a/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterHelper.java
+++ b/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java
@@ -16,12 +16,14 @@
// under the License.
package com.cloud.kubernetes.cluster;
-import com.cloud.utils.component.Adapter;
import org.apache.cloudstack.acl.ControlledEntity;
import java.util.Map;
-public interface KubernetesClusterHelper extends Adapter {
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.component.Adapter;
+
+public interface KubernetesServiceHelper extends Adapter {
enum KubernetesClusterNodeType {
CONTROL, WORKER, ETCD, DEFAULT
@@ -29,6 +31,7 @@ public interface KubernetesClusterHelper extends Adapter {
ControlledEntity findByUuid(String uuid);
ControlledEntity findByVmId(long vmId);
+ void checkVmCanBeDestroyed(UserVm userVm);
boolean isValidNodeType(String nodeType);
Map getServiceOfferingNodeTypeMap(Map> serviceOfferingNodeTypeMap);
Map getTemplateNodeTypeMap(Map> templateNodeTypeMap);
diff --git a/api/src/main/java/com/cloud/network/Network.java b/api/src/main/java/com/cloud/network/Network.java
index 3b13ef7bd9c..d3bc5005cb7 100644
--- a/api/src/main/java/com/cloud/network/Network.java
+++ b/api/src/main/java/com/cloud/network/Network.java
@@ -103,7 +103,7 @@ public interface Network extends ControlledEntity, StateObject, I
public static final Service Vpn = new Service("Vpn", Capability.SupportedVpnProtocols, Capability.VpnTypes);
public static final Service Dhcp = new Service("Dhcp", Capability.ExtraDhcpOptions);
public static final Service Dns = new Service("Dns", Capability.AllowDnsSuffixModification);
- public static final Service Gateway = new Service("Gateway");
+ public static final Service Gateway = new Service("Gateway", Capability.RedundantRouter);
public static final Service Firewall = new Service("Firewall", Capability.SupportedProtocols, Capability.MultipleIps, Capability.TrafficStatistics,
Capability.SupportedTrafficDirection, Capability.SupportedEgressProtocols);
public static final Service Lb = new Service("Lb", Capability.SupportedLBAlgorithms, Capability.SupportedLBIsolation, Capability.SupportedProtocols,
@@ -412,12 +412,16 @@ public interface Network extends ControlledEntity, StateObject, I
String getGateway();
+ void setGateway(String gateway);
+
// "cidr" is the Cloudstack managed address space, all CloudStack managed vms get IP address from "cidr",
// In general "cidr" also serves as the network CIDR
// But in case IP reservation is configured for a Guest network, "networkcidr" is the Effective network CIDR for that network,
// "cidr" will still continue to be the effective address space for CloudStack managed vms in that Guest network
String getCidr();
+ void setCidr(String cidr);
+
// "networkcidr" is the network CIDR of the guest network which uses IP reservation.
// It is the summation of "cidr" and the reservedIPrange(the address space used for non CloudStack purposes).
// For networks not configured with IP reservation, "networkcidr" is always null
@@ -503,4 +507,6 @@ public interface Network extends ControlledEntity, StateObject, I
Integer getPublicMtu();
Integer getPrivateMtu();
+
+ Integer getNetworkCidrSize();
}
diff --git a/api/src/main/java/com/cloud/network/NetworkModel.java b/api/src/main/java/com/cloud/network/NetworkModel.java
index 53ac735cf05..a4cd87af008 100644
--- a/api/src/main/java/com/cloud/network/NetworkModel.java
+++ b/api/src/main/java/com/cloud/network/NetworkModel.java
@@ -149,7 +149,7 @@ public interface NetworkModel {
boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services);
- Network getNetworkWithSGWithFreeIPs(Long zoneId);
+ Network getNetworkWithSGWithFreeIPs(Account account, Long zoneId);
Network getNetworkWithSecurityGroupEnabled(Long zoneId);
@@ -173,6 +173,8 @@ public interface NetworkModel {
boolean isProviderSupportServiceInNetwork(long networkId, Service service, Provider provider);
+ boolean isAnyServiceSupportedInNetwork(long networkId, Provider provider, Service... services);
+
boolean isProviderEnabledInPhysicalNetwork(long physicalNetowrkId, String providerName);
String getNetworkTag(HypervisorType hType, Network network);
@@ -317,6 +319,8 @@ public interface NetworkModel {
void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException;
+ void checkIp6CidrSizeEqualTo64(String ip6Cidr) throws InvalidParameterValueException;
+
void checkRequestedIpAddresses(long networkId, IpAddresses ips) throws InvalidParameterValueException;
String getStartIpv6Address(long id);
@@ -354,4 +358,8 @@ public interface NetworkModel {
void verifyIp6DnsPair(final String ip6Dns1, final String ip6Dns2);
+ boolean isSecurityGroupSupportedForZone(Long zoneId);
+
+ boolean checkSecurityGroupSupportForNetwork(Account account, DataCenter zone, List networkIds,
+ List securityGroupsIds);
}
diff --git a/api/src/main/java/com/cloud/network/NetworkProfile.java b/api/src/main/java/com/cloud/network/NetworkProfile.java
index 1a5c80ea871..83dc247cc9e 100644
--- a/api/src/main/java/com/cloud/network/NetworkProfile.java
+++ b/api/src/main/java/com/cloud/network/NetworkProfile.java
@@ -41,8 +41,8 @@ public class NetworkProfile implements Network {
private final Mode mode;
private final BroadcastDomainType broadcastDomainType;
private TrafficType trafficType;
- private final String gateway;
- private final String cidr;
+ private String gateway;
+ private String cidr;
private final String networkCidr;
private final String ip6Gateway;
private final String ip6Cidr;
@@ -62,6 +62,7 @@ public class NetworkProfile implements Network {
private final String guruName;
private boolean strechedL2Subnet;
private String externalId;
+ private Integer networkCidrSize;
public NetworkProfile(Network network) {
id = network.getId();
@@ -98,6 +99,7 @@ public class NetworkProfile implements Network {
isRedundant = network.isRedundant();
isRollingRestart = network.isRollingRestart();
externalId = network.getExternalId();
+ networkCidrSize = network.getNetworkCidrSize();
}
@Override
@@ -210,11 +212,21 @@ public class NetworkProfile implements Network {
return gateway;
}
+ @Override
+ public void setGateway(String gateway) {
+ this.gateway = gateway;
+ }
+
@Override
public String getCidr() {
return cidr;
}
+ @Override
+ public void setCidr(String cidr) {
+ this.cidr = cidr;
+ }
+
@Override
public String getNetworkCidr() {
return networkCidr;
@@ -367,4 +379,9 @@ public class NetworkProfile implements Network {
return null;
}
+ @Override
+ public Integer getNetworkCidrSize() {
+ return networkCidrSize;
+ }
+
}
diff --git a/api/src/main/java/com/cloud/network/NetworkService.java b/api/src/main/java/com/cloud/network/NetworkService.java
index 02ca13cb9a4..36d58c737cc 100644
--- a/api/src/main/java/com/cloud/network/NetworkService.java
+++ b/api/src/main/java/com/cloud/network/NetworkService.java
@@ -20,6 +20,7 @@ import java.util.List;
import java.util.Map;
import com.cloud.dc.DataCenter;
+import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
@@ -102,6 +103,10 @@ public interface NetworkService {
Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException;
+ Network createGuestNetwork(long networkOfferingId, String name, String displayText, Account owner,
+ PhysicalNetwork physicalNetwork, long zoneId, ControlledEntity.ACLType aclType) throws
+ InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException;
+
Pair, Integer> searchForNetworks(ListNetworksCmd cmd);
boolean deleteNetwork(long networkId, boolean forced);
diff --git a/api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java b/api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java
index c47500c7849..cb92739d283 100644
--- a/api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java
+++ b/api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java
@@ -17,17 +17,22 @@
package com.cloud.network;
import java.util.List;
+import java.util.Map;
import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
+import com.cloud.deploy.DeploymentPlanner;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.router.VirtualRouter;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.vm.Nic;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
public interface VirtualNetworkApplianceService {
/**
@@ -62,6 +67,10 @@ public interface VirtualNetworkApplianceService {
VirtualRouter startRouter(long id) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException;
+ void startRouterForHA(VirtualMachine vm, Map params, DeploymentPlanner planner)
+ throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException,
+ OperationTimedoutException;
+
VirtualRouter destroyRouter(long routerId, Account caller, Long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException;
VirtualRouter findRouter(long routerId);
diff --git a/api/src/main/java/com/cloud/network/VpcVirtualNetworkApplianceService.java b/api/src/main/java/com/cloud/network/VpcVirtualNetworkApplianceService.java
index 5c3ee3f1032..cd04db802ca 100644
--- a/api/src/main/java/com/cloud/network/VpcVirtualNetworkApplianceService.java
+++ b/api/src/main/java/com/cloud/network/VpcVirtualNetworkApplianceService.java
@@ -29,7 +29,6 @@ public interface VpcVirtualNetworkApplianceService extends VirtualNetworkApplian
/**
* @param router
* @param network
- * @param isRedundant
* @param params TODO
* @return
* @throws ConcurrentOperationException
@@ -42,11 +41,30 @@ public interface VpcVirtualNetworkApplianceService extends VirtualNetworkApplian
/**
* @param router
* @param network
- * @param isRedundant
* @return
* @throws ConcurrentOperationException
* @throws ResourceUnavailableException
*/
boolean removeVpcRouterFromGuestNetwork(VirtualRouter router, Network network) throws ConcurrentOperationException, ResourceUnavailableException;
+
+ /**
+ * @param router
+ * @param network
+ * @return
+ * @throws ConcurrentOperationException
+ * @throws ResourceUnavailableException
+ */
+ boolean stopKeepAlivedOnRouter(VirtualRouter router, Network network) throws ConcurrentOperationException, ResourceUnavailableException;
+
+
+ /**
+ * @param router
+ * @param network
+ * @return
+ * @throws ConcurrentOperationException
+ * @throws ResourceUnavailableException
+ */
+ boolean startKeepAlivedOnRouter(VirtualRouter router, Network network) throws ConcurrentOperationException, ResourceUnavailableException;
+
}
diff --git a/api/src/main/java/com/cloud/network/element/BgpServiceProvider.java b/api/src/main/java/com/cloud/network/element/BgpServiceProvider.java
new file mode 100644
index 00000000000..ee919cb1af7
--- /dev/null
+++ b/api/src/main/java/com/cloud/network/element/BgpServiceProvider.java
@@ -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.
+package com.cloud.network.element;
+
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.vpc.Vpc;
+
+import org.apache.cloudstack.network.BgpPeer;
+
+import java.util.List;
+
+public interface BgpServiceProvider extends NetworkElement {
+
+ boolean applyBgpPeers(Vpc vpc, Network network, List extends BgpPeer> bgpPeers) throws ResourceUnavailableException;
+
+}
diff --git a/api/src/main/java/com/cloud/network/element/LoadBalancingServiceProvider.java b/api/src/main/java/com/cloud/network/element/LoadBalancingServiceProvider.java
index 1bb37be970d..dc0f60f4519 100644
--- a/api/src/main/java/com/cloud/network/element/LoadBalancingServiceProvider.java
+++ b/api/src/main/java/com/cloud/network/element/LoadBalancingServiceProvider.java
@@ -48,4 +48,7 @@ public interface LoadBalancingServiceProvider extends NetworkElement, IpDeployin
List updateHealthChecks(Network network, List lbrules);
boolean handlesOnlyRulesInTransitionState();
+
+ default void expungeLbVmRefs(List vmIds, Long batchSize) {
+ }
}
diff --git a/api/src/main/java/com/cloud/network/guru/NetworkGuru.java b/api/src/main/java/com/cloud/network/guru/NetworkGuru.java
index cbadbb18a8f..7b81c75ed84 100644
--- a/api/src/main/java/com/cloud/network/guru/NetworkGuru.java
+++ b/api/src/main/java/com/cloud/network/guru/NetworkGuru.java
@@ -212,4 +212,7 @@ public interface NetworkGuru extends Adapter {
boolean isMyTrafficType(TrafficType type);
+ default boolean isSlaacV6Only() {
+ return true;
+ }
}
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 3aab57d5d3d..38263f59667 100644
--- a/api/src/main/java/com/cloud/network/vpc/VpcOffering.java
+++ b/api/src/main/java/com/cloud/network/vpc/VpcOffering.java
@@ -18,6 +18,7 @@ package com.cloud.network.vpc;
import java.util.Date;
+import com.cloud.offering.NetworkOffering;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
@@ -57,7 +58,7 @@ public interface VpcOffering extends InternalIdentity, Identity {
boolean isForNsx();
- String getNsxMode();
+ NetworkOffering.NetworkMode getNetworkMode();
/**
* @return service offering id used by VPC virtual router
@@ -79,4 +80,8 @@ public interface VpcOffering extends InternalIdentity, Identity {
Date getRemoved();
Date getCreated();
+
+ NetworkOffering.RoutingMode getRoutingMode();
+
+ Boolean isSpecifyAsNumber();
}
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 1ce3cf8ab0e..10f1ddcc12d 100644
--- a/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java
+++ b/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java
@@ -24,6 +24,7 @@ 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;
+import com.cloud.offering.NetworkOffering;
import com.cloud.utils.Pair;
import com.cloud.utils.net.NetUtils;
@@ -36,8 +37,10 @@ public interface VpcProvisioningService {
VpcOffering createVpcOffering(String name, String displayText, List supportedServices,
Map> serviceProviders,
Map serviceCapabilitystList, NetUtils.InternetProtocol internetProtocol,
- Long serviceOfferingId, Boolean forNsx, String mode,
- List domainIds, List zoneIds, VpcOffering.State state);
+ Long serviceOfferingId, Boolean forNsx, NetworkOffering.NetworkMode networkMode,
+ List domainIds, List zoneIds, VpcOffering.State state,
+ NetworkOffering.RoutingMode routingMode, boolean specifyAsNumber);
+
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 2cdc034a16e..af2a9847a62 100644
--- a/api/src/main/java/com/cloud/network/vpc/VpcService.java
+++ b/api/src/main/java/com/cloud/network/vpc/VpcService.java
@@ -56,7 +56,8 @@ public interface VpcService {
* @throws ResourceAllocationException TODO
*/
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)
+ String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2, Boolean displayVpc, Integer publicMtu, Integer cidrSize,
+ Long asNumber, List bgpPeerIds)
throws ResourceAllocationException;
/**
@@ -132,6 +133,8 @@ public interface VpcService {
*/
boolean startVpc(long vpcId, boolean destroyOnFailure) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
+ void startVpc(CreateVPCCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
+
/**
* Shuts down the VPC which includes shutting down all VPC provider and rules cleanup on the backend
*
diff --git a/api/src/main/java/com/cloud/offering/NetworkOffering.java b/api/src/main/java/com/cloud/offering/NetworkOffering.java
index cf01fbf30e2..7011aea679e 100644
--- a/api/src/main/java/com/cloud/offering/NetworkOffering.java
+++ b/api/src/main/java/com/cloud/offering/NetworkOffering.java
@@ -43,11 +43,15 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription, PromiscuousMode, MacAddressChanges, ForgedTransmits, MacLearning, RelatedNetworkOffering, domainid, zoneid, pvlanType, internetProtocol
}
- public enum NsxMode {
+ public enum NetworkMode {
NATTED,
ROUTED
}
+ enum RoutingMode {
+ Static, Dynamic
+ }
+
public final static String SystemPublicNetwork = "System-Public-Network";
public final static String SystemControlNetwork = "System-Control-Network";
public final static String SystemManagementNetwork = "System-Management-Network";
@@ -102,7 +106,7 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
boolean isForNsx();
- String getNsxMode();
+ NetworkMode getNetworkMode();
TrafficType getTrafficType();
@@ -165,4 +169,8 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
String getServicePackage();
Date getCreated();
+
+ RoutingMode getRoutingMode();
+
+ Boolean isSpecifyAsNumber();
}
diff --git a/api/src/main/java/com/cloud/offering/ServiceOffering.java b/api/src/main/java/com/cloud/offering/ServiceOffering.java
index 58c7b0dbaf9..acb7a9f1cf9 100644
--- a/api/src/main/java/com/cloud/offering/ServiceOffering.java
+++ b/api/src/main/java/com/cloud/offering/ServiceOffering.java
@@ -33,6 +33,9 @@ public interface ServiceOffering extends InfrastructureEntity, InternalIdentity,
static final String internalLbVmDefaultOffUniqueName = "Cloud.Com-InternalLBVm";
// leaving cloud.com references as these are identifyers and no real world addresses (check against DB)
+
+ static final String PURGE_DB_ENTITIES_KEY = "purge.db.entities";
+
enum State {
Inactive, Active,
}
diff --git a/api/src/main/java/com/cloud/org/Cluster.java b/api/src/main/java/com/cloud/org/Cluster.java
index 4079c88dfde..5124168084c 100644
--- a/api/src/main/java/com/cloud/org/Cluster.java
+++ b/api/src/main/java/com/cloud/org/Cluster.java
@@ -16,6 +16,7 @@
// under the License.
package com.cloud.org;
+import com.cloud.cpu.CPU;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.org.Managed.ManagedState;
import org.apache.cloudstack.kernel.Partition;
@@ -38,4 +39,6 @@ public interface Cluster extends Grouping, Partition {
AllocationState getAllocationState();
ManagedState getManagedState();
+
+ CPU.CPUArch getArch();
}
diff --git a/api/src/main/java/com/cloud/storage/StorageService.java b/api/src/main/java/com/cloud/storage/StorageService.java
index c3609cfd8ee..b8df75cd3e4 100644
--- a/api/src/main/java/com/cloud/storage/StorageService.java
+++ b/api/src/main/java/com/cloud/storage/StorageService.java
@@ -21,6 +21,7 @@ import java.net.UnknownHostException;
import java.util.Map;
import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
+import org.apache.cloudstack.api.command.admin.storage.ChangeStoragePoolScopeCmd;
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
@@ -29,11 +30,13 @@ import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
import org.apache.cloudstack.api.command.admin.storage.SyncStoragePoolCmd;
import org.apache.cloudstack.api.command.admin.storage.UpdateObjectStoragePoolCmd;
+import org.apache.cloudstack.api.command.admin.storage.UpdateImageStoreCmd;
import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
import com.cloud.exception.DiscoveryException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.exception.ResourceUnavailableException;
import org.apache.cloudstack.api.command.admin.storage.heuristics.CreateSecondaryStorageSelectorCmd;
@@ -92,6 +95,10 @@ public interface StorageService {
StoragePool updateStoragePool(UpdateStoragePoolCmd cmd) throws IllegalArgumentException;
+ StoragePool enablePrimaryStoragePool(Long id);
+
+ StoragePool disablePrimaryStoragePool(Long id);
+
StoragePool getStoragePool(long id);
boolean deleteImageStore(DeleteImageStoreCmd cmd);
@@ -110,6 +117,8 @@ public interface StorageService {
*/
ImageStore migrateToObjectStore(String name, String url, String providerName, Map details) throws DiscoveryException;
+ ImageStore updateImageStore(UpdateImageStoreCmd cmd);
+
ImageStore updateImageStoreStatus(Long id, Boolean readonly);
void updateStorageCapabilities(Long poolId, boolean failOnChecks);
@@ -127,4 +136,6 @@ public interface StorageService {
boolean deleteObjectStore(DeleteObjectStoragePoolCmd cmd);
ObjectStore updateObjectStore(Long id, UpdateObjectStoragePoolCmd cmd);
+
+ void changeStoragePoolScope(ChangeStoragePoolScopeCmd cmd) throws IllegalArgumentException, InvalidParameterValueException, PermissionDeniedException;
}
diff --git a/api/src/main/java/com/cloud/storage/Upload.java b/api/src/main/java/com/cloud/storage/Upload.java
index 59d203ac73a..4e696e877cc 100644
--- a/api/src/main/java/com/cloud/storage/Upload.java
+++ b/api/src/main/java/com/cloud/storage/Upload.java
@@ -40,7 +40,7 @@ public interface Upload extends InternalIdentity, Identity {
}
public static enum Type {
- VOLUME, TEMPLATE, ISO
+ VOLUME, SNAPSHOT, TEMPLATE, ISO
}
public static enum Mode {
diff --git a/api/src/main/java/com/cloud/storage/Volume.java b/api/src/main/java/com/cloud/storage/Volume.java
index 40c5660b2df..c7fbdb0a544 100644
--- a/api/src/main/java/com/cloud/storage/Volume.java
+++ b/api/src/main/java/com/cloud/storage/Volume.java
@@ -271,11 +271,13 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
void setExternalUuid(String externalUuid);
- public Long getPassphraseId();
+ Long getPassphraseId();
- public void setPassphraseId(Long id);
+ void setPassphraseId(Long id);
- public String getEncryptFormat();
+ String getEncryptFormat();
- public void setEncryptFormat(String encryptFormat);
+ void setEncryptFormat(String encryptFormat);
+
+ boolean isDeleteProtection();
}
diff --git a/api/src/main/java/com/cloud/storage/VolumeApiService.java b/api/src/main/java/com/cloud/storage/VolumeApiService.java
index 4f09702b7db..6f4c7aa09e2 100644
--- a/api/src/main/java/com/cloud/storage/VolumeApiService.java
+++ b/api/src/main/java/com/cloud/storage/VolumeApiService.java
@@ -102,8 +102,12 @@ public interface VolumeApiService {
boolean deleteVolume(long volumeId, Account caller);
+ Volume changeDiskOfferingForVolumeInternal(Long volumeId, Long newDiskOfferingId, Long newSize, Long newMinIops, Long newMaxIops, boolean autoMigrateVolume, boolean shrinkOk) throws ResourceAllocationException;
+
Volume attachVolumeToVM(AttachVolumeCmd command);
+ Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId, Boolean allowAttachForSharedFS);
+
Volume detachVolumeViaDestroyVM(long vmId, long volumeId);
Volume detachVolumeFromVM(DetachVolumeCmd cmd);
@@ -113,7 +117,9 @@ public interface VolumeApiService {
Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType, List zoneIds) throws ResourceAllocationException;
- Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long owner, String chainInfo, String name);
+ Volume updateVolume(long volumeId, String path, String state, Long storageId,
+ Boolean displayVolume, Boolean deleteProtection,
+ String customId, long owner, String chainInfo, String name);
/**
* Extracts the volume to a particular location.
diff --git a/api/src/main/java/com/cloud/storage/snapshot/SnapshotApiService.java b/api/src/main/java/com/cloud/storage/snapshot/SnapshotApiService.java
index 0893f337ce2..67afd6aa4e2 100644
--- a/api/src/main/java/com/cloud/storage/snapshot/SnapshotApiService.java
+++ b/api/src/main/java/com/cloud/storage/snapshot/SnapshotApiService.java
@@ -21,6 +21,7 @@ import java.util.List;
import org.apache.cloudstack.api.command.user.snapshot.CopySnapshotCmd;
import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd;
import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd;
+import org.apache.cloudstack.api.command.user.snapshot.ExtractSnapshotCmd;
import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd;
import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd;
@@ -106,6 +107,16 @@ public interface SnapshotApiService {
*/
Snapshot createSnapshot(Long volumeId, Long policyId, Long snapshotId, Account snapshotOwner);
+ /**
+ * Extracts the snapshot to a particular location.
+ *
+ * @param cmd
+ * the command specifying url (where the snapshot needs to be extracted to), zoneId (zone where the snapshot exists) and
+ * id (the id of the snapshot)
+ *
+ */
+ String extractSnapshot(ExtractSnapshotCmd cmd);
+
/**
* Archives a snapshot from primary storage to secondary storage.
* @param id Snapshot ID
diff --git a/api/src/main/java/com/cloud/template/VirtualMachineTemplate.java b/api/src/main/java/com/cloud/template/VirtualMachineTemplate.java
index 6ed6ae0932d..89953d225a0 100644
--- a/api/src/main/java/com/cloud/template/VirtualMachineTemplate.java
+++ b/api/src/main/java/com/cloud/template/VirtualMachineTemplate.java
@@ -19,6 +19,7 @@ package com.cloud.template;
import java.util.Date;
import java.util.Map;
+import com.cloud.cpu.CPU;
import com.cloud.user.UserData;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.api.Identity;
@@ -150,4 +151,6 @@ public interface VirtualMachineTemplate extends ControlledEntity, Identity, Inte
UserData.UserDataOverridePolicy getUserDataOverridePolicy();
+ CPU.CPUArch getArch();
+
}
diff --git a/api/src/main/java/com/cloud/user/ResourceLimitService.java b/api/src/main/java/com/cloud/user/ResourceLimitService.java
index ba19719ea8d..2f4ad1347be 100644
--- a/api/src/main/java/com/cloud/user/ResourceLimitService.java
+++ b/api/src/main/java/com/cloud/user/ResourceLimitService.java
@@ -38,11 +38,18 @@ public interface ResourceLimitService {
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",
- "Time (in seconds) to wait before running resource recalculation and fixing task. Default is 300 seconds, Setting this to 0 disables execution of the task", true);
+ "Time (in seconds) to wait before running resource recalculation and fixing tasks like stale resource reservation cleanup" +
+ ". Default is 300 seconds, Setting this to 0 disables execution of the task", true);
+ static final ConfigKey ResourceReservationCleanupDelay = new ConfigKey<>("Advanced", Long.class, "resource.reservation.cleanup.delay", "3600",
+ "Time (in seconds) after which a resource reservation gets deleted. Default is 3600 seconds, Setting this to 0 disables execution of the task", true);
static final ConfigKey ResourceLimitHostTags = new ConfigKey<>("Advanced", String.class, "resource.limit.host.tags", "",
"A comma-separated list of tags for host resource limits", true);
static final ConfigKey ResourceLimitStorageTags = new ConfigKey<>("Advanced", String.class, "resource.limit.storage.tags", "",
"A comma-separated list of tags for storage resource limits", true);
+ static final ConfigKey DefaultMaxAccountProjects = new ConfigKey<>("Account Defaults",Long.class,"max.account.projects","10",
+ "The default maximum number of projects that can be created for an account",false);
+ static final ConfigKey DefaultMaxDomainProjects = new ConfigKey<>("Domain Defaults",Long.class,"max.domain.projects","50",
+ "The default maximum number of projects that can be created for a domain",false);
static final List HostTagsSupportingTypes = List.of(ResourceType.user_vm, ResourceType.cpu, ResourceType.memory);
static final List StorageTagsSupportingTypes = List.of(ResourceType.volume, ResourceType.primary_storage);
diff --git a/api/src/main/java/com/cloud/uservm/UserVm.java b/api/src/main/java/com/cloud/uservm/UserVm.java
index e30f5e03054..9035d2903c9 100644
--- a/api/src/main/java/com/cloud/uservm/UserVm.java
+++ b/api/src/main/java/com/cloud/uservm/UserVm.java
@@ -48,4 +48,6 @@ public interface UserVm extends VirtualMachine, ControlledEntity {
void setAccountId(long accountId);
public boolean isDisplayVm();
+
+ String getUserVmType();
}
diff --git a/api/src/main/java/com/cloud/vm/NicProfile.java b/api/src/main/java/com/cloud/vm/NicProfile.java
index d3c1daa1f5d..183c8dcb2d5 100644
--- a/api/src/main/java/com/cloud/vm/NicProfile.java
+++ b/api/src/main/java/com/cloud/vm/NicProfile.java
@@ -62,6 +62,7 @@ public class NicProfile implements InternalIdentity, Serializable {
String iPv4Dns1;
String iPv4Dns2;
String requestedIPv4;
+ boolean ipv4AllocationRaceCheck;
// IPv6
String iPv6Address;
@@ -405,6 +406,13 @@ public class NicProfile implements InternalIdentity, Serializable {
this.mtu = mtu;
}
+ public boolean getIpv4AllocationRaceCheck() {
+ return this.ipv4AllocationRaceCheck;
+ }
+
+ public void setIpv4AllocationRaceCheck(boolean ipv4AllocationRaceCheck) {
+ this.ipv4AllocationRaceCheck = ipv4AllocationRaceCheck;
+ }
//
// OTHER METHODS
diff --git a/api/src/main/java/com/cloud/vm/UserVmService.java b/api/src/main/java/com/cloud/vm/UserVmService.java
index 9d8b196a4ff..df7cdca5646 100644
--- a/api/src/main/java/com/cloud/vm/UserVmService.java
+++ b/api/src/main/java/com/cloud/vm/UserVmService.java
@@ -20,6 +20,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import com.cloud.deploy.DeploymentPlan;
import org.apache.cloudstack.api.BaseCmd.HTTPMethod;
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
@@ -42,9 +43,11 @@ import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
import com.cloud.dc.DataCenter;
+import com.cloud.deploy.DeploymentPlanner;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ManagementServerException;
+import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
@@ -66,10 +69,7 @@ public interface UserVmService {
/**
* Destroys one virtual machine
*
- * @param userId
- * the id of the user performing the action
- * @param vmId
- * the id of the virtual machine.
+ * @param cmd the API Command Object containg the parameters to use for this service action
* @throws ConcurrentOperationException
* @throws ResourceUnavailableException
*/
@@ -112,6 +112,12 @@ public interface UserVmService {
UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ResourceAllocationException;
+ void startVirtualMachine(UserVm vm, DeploymentPlan plan) throws OperationTimedoutException, ResourceUnavailableException, InsufficientCapacityException;
+
+ void startVirtualMachineForHA(VirtualMachine vm, Map params,
+ DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException,
+ ConcurrentOperationException, OperationTimedoutException;
+
UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException;
/**
@@ -148,14 +154,6 @@ public interface UserVmService {
* Creates a Basic Zone User VM in the database and returns the VM to the
* caller.
*
- *
- *
- * @param sshKeyPair
- * - name of the ssh key pair used to login to the virtual
- * machine
- * @param cpuSpeed
- * @param memory
- * @param cpuNumber
* @param zone
* - availability zone for the virtual machine
* @param serviceOffering
@@ -231,9 +229,6 @@ public interface UserVmService {
* Creates a User VM in Advanced Zone (Security Group feature is enabled) in
* the database and returns the VM to the caller.
*
- *
- *
- * @param type
* @param zone
* - availability zone for the virtual machine
* @param serviceOffering
@@ -309,14 +304,6 @@ public interface UserVmService {
* Creates a User VM in Advanced Zone (Security Group feature is disabled)
* in the database and returns the VM to the caller.
*
- *
- *
- * @param sshKeyPair
- * - name of the ssh key pair used to login to the virtual
- * machine
- * @param cpuSpeed
- * @param memory
- * @param cpuNumber
* @param zone
* - availability zone for the virtual machine
* @param serviceOffering
diff --git a/api/src/main/java/com/cloud/vm/VirtualMachine.java b/api/src/main/java/com/cloud/vm/VirtualMachine.java
index e7c5efb773b..e2ea408e7b8 100644
--- a/api/src/main/java/com/cloud/vm/VirtualMachine.java
+++ b/api/src/main/java/com/cloud/vm/VirtualMachine.java
@@ -333,6 +333,8 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Partition,
*/
Date getCreated();
+ Date getRemoved();
+
long getServiceOfferingId();
Long getBackupOfferingId();
diff --git a/api/src/main/java/com/cloud/vm/VirtualMachineProfile.java b/api/src/main/java/com/cloud/vm/VirtualMachineProfile.java
index f2ff3da8449..c67ee4eabc2 100644
--- a/api/src/main/java/com/cloud/vm/VirtualMachineProfile.java
+++ b/api/src/main/java/com/cloud/vm/VirtualMachineProfile.java
@@ -192,6 +192,10 @@ public interface VirtualMachineProfile {
Map getParameters();
+ void setCpuOvercommitRatio(Float cpuOvercommitRatio);
+
+ void setMemoryOvercommitRatio(Float memoryOvercommitRatio);
+
Float getCpuOvercommitRatio();
Float getMemoryOvercommitRatio();
diff --git a/api/src/main/java/org/apache/cloudstack/acl/Role.java b/api/src/main/java/org/apache/cloudstack/acl/Role.java
index 5e5ffd583d8..ce4166ef4c8 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/Role.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/Role.java
@@ -21,7 +21,18 @@ import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
public interface Role extends RoleEntity, InternalIdentity, Identity {
+
+ enum State {
+ ENABLED, DISABLED;
+
+ @Override
+ public String toString(){
+ return super.toString().toLowerCase();
+ }
+ }
+
RoleType getRoleType();
boolean isDefault();
boolean isPublicRole();
+ State getState();
}
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 07f62a7e7f8..68204d43253 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/RoleService.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/RoleService.java
@@ -54,6 +54,10 @@ public interface RoleService {
boolean deleteRole(Role role);
+ boolean enableRole(Role role);
+
+ boolean disableRole(Role role);
+
RolePermission findRolePermission(Long id);
RolePermission findRolePermissionByRoleIdAndRule(Long roleId, String rule);
@@ -76,7 +80,7 @@ public interface RoleService {
*/
List listRoles();
- Pair, Integer> listRoles(Long startIndex, Long limit);
+ Pair, Integer> listRoles(String state, Long startIndex, Long limit);
/**
* Find all roles that have the giving {@link String} as part of their name.
@@ -84,14 +88,14 @@ public interface RoleService {
*/
List findRolesByName(String name);
- Pair, Integer> findRolesByName(String name, String keyword, Long startIndex, Long limit);
+ Pair, Integer> findRolesByName(String name, String keyword, String state, Long startIndex, Long limit);
/**
* Find all roles by {@link RoleType}. If the role type is {@link RoleType#Admin}, the calling account must be a root admin, otherwise we return an empty list.
*/
List findRolesByType(RoleType roleType);
- Pair, Integer> findRolesByType(RoleType roleType, Long startIndex, Long limit);
+ Pair, Integer> findRolesByType(RoleType roleType, String state, Long startIndex, Long limit);
List findAllPermissionsBy(Long roleId);
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 22842b834fe..69f391a5656 100644
--- a/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupResponse.java
@@ -25,6 +25,7 @@ import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import org.apache.cloudstack.api.response.ControlledViewEntityResponse;
+import org.apache.cloudstack.dedicated.DedicatedResourceResponse;
import com.cloud.serializer.Param;
@@ -56,6 +57,10 @@ public class AffinityGroupResponse extends BaseResponse implements ControlledVie
@Param(description = "the domain name of the affinity group")
private String domainName;
+ @SerializedName(ApiConstants.DOMAIN_PATH)
+ @Param(description = "path of the Domain the affinity group belongs to", since = "4.19.2.0")
+ private String domainPath;
+
@SerializedName(ApiConstants.PROJECT_ID)
@Param(description = "the project ID of the affinity group")
private String projectId;
@@ -72,6 +77,10 @@ public class AffinityGroupResponse extends BaseResponse implements ControlledVie
@Param(description = "virtual machine IDs associated with this affinity group")
private List vmIdList;
+ @SerializedName("dedicatedresources")
+ @Param(description = "dedicated resources associated with this affinity group")
+ private List dedicatedResources;
+
public AffinityGroupResponse() {
}
@@ -115,6 +124,11 @@ public class AffinityGroupResponse extends BaseResponse implements ControlledVie
this.domainName = domainName;
}
+ @Override
+ public void setDomainPath(String domainPath) {
+ this.domainPath = domainPath;
+ }
+
@Override
public int hashCode() {
final int prime = 31;
@@ -162,4 +176,12 @@ public class AffinityGroupResponse extends BaseResponse implements ControlledVie
this.vmIdList.add(vmId);
}
+ public void addDedicatedResource(DedicatedResourceResponse dedicatedResourceResponse) {
+ if (this.dedicatedResources == null) {
+ this.dedicatedResources = new ArrayList<>();
+ }
+
+ this.dedicatedResources.add(dedicatedResourceResponse);
+ }
+
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiArgValidator.java b/api/src/main/java/org/apache/cloudstack/api/ApiArgValidator.java
index 3e06fc0e44e..38047235273 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiArgValidator.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiArgValidator.java
@@ -32,4 +32,9 @@ public enum ApiArgValidator {
* Validates if the parameter is an UUID with the method {@link UuidUtils#isUuid(String)}.
*/
UuidString,
+
+ /**
+ * Validates if the parameter is a valid RFC Compliance domain name.
+ */
+ RFCComplianceDomainName,
}
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 38efa428726..a5bedc65d9c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java
@@ -17,7 +17,9 @@
package org.apache.cloudstack.api;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.cloudstack.region.PortableIp;
import org.apache.commons.collections.CollectionUtils;
@@ -82,15 +84,22 @@ public enum ApiCommandResourceType {
ObjectStore(org.apache.cloudstack.storage.object.ObjectStore.class),
Bucket(org.apache.cloudstack.storage.object.Bucket.class),
QuotaTariff(org.apache.cloudstack.quota.QuotaTariff.class),
- KubernetesCluster(com.cloud.kubernetes.cluster.KubernetesCluster.class);
+ KubernetesCluster(com.cloud.kubernetes.cluster.KubernetesCluster.class),
+ KubernetesSupportedVersion(null),
+ SharedFS(org.apache.cloudstack.storage.sharedfs.SharedFS.class);
private final Class> clazz;
+ static final Map> additionalClassMappings = new HashMap<>();
+
private ApiCommandResourceType(Class> clazz) {
this.clazz = clazz;
}
public Class> getAssociatedClass() {
+ if (this.clazz == null && additionalClassMappings.containsKey(this)) {
+ return additionalClassMappings.get(this);
+ }
return this.clazz;
}
@@ -120,4 +129,8 @@ public enum ApiCommandResourceType {
}
return null;
}
+
+ public static void setClassMapping(ApiCommandResourceType type, Class> clazz) {
+ additionalClassMappings.put(type, clazz);
+ }
}
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 7943ed0b1ee..cf667063e38 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
@@ -29,10 +29,18 @@ public class ApiConstants {
public static final String ADDRESS = "address";
public static final String ALGORITHM = "algorithm";
public static final String ALIAS = "alias";
+ public static final String ALLOCATED_DATE = "allocateddate";
public static final String ALLOCATED_ONLY = "allocatedonly";
+ public static final String ALLOCATED_TIME = "allocated";
+ public static final String ALLOW_USER_FORCE_STOP_VM = "allowuserforcestopvm";
public static final String ANNOTATION = "annotation";
public static final String API_KEY = "apikey";
public static final String ARCHIVED = "archived";
+ public static final String ARCH = "arch";
+ public static final String AS_NUMBER = "asnumber";
+ 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 ASYNC_BACKUP = "asyncbackup";
public static final String AUTO_SELECT = "autoselect";
public static final String USER_API_KEY = "userapikey";
@@ -46,6 +54,8 @@ public class ApiConstants {
public static final String BACKUP_OFFERING_NAME = "backupofferingname";
public static final String BACKUP_OFFERING_ID = "backupofferingid";
public static final String BASE64_IMAGE = "base64image";
+ public static final String BGP_PEERS = "bgppeers";
+ public static final String BGP_PEER_IDS = "bgppeerids";
public static final String BITS = "bits";
public static final String BOOTABLE = "bootable";
public static final String BIND_DN = "binddn";
@@ -87,6 +97,8 @@ public class ApiConstants {
public static final String DNS_SEARCH_ORDER = "dnssearchorder";
public static final String CHAIN_INFO = "chaininfo";
public static final String CIDR = "cidr";
+ public static final String CIDR_SIZE = "cidrsize";
+
public static final String IP6_CIDR = "ip6cidr";
public static final String CIDR_LIST = "cidrlist";
public static final String DEST_CIDR_LIST = "destcidrlist";
@@ -127,6 +139,7 @@ public class ApiConstants {
public static final String DATACENTER_NAME = "datacentername";
public static final String DATADISK_OFFERING_LIST = "datadiskofferinglist";
public static final String DEFAULT_VALUE = "defaultvalue";
+ public static final String DELETE_PROTECTION = "deleteprotection";
public static final String DESCRIPTION = "description";
public static final String DESTINATION = "destination";
public static final String DESTINATION_ZONE_ID = "destzoneid";
@@ -171,11 +184,14 @@ public class ApiConstants {
public static final String DURATION = "duration";
public static final String ELIGIBLE = "eligible";
public static final String EMAIL = "email";
+ public static final String END_ASN = "endasn";
public static final String END_DATE = "enddate";
public static final String END_IP = "endip";
public static final String END_IPV6 = "endipv6";
public static final String END_PORT = "endport";
public static final String ENTRY_TIME = "entrytime";
+ public static final String EVENT_ID = "eventid";
+ public static final String EVENT_TYPE = "eventtype";
public static final String EXPIRES = "expires";
public static final String EXTRA_CONFIG = "extraconfig";
public static final String EXTRA_DHCP_OPTION = "extradhcpoption";
@@ -186,10 +202,12 @@ public class ApiConstants {
public static final String EXTERNAL_UUID = "externaluuid";
public static final String FENCE = "fence";
public static final String FETCH_LATEST = "fetchlatest";
+ public static final String FILESYSTEM = "filesystem";
public static final String FIRSTNAME = "firstname";
public static final String FORCED = "forced";
public static final String FORCED_DESTROY_LOCAL_STORAGE = "forcedestroylocalstorage";
public static final String FORCE_DELETE_HOST = "forcedeletehost";
+ public static final String FORCE_MS_TO_IMPORT_VM_FILES = "forcemstoimportvmfiles";
public static final String FORMAT = "format";
public static final String FOR_VIRTUAL_NETWORK = "forvirtualnetwork";
public static final String FOR_SYSTEM_VMS = "forsystemvms";
@@ -210,6 +228,7 @@ public class ApiConstants {
public static final String HA_PROVIDER = "haprovider";
public static final String HA_STATE = "hastate";
public static final String HEALTH = "health";
+ public static final String HEADERS = "headers";
public static final String HIDE_IP_ADDRESS_USAGE = "hideipaddressusage";
public static final String HOST_ID = "hostid";
public static final String HOST_IDS = "hostids";
@@ -237,6 +256,7 @@ public class ApiConstants {
public static final String NEXT_ACL_RULE_ID = "nextaclruleid";
public static final String MOVE_ACL_CONSISTENCY_HASH = "aclconsistencyhash";
public static final String IMAGE_PATH = "imagepath";
+ public static final String INSTANCE_CONVERSION_SUPPORTED = "instanceconversionsupported";
public static final String INTERNAL_DNS1 = "internaldns1";
public static final String INTERNAL_DNS2 = "internaldns2";
public static final String INTERNET_PROTOCOL = "internetprotocol";
@@ -264,6 +284,7 @@ public class ApiConstants {
public static final String IS_CLEANUP_REQUIRED = "iscleanuprequired";
public static final String IS_DYNAMIC = "isdynamic";
public static final String IS_EDGE = "isedge";
+ public static final String IS_ENCRYPTED = "isencrypted";
public static final String IS_EXTRACTABLE = "isextractable";
public static final String IS_FEATURED = "isfeatured";
public static final String IS_IMPLICIT = "isimplicit";
@@ -282,6 +303,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 KEY = "key";
public static final String LABEL = "label";
public static final String LASTNAME = "lastname";
public static final String LAST_BOOT = "lastboottime";
@@ -309,7 +331,9 @@ public class ApiConstants {
public static final String MEMORY = "memory";
public static final String MODE = "mode";
public static final String MOUNT_CKS_ISO_ON_VR = "mountcksisoonvr";
+ public static final String MULTI_ARCH = "ismultiarch";
public static final String NSX_MODE = "nsxmode";
+ public static final String NETWORK_MODE = "networkmode";
public static final String NSX_ENABLED = "isnsxenabled";
public static final String NAME = "name";
public static final String METHOD_NAME = "methodname";
@@ -351,6 +375,7 @@ public class ApiConstants {
public static final String PARENT = "parent";
public static final String PARENT_ID = "parentid";
public static final String PARENT_DOMAIN_ID = "parentdomainid";
+ public static final String PARENT_SUBNET = "parentsubnet";
public static final String PARENT_TEMPLATE_ID = "parenttemplateid";
public static final String PASSWORD = "password";
public static final String CURRENT_PASSWORD = "currentpassword";
@@ -359,6 +384,7 @@ public class ApiConstants {
public static final String SSHKEY_ENABLED = "sshkeyenabled";
public static final String PATH = "path";
public static final String PAYLOAD = "payload";
+ public static final String PAYLOAD_URL = "payloadurl";
public static final String POD_ID = "podid";
public static final String POD_NAME = "podname";
public static final String POD_IDS = "podids";
@@ -386,6 +412,7 @@ public class ApiConstants {
public static final String PUBLIC_START_PORT = "publicport";
public static final String PUBLIC_END_PORT = "publicendport";
public static final String PUBLIC_ZONE = "publiczone";
+ public static final String PURGE_RESOURCES = "purgeresources";
public static final String RECEIVED_BYTES = "receivedbytes";
public static final String RECONNECT = "reconnect";
public static final String RECOVER = "recover";
@@ -404,11 +431,9 @@ public class ApiConstants {
public static final String QUERY_FILTER = "queryfilter";
public static final String SCHEDULE = "schedule";
public static final String SCOPE = "scope";
- public static final String SECRET_KEY = "usersecretkey";
- public static final String SECONDARY_IP = "secondaryip";
- public static final String SINCE = "since";
- public static final String KEY = "key";
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";
@@ -426,15 +451,17 @@ public class ApiConstants {
public static final String SHOW_UNIQUE = "showunique";
public static final String SIGNATURE = "signature";
public static final String SIGNATURE_VERSION = "signatureversion";
+ public static final String SINCE = "since";
public static final String SIZE = "size";
+ public static final String SIZEGB = "sizegb";
public static final String SNAPSHOT = "snapshot";
public static final String SNAPSHOT_ID = "snapshotid";
public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid";
public static final String SNAPSHOT_TYPE = "snapshottype";
public static final String SNAPSHOT_QUIESCEVM = "quiescevm";
public static final String SOURCE_ZONE_ID = "sourcezoneid";
- public static final String SUITABLE_FOR_VM = "suitableforvirtualmachine";
- public static final String SUPPORTS_STORAGE_SNAPSHOT = "supportsstoragesnapshot";
+ public static final String SSL_VERIFICATION = "sslverification";
+ public static final String START_ASN = "startasn";
public static final String START_DATE = "startdate";
public static final String START_ID = "startid";
public static final String START_IP = "startip";
@@ -447,12 +474,16 @@ public class ApiConstants {
public static final String STORAGE_POLICY = "storagepolicy";
public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
public static final String STORAGE_CAPABILITIES = "storagecapabilities";
+ public static final String STORAGE_CUSTOM_STATS = "storagecustomstats";
public static final String SUBNET = "subnet";
public static final String OWNER = "owner";
public static final String SWAP_OWNER = "swapowner";
public static final String SYSTEM_VM_TYPE = "systemvmtype";
public static final String TAGS = "tags";
public static final String STORAGE_TAGS = "storagetags";
+ public static final String SUCCESS = "success";
+ 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 TEMPLATE_FILTER = "templatefilter";
public static final String TEMPLATE_ID = "templateid";
@@ -486,6 +517,7 @@ public class ApiConstants {
public static final String USERNAME = "username";
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_VIRTUAL_NETWORK = "usevirtualnetwork";
public static final String UPDATE_IN_SEQUENCE = "updateinsequence";
public static final String VALUE = "value";
@@ -495,6 +527,7 @@ public class ApiConstants {
public static final String VIRTUAL_MACHINE_ID_IP = "vmidipmap";
public static final String VIRTUAL_MACHINE_COUNT = "virtualmachinecount";
public static final String VIRTUAL_MACHINE_TYPE = "virtualmachinetype";
+ 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_TYPE = "usagetype";
@@ -513,6 +546,7 @@ public class ApiConstants {
public static final String ISOLATED_PVLAN = "isolatedpvlan";
public static final String ISOLATED_PVLAN_TYPE = "isolatedpvlantype";
public static final String ISOLATION_URI = "isolationuri";
+ public static final String IS_ALLOCATED = "isallocated";
public static final String IS_DEDICATED = "isdedicated";
public static final String TAKEN = "taken";
public static final String VM_AVAILABLE = "vmavailable";
@@ -541,6 +575,7 @@ public class ApiConstants {
public static final String NETWORK_ID = "networkid";
public static final String NETWORK_FILTER = "networkfilter";
public static final String NIC_ID = "nicid";
+ public static final String SPECIFY_AS_NUMBER = "specifyasnumber";
public static final String SPECIFY_VLAN = "specifyvlan";
public static final String IS_DEFAULT = "isdefault";
public static final String IS_SYSTEM = "issystem";
@@ -571,6 +606,7 @@ public class ApiConstants {
public static final String ALLOCATION_STATE = "allocationstate";
public static final String MANAGED_STATE = "managedstate";
public static final String MANAGEMENT_SERVER_ID = "managementserverid";
+ public static final String MANAGEMENT_SERVER_NAME = "managementservername";
public static final String STORAGE = "storage";
public static final String STORAGE_ID = "storageid";
public static final String PING_STORAGE_SERVER_IP = "pingstorageserverip";
@@ -590,6 +626,7 @@ public class ApiConstants {
public static final String AGGREGATE_NAME = "aggregatename";
public static final String POOL_NAME = "poolname";
public static final String VOLUME_NAME = "volumename";
+ public static final String VOLUME_STATE = "volumestate";
public static final String SNAPSHOT_POLICY = "snapshotpolicy";
public static final String SNAPSHOT_RESERVATION = "snapshotreservation";
public static final String IP_NETWORK_LIST = "iptonetworklist";
@@ -680,6 +717,8 @@ public class ApiConstants {
public static final String ASSOCIATED_NETWORK = "associatednetwork";
public static final String ASSOCIATED_NETWORK_ID = "associatednetworkid";
public static final String ASSOCIATED_NETWORK_NAME = "associatednetworkname";
+ public static final String ASSOCIATED_VPC_ID = "associatedvpcid";
+ public static final String ASSOCIATED_VPC_NAME = "associatedvpcname";
public static final String SOURCE_NAT_SUPPORTED = "sourcenatsupported";
public static final String RESOURCE_STATE = "resourcestate";
public static final String PROJECT_INVITE_REQUIRED = "projectinviterequired";
@@ -692,8 +731,11 @@ public class ApiConstants {
public static final String TRAFFIC_TYPE_IMPLEMENTOR = "traffictypeimplementor";
public static final String KEYWORD = "keyword";
public static final String LIST_ALL = "listall";
+ public static final String LIST_ONLY_REMOVED = "listonlyremoved";
public static final String LIST_SYSTEM_VMS = "listsystemvms";
public static final String IP_RANGES = "ipranges";
+ public static final String IPV4_ROUTING = "ip4routing";
+ public static final String IPV4_ROUTES = "ip4routes";
public static final String IPV6_ROUTING = "ip6routing";
public static final String IPV6_ROUTES = "ip6routes";
public static final String SPECIFY_IP_RANGES = "specifyipranges";
@@ -911,6 +953,7 @@ public class ApiConstants {
public static final String AUTOSCALE_VMGROUP_NAME = "autoscalevmgroupname";
public static final String BAREMETAL_DISCOVER_NAME = "baremetaldiscovername";
public static final String BAREMETAL_RCT_URL = "baremetalrcturl";
+ public static final String BATCH_SIZE = "batchsize";
public static final String UCS_DN = "ucsdn";
public static final String GSLB_PROVIDER = "gslbprovider";
public static final String EXCLUSIVE_GSLB_PROVIDER = "isexclusivegslbprovider";
@@ -955,6 +998,7 @@ public class ApiConstants {
public static final String NUMBER = "number";
public static final String IS_DYNAMICALLY_SCALABLE = "isdynamicallyscalable";
public static final String ROUTING = "isrouting";
+ public static final String ROUTING_MODE = "routingmode";
public static final String MAX_CONNECTIONS = "maxconnections";
public static final String SERVICE_STATE = "servicestate";
@@ -1138,6 +1182,20 @@ public class ApiConstants {
public static final String PARAMETER_DESCRIPTION_IS_TAG_A_RULE = "Whether the informed tag is a JS interpretable rule or not.";
+ public static final String WEBHOOK_ID = "webhookid";
+ public static final String WEBHOOK_NAME = "webhookname";
+
+ public static final String NFS_MOUNT_OPTIONS = "nfsmountopts";
+ public static final String MOUNT_OPTIONS = "mountopts";
+
+ public static final String SHAREDFSVM_MIN_CPU_COUNT = "sharedfsvmmincpucount";
+ public static final String SHAREDFSVM_MIN_RAM_SIZE = "sharedfsvmminramsize";
+
+ 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 " +
+ "value will be applied.";
+
/**
* 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 54fda7e36b8..cbbcdc3bda4 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiServerService.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiServerService.java
@@ -21,7 +21,9 @@ import java.util.Map;
import javax.servlet.http.HttpSession;
+import com.cloud.domain.Domain;
import com.cloud.exception.CloudAuthenticationException;
+import com.cloud.user.UserAccount;
public interface ApiServerService {
public boolean verifyRequest(Map requestParameters, Long userId, InetAddress remoteAddress) throws ServerApiException;
@@ -42,4 +44,8 @@ public interface ApiServerService {
public String handleRequest(Map params, String responseType, StringBuilder auditTrailSb) throws ServerApiException;
public Class> getCmdClass(String cmdName);
+
+ boolean forgotPassword(UserAccount userAccount, Domain domain);
+
+ boolean resetPassword(UserAccount userAccount, String token, String password);
}
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 b206cd011c1..457afdc8847 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java
@@ -31,6 +31,7 @@ import java.util.regex.Pattern;
import javax.inject.Inject;
+import com.cloud.bgp.BGPService;
import org.apache.cloudstack.acl.ProjectRoleService;
import org.apache.cloudstack.acl.RoleService;
import org.apache.cloudstack.acl.RoleType;
@@ -38,6 +39,7 @@ import org.apache.cloudstack.affinity.AffinityGroupService;
import org.apache.cloudstack.alert.AlertService;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.network.RoutedIpv4Manager;
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService;
import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService;
import org.apache.cloudstack.query.QueryService;
@@ -217,7 +219,11 @@ public abstract class BaseCmd {
public VnfTemplateManager vnfTemplateManager;
@Inject
public BucketApiService _bucketService;
+ @Inject
+ public BGPService bgpService;
+ @Inject
+ public RoutedIpv4Manager routedIpv4Manager;
public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException, NetworkRuleConflictException;
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 e3aead6881b..9a8282df112 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
@@ -16,8 +16,10 @@
// under the License.
package org.apache.cloudstack.api;
+import com.cloud.cpu.CPU;
import org.apache.cloudstack.api.response.GuestOSResponse;
import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.commons.lang3.StringUtils;
import java.util.Collection;
import java.util.Map;
@@ -77,6 +79,11 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd {
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",
+ since = "4.20")
+ private String arch;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -141,4 +148,11 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd {
public boolean isCleanupDetails(){
return cleanupDetails == null ? false : cleanupDetails.booleanValue();
}
+
+ public CPU.CPUArch getCPUArch() {
+ if (StringUtils.isBlank(arch)) {
+ return null;
+ }
+ return CPU.CPUArch.fromType(arch);
+ }
}
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 ef759aaf9c3..ea0d946ee41 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
@@ -22,6 +22,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import com.cloud.bgp.ASNumber;
+import com.cloud.bgp.ASNumberRange;
+
import org.apache.cloudstack.storage.object.Bucket;
import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
@@ -31,11 +34,14 @@ import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse;
+import org.apache.cloudstack.api.response.ASNRangeResponse;
+import org.apache.cloudstack.api.response.ASNumberResponse;
import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
import org.apache.cloudstack.api.response.BackupOfferingResponse;
+import org.apache.cloudstack.api.response.BackupRepositoryResponse;
import org.apache.cloudstack.api.response.BackupResponse;
import org.apache.cloudstack.api.response.BackupScheduleResponse;
import org.apache.cloudstack.api.response.BucketResponse;
@@ -54,6 +60,7 @@ import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.DomainRouterResponse;
import org.apache.cloudstack.api.response.EventResponse;
import org.apache.cloudstack.api.response.ExtractResponse;
+import org.apache.cloudstack.api.response.SharedFSResponse;
import org.apache.cloudstack.api.response.FirewallResponse;
import org.apache.cloudstack.api.response.FirewallRuleResponse;
import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
@@ -139,6 +146,7 @@ import org.apache.cloudstack.api.response.VpnUsersResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.backup.Backup;
import org.apache.cloudstack.backup.BackupOffering;
+import org.apache.cloudstack.backup.BackupRepository;
import org.apache.cloudstack.backup.BackupSchedule;
import org.apache.cloudstack.config.Configuration;
import org.apache.cloudstack.config.ConfigurationGroup;
@@ -151,6 +159,7 @@ import org.apache.cloudstack.region.PortableIp;
import org.apache.cloudstack.region.PortableIpRange;
import org.apache.cloudstack.region.Region;
import org.apache.cloudstack.secstorage.heuristics.Heuristic;
+import org.apache.cloudstack.storage.sharedfs.SharedFS;
import org.apache.cloudstack.storage.object.ObjectStore;
import org.apache.cloudstack.usage.Usage;
@@ -345,9 +354,11 @@ public interface ResponseGenerator {
SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group);
- ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url);
+ ExtractResponse createImageExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url);
- ExtractResponse createExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url);
+ ExtractResponse createVolumeExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url);
+
+ ExtractResponse createSnapshotExtractResponse(Long id, Long zoneId, Long accountId, String url);
String toSerializedString(CreateCmdResponse response, String responseType);
@@ -549,4 +560,12 @@ public interface ResponseGenerator {
ObjectStoreResponse createObjectStoreResponse(ObjectStore os);
BucketResponse createBucketResponse(Bucket bucket);
+
+ ASNRangeResponse createASNumberRangeResponse(ASNumberRange asnRange);
+
+ ASNumberResponse createASNumberResponse(ASNumber asn);
+
+ BackupRepositoryResponse createBackupRepositoryResponse(BackupRepository repository);
+
+ SharedFSResponse createSharedFSResponse(ResponseView view, SharedFS sharedFS);
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/auth/APIAuthenticationType.java b/api/src/main/java/org/apache/cloudstack/api/auth/APIAuthenticationType.java
index 5ba9d182daa..1f78708f7e5 100644
--- a/api/src/main/java/org/apache/cloudstack/api/auth/APIAuthenticationType.java
+++ b/api/src/main/java/org/apache/cloudstack/api/auth/APIAuthenticationType.java
@@ -17,5 +17,5 @@
package org.apache.cloudstack.api.auth;
public enum APIAuthenticationType {
- LOGIN_API, LOGOUT_API, READONLY_API, LOGIN_2FA_API
+ LOGIN_API, LOGOUT_API, READONLY_API, LOGIN_2FA_API, PASSWORD_RESET
}
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 36e22acff91..a90fc4aebe9 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
@@ -89,12 +89,11 @@ public class DeleteAccountCmd extends BaseAsyncCmd {
CallContext.current().setEventDetails("Account ID: " + (account != null ? account.getUuid() : getId())); // Account not found is already handled by service
boolean result = _regionService.deleteUserAccount(this);
- if (result) {
- SuccessResponse response = new SuccessResponse(getCommandName());
- setResponseObject(response);
- } else {
+ if (!result) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete user account and all corresponding users");
}
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ setResponseObject(response);
}
@Override
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
new file mode 100644
index 00000000000..80cb92c8362
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DisableRoleCmd.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
+// 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.acl;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import org.apache.cloudstack.acl.Role;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiArgValidator;
+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.RoleResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+
+@APICommand(name = "disableRole", description = "Disables a role", responseObject = SuccessResponse.class,
+ requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+ since = "4.20.0",
+ authorized = {RoleType.Admin})
+public class DisableRoleCmd extends BaseCmd {
+
+ @Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, required = true, entityType = RoleResponse.class,
+ description = "ID of the role", validations = {ApiArgValidator.PositiveNumber})
+ private Long roleId;
+
+ public Long getRoleId() {
+ return roleId;
+ }
+
+ @Override
+ public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
+ Role role = roleService.findRole(getRoleId());
+ if (role == null) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find the role with provided id");
+ }
+ CallContext.current().setEventDetails("Role id: " + role.getId());
+ boolean result = roleService.disableRole(role);
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ response.setSuccess(result);
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
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
new file mode 100644
index 00000000000..c4a6505d52f
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/EnableRoleCmd.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
+// 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.acl;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import org.apache.cloudstack.acl.Role;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiArgValidator;
+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.RoleResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+
+@APICommand(name = "enableRole", description = "Enables a role", responseObject = SuccessResponse.class,
+ requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+ since = "4.20.0",
+ authorized = {RoleType.Admin})
+public class EnableRoleCmd extends BaseCmd {
+
+ @Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, required = true, entityType = RoleResponse.class,
+ description = "ID of the role", validations = {ApiArgValidator.PositiveNumber})
+ private Long roleId;
+
+ public Long getRoleId() {
+ return roleId;
+ }
+
+ @Override
+ public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
+ Role role = roleService.findRole(getRoleId());
+ if (role == null) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find the role with provided id");
+ }
+ CallContext.current().setEventDetails("Role id: " + role.getId());
+ boolean result = roleService.enableRole(role);
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ response.setSuccess(result);
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/ListRolesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/ListRolesCmd.java
index fef2b27eaa5..d82cc852e4f 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/ListRolesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/ListRolesCmd.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import com.cloud.exception.InvalidParameterValueException;
import org.apache.cloudstack.acl.Role;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
@@ -51,6 +52,9 @@ public class ListRolesCmd extends BaseListCmd {
@Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "List role by role type, valid options are: Admin, ResourceAdmin, DomainAdmin, User.")
private String roleType;
+ @Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "List role by role type status, valid options are: enabled, disabled")
+ private String roleState;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -70,6 +74,17 @@ public class ListRolesCmd extends BaseListCmd {
return null;
}
+ public Role.State getRoleState() {
+ if (roleState == null) {
+ return null;
+ }
+ try {
+ return Role.State.valueOf(roleState.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ throw new InvalidParameterValueException("Unrecognized role state value");
+ }
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@@ -93,6 +108,7 @@ public class ListRolesCmd extends BaseListCmd {
roleResponse.setDescription(role.getDescription());
roleResponse.setIsDefault(role.isDefault());
roleResponse.setPublicRole(role.isPublicRole());
+ roleResponse.setState(role.getState().toString());
roleResponse.setObjectName("role");
roleResponses.add(roleResponse);
}
@@ -104,14 +120,16 @@ public class ListRolesCmd extends BaseListCmd {
@Override
public void execute() {
Pair, Integer> roles;
+ Role.State state = getRoleState();
+ String roleStateStr = state != null ? state.toString() : null;
if (getId() != null && getId() > 0L) {
roles = new Pair<>(Collections.singletonList(roleService.findRole(getId(), true)), 1);
} else if (StringUtils.isNotBlank(getName()) || StringUtils.isNotBlank(getKeyword())) {
- roles = roleService.findRolesByName(getName(), getKeyword(), getStartIndex(), getPageSizeVal());
+ roles = roleService.findRolesByName(getName(), getKeyword(), roleStateStr, getStartIndex(), getPageSizeVal());
} else if (getRoleType() != null) {
- roles = roleService.findRolesByType(getRoleType(), getStartIndex(), getPageSizeVal());
+ roles = roleService.findRolesByType(getRoleType(), roleStateStr, getStartIndex(), getPageSizeVal());
} else {
- roles = roleService.listRoles(getStartIndex(), getPageSizeVal());
+ roles = roleService.listRoles(roleStateStr, getStartIndex(), getPageSizeVal());
}
setupResponse(roles);
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/RoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/RoleCmd.java
index 4c317d06b13..b3d816adc3f 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/RoleCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/RoleCmd.java
@@ -59,6 +59,7 @@ public abstract class RoleCmd extends BaseCmd {
response.setRoleType(role.getRoleType());
response.setDescription(role.getDescription());
response.setPublicRole(role.isPublicRole());
+ response.setState(role.getState().toString());
response.setResponseName(getCommandName());
response.setObjectName("role");
setResponseObject(response);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/bgp/CreateASNRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/bgp/CreateASNRangeCmd.java
new file mode 100644
index 00000000000..beacba850c3
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/bgp/CreateASNRangeCmd.java
@@ -0,0 +1,83 @@
+// 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.bgp;
+
+import com.cloud.bgp.ASNumberRange;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+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.ASNRangeResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+
+@APICommand(name = "createASNRange",
+ description = "Creates a range of Autonomous Systems for BGP Dynamic Routing",
+ responseObject = ASNRangeResponse.class,
+ entityType = {ASNumberRange.class},
+ since = "4.20.0",
+ authorized = {RoleType.Admin})
+public class CreateASNRangeCmd extends BaseCmd {
+
+ @Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
+ description = "the zone ID", required = true)
+ private Long zoneId;
+
+ @Parameter(name = ApiConstants.START_ASN, type = CommandType.LONG, required=true, description = "the start AS Number")
+ private Long startASNumber;
+
+ @Parameter(name = ApiConstants.END_ASN, type = CommandType.LONG, required=true, description = "the end AS Number")
+ private Long endASNumber;
+
+ @Override
+ public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
+ try {
+ ASNumberRange asnRange = bgpService.createASNumberRange(zoneId, startASNumber, endASNumber);
+ ASNRangeResponse response = _responseGenerator.createASNumberRangeResponse(asnRange);
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ } catch (Exception e) {
+ String msg = String.format("Cannot create AS Number Range %s-%s for zone %s: %s", startASNumber, endASNumber, zoneId, e.getMessage());
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, msg);
+ }
+ }
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ public Long getStartASNumber() {
+ return startASNumber;
+ }
+
+ public Long getEndASNumber() {
+ return endASNumber;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/bgp/DeleteASNRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/bgp/DeleteASNRangeCmd.java
new file mode 100644
index 00000000000..33e139315bf
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/bgp/DeleteASNRangeCmd.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.bgp;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+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.ASNRangeResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+
+@APICommand(name = "deleteASNRange",
+ description = "deletes a range of Autonomous Systems for BGP Dynamic Routing",
+ responseObject = SuccessResponse.class,
+ since = "4.20.0",
+ authorized = {RoleType.Admin})
+public class DeleteASNRangeCmd extends BaseCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ ////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.ID,
+ type = CommandType.UUID,
+ entityType = ASNRangeResponse.class,
+ required = true,
+ description = "ID of the AS range")
+ private Long id;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getId() {
+ return id;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
+ if (bgpService.deleteASRange(getId())) {
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove AS range: " + getId());
+ }
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/bgp/ListASNRangesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/bgp/ListASNRangesCmd.java
new file mode 100644
index 00000000000..82e54581102
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/bgp/ListASNRangesCmd.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.bgp;
+
+import com.cloud.bgp.ASNumberRange;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+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.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ASNRangeResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@APICommand(name = "listASNRanges",
+ description = "List Autonomous Systems Number Ranges",
+ responseObject = ASNRangeResponse.class,
+ entityType = {ASNumberRange.class},
+ since = "4.20.0",
+ authorized = {RoleType.Admin})
+public class ListASNRangesCmd extends BaseListCmd {
+
+ @Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
+ description = "the zone ID")
+ private Long zoneId;
+
+ @Override
+ public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
+ try {
+ List ranges = bgpService.listASNumberRanges(zoneId);
+ ListResponse response = new ListResponse<>();
+ List responses = new ArrayList<>();
+ for (ASNumberRange asnRange : ranges) {
+ responses.add(_responseGenerator.createASNumberRangeResponse(asnRange));
+ }
+ response.setResponses(responses);
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ } catch (Exception e) {
+ String msg = String.format("Error listing AS Number Ranges: %s", e.getMessage());
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, msg);
+ }
+ }
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/bgp/ReleaseASNumberCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/bgp/ReleaseASNumberCmd.java
new file mode 100644
index 00000000000..687f60dc6da
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/bgp/ReleaseASNumberCmd.java
@@ -0,0 +1,83 @@
+// 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.bgp;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+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.SuccessResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+
+@APICommand(name = "releaseASNumber",
+ description = "Releases an AS Number back to the pool",
+ since = "4.20.0",
+ authorized = {RoleType.Admin},
+ responseObject = SuccessResponse.class,
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false)
+public class ReleaseASNumberCmd extends BaseCmd {
+
+ @Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
+ description = "the zone ID", required = true)
+ private Long zoneId;
+
+ @Parameter(name= ApiConstants.AS_NUMBER, type=CommandType.LONG, description="the AS Number to be released",
+ required = true)
+ private Long asNumber;
+
+ @Override
+ public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
+ try {
+ Pair resultPair = bgpService.releaseASNumber(zoneId, asNumber, false);
+ Boolean result = resultPair.first();
+ if (!result) {
+ String details = resultPair.second();
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Cannot release AS Number %s: %s", asNumber, details));
+ }
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ response.setDisplayText(String.format("AS Number %s is released successfully", asNumber));
+ setResponseObject(response);
+ } catch (Exception e) {
+ String msg = String.format("Error releasing AS Number %s: %s", asNumber, e.getMessage());
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, msg);
+ }
+ }
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ public Long getAsNumber() {
+ return asNumber;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
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 184a443d9db..69cb43ce40e 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
@@ -20,6 +20,7 @@ package org.apache.cloudstack.api.command.admin.cluster;
import java.util.ArrayList;
import java.util.List;
+import com.cloud.cpu.CPU;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.APICommand;
@@ -67,6 +68,11 @@ public class AddClusterCmd extends BaseCmd {
description = "hypervisor type of the cluster: XenServer,KVM,VMware,Hyperv,BareMetal,Simulator,Ovm3")
private String hypervisor;
+ @Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
+ description = "the CPU arch of the cluster. Valid options are: x86_64, aarch64",
+ since = "4.20")
+ private String arch;
+
@Parameter(name = ApiConstants.CLUSTER_TYPE, type = CommandType.STRING, required = true, description = "type of the cluster: CloudManaged, ExternalManaged")
private String clusterType;
@@ -204,6 +210,10 @@ public class AddClusterCmd extends BaseCmd {
return ApiCommandResourceType.Cluster;
}
+ public CPU.CPUArch getArch() {
+ return CPU.CPUArch.fromType(arch);
+ }
+
@Override
public void execute() {
try {
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 77bb97fd39d..c4ee87380ed 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
@@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.admin.cluster;
+import com.cloud.cpu.CPU;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.APICommand;
@@ -29,6 +30,7 @@ import org.apache.cloudstack.api.response.ClusterResponse;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.org.Cluster;
import com.cloud.user.Account;
+import org.apache.commons.lang3.StringUtils;
@APICommand(name = "updateCluster", description = "Updates an existing cluster", responseObject = ClusterResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@@ -53,6 +55,11 @@ public class UpdateClusterCmd extends BaseCmd {
@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",
+ since = "4.20")
+ private String arch;
+
public String getClusterName() {
return clusterName;
}
@@ -108,6 +115,13 @@ public class UpdateClusterCmd extends BaseCmd {
return ApiCommandResourceType.Cluster;
}
+ public CPU.CPUArch getArch() {
+ if (StringUtils.isBlank(arch)) {
+ return null;
+ }
+ return CPU.CPUArch.fromType(arch);
+ }
+
@Override
public void execute() {
Cluster cluster = _resourceService.getCluster(getId());
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 50984188bf5..01f7af10841 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,6 +43,12 @@ 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")
+ 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")
+ private String hypervisorVersion;
+
@Parameter(name = ApiConstants.SECURITY_GROUP_EANBLED, type = CommandType.BOOLEAN, description = "set true to enable security group for this hypervisor.")
private Boolean securityGroupEnabled;
@@ -73,6 +79,14 @@ public class UpdateHypervisorCapabilitiesCmd extends BaseCmd {
return id;
}
+ public String getHypervisor() {
+ return hypervisor;
+ }
+
+ public String getHypervisorVersion() {
+ return hypervisorVersion;
+ }
+
public Long getMaxGuestsLimit() {
return maxGuestsLimit;
}
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
new file mode 100644
index 00000000000..a482cb1d4f2
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmd.java
@@ -0,0 +1,108 @@
+// 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 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.response.DataCenterIpv4SubnetResponse;
+import org.apache.cloudstack.api.response.Ipv4SubnetForGuestNetworkResponse;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+import org.apache.cloudstack.network.Ipv4GuestSubnetNetworkMap;
+
+@APICommand(name = "createIpv4SubnetForGuestNetwork",
+ description = "Creates a IPv4 subnet for guest networks.",
+ responseObject = Ipv4SubnetForGuestNetworkResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class CreateIpv4SubnetForGuestNetworkCmd extends BaseAsyncCmd {
+
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+ @Parameter(name = ApiConstants.PARENT_ID,
+ type = CommandType.UUID,
+ entityType = DataCenterIpv4SubnetResponse.class,
+ required = true,
+ description = "The zone Ipv4 subnet which the IPv4 subnet belongs to.")
+ private Long parentId;
+
+ @Parameter(name = ApiConstants.SUBNET,
+ type = CommandType.STRING,
+ description = "The CIDR of this Ipv4 subnet.")
+ private String subnet;
+
+ @Parameter(name = ApiConstants.CIDR_SIZE,
+ type = CommandType.INTEGER,
+ description = "the CIDR size of IPv4 network. This is mutually exclusive with subnet.")
+ private Integer cidrSize;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+
+ public Long getParentId() {
+ return parentId;
+ }
+
+ public String getSubnet() {
+ return subnet;
+ }
+
+ public Integer getCidrSize() {
+ return cidrSize;
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_IP4_GUEST_SUBNET_CREATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Creating guest IPv4 subnet " + getSubnet() + " in zone subnet=" + getParentId();
+ }
+
+ @Override
+ public void execute() {
+ Ipv4GuestSubnetNetworkMap result = routedIpv4Manager.createIpv4SubnetForGuestNetwork(this);
+ if (result != null) {
+ Ipv4SubnetForGuestNetworkResponse response = routedIpv4Manager.createIpv4SubnetForGuestNetworkResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create zone guest IPv4 subnet.");
+ }
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+
+}
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
new file mode 100644
index 00000000000..5f48cf9c632
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmd.java
@@ -0,0 +1,125 @@
+// 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 org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiArgValidator;
+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.response.DataCenterIpv4SubnetResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.datacenter.DataCenterIpv4GuestSubnet;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+
+@APICommand(name = "createIpv4SubnetForZone",
+ description = "Creates a IPv4 subnet for a zone.",
+ responseObject = DataCenterIpv4SubnetResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class CreateIpv4SubnetForZoneCmd extends BaseAsyncCmd {
+
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+ @Parameter(name = ApiConstants.ZONE_ID,
+ type = CommandType.UUID,
+ entityType = ZoneResponse.class,
+ required = true,
+ description = "UUID of the zone which the IPv4 subnet belongs to.",
+ validations = {ApiArgValidator.PositiveNumber})
+ private Long zoneId;
+
+ @Parameter(name = ApiConstants.SUBNET,
+ type = CommandType.STRING,
+ required = true,
+ description = "The CIDR of the IPv4 subnet.")
+ private String subnet;
+
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "account who will own the IPv4 subnet")
+ private String accountName;
+
+ @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "project who will own the IPv4 subnet")
+ private Long projectId;
+
+ @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "domain ID of the account owning the IPv4 subnet")
+ private Long domainId;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ public String getSubnet() {
+ return subnet;
+ }
+
+ public String getAccountName() {
+ return accountName;
+ }
+
+ public Long getProjectId() {
+ return projectId;
+ }
+
+ public Long getDomainId() {
+ return domainId;
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_ZONE_IP4_SUBNET_CREATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Creating guest IPv4 subnet " + getSubnet() + " for zone=" + getZoneId();
+ }
+
+ @Override
+ public void execute() {
+ DataCenterIpv4GuestSubnet result = routedIpv4Manager.createDataCenterIpv4GuestSubnet(this);
+ if (result != null) {
+ DataCenterIpv4SubnetResponse response = routedIpv4Manager.createDataCenterIpv4SubnetResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create zone guest IPv4 subnet.");
+ }
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+
+}
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 cd9770877ed..d8b57f79528 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
@@ -24,10 +24,13 @@ import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.command.admin.AdminCmd;
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
+import org.apache.cloudstack.api.response.BgpPeerResponse;
import org.apache.cloudstack.api.response.NetworkResponse;
import com.cloud.network.Network;
+import java.util.List;
+
@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 {
@@ -49,6 +52,14 @@ public class CreateNetworkCmdByAdmin extends CreateNetworkCmd implements AdminCm
validations = {ApiArgValidator.NotNullOrEmpty})
private String routerIpv6;
+ @Parameter(name = ApiConstants.BGP_PEER_IDS,
+ type = CommandType.LIST,
+ collectionType = CommandType.UUID,
+ entityType = BgpPeerResponse.class,
+ description = "Ids of the Bgp Peer for the network",
+ since = "4.20.0")
+ private List bgpPeerIds;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -78,4 +89,8 @@ public class CreateNetworkCmdByAdmin extends CreateNetworkCmd implements AdminCm
public String getRouterIpv6() {
return routerIpv6;
}
+
+ public List getBgpPeerIds() {
+ return 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 9117bcfc193..af3db374a7c 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
@@ -146,12 +146,6 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
since = "4.20.0")
private Boolean forNsx;
- @Parameter(name = ApiConstants.NSX_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 nsxMode;
-
@Parameter(name = ApiConstants.NSX_SUPPORT_LB,
type = CommandType.BOOLEAN,
description = "true if network offering for NSX network offering supports Load balancer service.",
@@ -164,6 +158,12 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
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.")
@@ -211,6 +211,16 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
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 ///////////////////////
/////////////////////////////////////////////////////
@@ -302,8 +312,8 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
return BooleanUtils.isTrue(forNsx);
}
- public String getNsxMode() {
- return nsxMode;
+ public String getNetworkMode() {
+ return networkMode;
}
public boolean getNsxSupportsLbService() {
@@ -462,6 +472,14 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
return false;
}
+ public boolean getSpecifyAsNumber() {
+ return BooleanUtils.toBoolean(specifyAsNumber);
+ }
+
+ public String getRoutingMode() {
+ return routingMode;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
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
new file mode 100644
index 00000000000..2df032c559c
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmd.java
@@ -0,0 +1,111 @@
+// 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 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.response.DataCenterIpv4SubnetResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.datacenter.DataCenterIpv4GuestSubnet;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@APICommand(name = "dedicateIpv4SubnetForZone",
+ description = "Dedicates an existing IPv4 subnet for a zone to an account or a domain.",
+ responseObject = DataCenterIpv4SubnetResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class DedicateIpv4SubnetForZoneCmd extends BaseAsyncCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DataCenterIpv4SubnetResponse.class, required = true, description = "Id of the guest network IPv4 subnet")
+ private Long id;
+
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "account who will own the IPv4 subnet")
+ private String accountName;
+
+ @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "project who will own the IPv4 subnet")
+ private Long projectId;
+
+ @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "domain ID of the account owning the IPv4 subnet")
+ private Long domainId;
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getAccountName() {
+ return accountName;
+ }
+
+ public Long getProjectId() {
+ return projectId;
+ }
+
+ public Long getDomainId() {
+ return domainId;
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_ZONE_IP4_SUBNET_DEDICATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Dedicating zone IPv4 subnet " + getId();
+ }
+
+ @Override
+ public void execute() {
+ try {
+ DataCenterIpv4GuestSubnet result = routedIpv4Manager.dedicateDataCenterIpv4GuestSubnet(this);
+ if (result != null) {
+ DataCenterIpv4SubnetResponse response = routedIpv4Manager.createDataCenterIpv4SubnetResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to dedicate guest network IPv4 subnet:" + getId());
+ }
+ } catch (InvalidParameterValueException ex) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
+ } catch (CloudRuntimeException ex) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+ }
+
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
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
new file mode 100644
index 00000000000..28a646f9d03
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmd.java
@@ -0,0 +1,88 @@
+// 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 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.response.Ipv4SubnetForGuestNetworkResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@APICommand(name = "deleteIpv4SubnetForGuestNetwork",
+ description = "Deletes an existing IPv4 subnet for guest network.",
+ responseObject = SuccessResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class DeleteIpv4SubnetForGuestNetworkCmd extends BaseAsyncCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = Ipv4SubnetForGuestNetworkResponse.class, required = true, description = "Id of the guest network IPv4 subnet")
+ private Long id;
+
+ public Long getId() {
+ return id;
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_IP4_GUEST_SUBNET_DELETE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Deleting guest IPv4 subnet " + getId();
+ }
+
+ @Override
+ public void execute() {
+ try {
+ boolean result = routedIpv4Manager.deleteIpv4SubnetForGuestNetwork(this);
+ if (result) {
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete guest network IPv4 subnet:" + getId());
+ }
+ } catch (InvalidParameterValueException ex) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
+ } catch (CloudRuntimeException ex) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+ }
+
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
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
new file mode 100644
index 00000000000..222bc1bad98
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmd.java
@@ -0,0 +1,88 @@
+// 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 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.response.DataCenterIpv4SubnetResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@APICommand(name = "deleteIpv4SubnetForZone",
+ description = "Deletes an existing IPv4 subnet for a zone.",
+ responseObject = SuccessResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class DeleteIpv4SubnetForZoneCmd extends BaseAsyncCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DataCenterIpv4SubnetResponse.class, required = true, description = "Id of the guest network IPv4 subnet")
+ private Long id;
+
+ public Long getId() {
+ return id;
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_ZONE_IP4_SUBNET_DELETE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Deleting zone IPv4 subnet " + getId();
+ }
+
+ @Override
+ public void execute() {
+ try {
+ boolean result = routedIpv4Manager.deleteDataCenterIpv4GuestSubnet(this);
+ if (result) {
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete guest network IPv4 subnet:" + getId());
+ }
+ } catch (InvalidParameterValueException ex) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
+ } catch (CloudRuntimeException ex) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+ }
+
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListIpv4SubnetsForGuestNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListIpv4SubnetsForGuestNetworkCmd.java
new file mode 100644
index 00000000000..9761f6e89eb
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListIpv4SubnetsForGuestNetworkCmd.java
@@ -0,0 +1,123 @@
+// 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.ArrayList;
+import java.util.List;
+
+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.response.DataCenterIpv4SubnetResponse;
+import org.apache.cloudstack.api.response.Ipv4SubnetForGuestNetworkResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.network.Ipv4GuestSubnetNetworkMap;
+
+@APICommand(name = "listIpv4SubnetsForGuestNetwork",
+ description = "Lists IPv4 subnets for guest networks.",
+ responseObject = Ipv4SubnetForGuestNetworkResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class ListIpv4SubnetsForGuestNetworkCmd extends BaseListCmd {
+
+ @Parameter(name = ApiConstants.ID,
+ type = CommandType.UUID,
+ entityType = Ipv4SubnetForGuestNetworkResponse.class,
+ description = "UUID of the IPv4 subnet for guest network.")
+ private Long id;
+
+ @Parameter(name = ApiConstants.PARENT_ID,
+ type = CommandType.UUID,
+ entityType = DataCenterIpv4SubnetResponse.class,
+ description = "UUID of zone Ipv4 subnet which the IPv4 subnet belongs to.")
+ private Long parentId;
+
+ @Parameter(name = ApiConstants.SUBNET,
+ type = CommandType.STRING,
+ description = "The CIDR of the Ipv4 subnet.")
+ private String subnet;
+
+ @Parameter(name = ApiConstants.ZONE_ID,
+ type = CommandType.UUID,
+ entityType = ZoneResponse.class,
+ description = "UUID of zone to which the IPv4 subnet belongs to.")
+ private Long zoneId;
+
+ @Parameter(name = ApiConstants.NETWORK_ID,
+ type = CommandType.UUID,
+ entityType = NetworkResponse.class,
+ description = "UUID of network to which the IPv4 subnet is associated to.")
+ private Long networkId;
+
+ @Parameter(name = ApiConstants.VPC_ID,
+ type = CommandType.UUID,
+ entityType = VpcResponse.class,
+ description = "UUID of VPC to which the IPv4 subnet is associated to.")
+ private Long vpcId;
+
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getId() {
+ return id;
+ }
+
+ public Long getParentId() {
+ return parentId;
+ }
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ public String getSubnet() {
+ return subnet;
+ }
+
+ public Long getNetworkId() {
+ return networkId;
+ }
+
+ public Long getVpcId() {
+ return vpcId;
+ }
+
+ @Override
+ public void execute() {
+ List extends Ipv4GuestSubnetNetworkMap> subnets = routedIpv4Manager.listIpv4GuestSubnetsForGuestNetwork(this);
+ ListResponse response = new ListResponse<>();
+ List subnetResponses = new ArrayList<>();
+ for (Ipv4GuestSubnetNetworkMap subnet : subnets) {
+ Ipv4SubnetForGuestNetworkResponse subnetResponse = routedIpv4Manager.createIpv4SubnetForGuestNetworkResponse(subnet);
+ subnetResponses.add(subnetResponse);
+ }
+
+ response.setResponses(subnetResponses, subnets.size());
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ }
+
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListIpv4SubnetsForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListIpv4SubnetsForZoneCmd.java
new file mode 100644
index 00000000000..2c2182250ed
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListIpv4SubnetsForZoneCmd.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
+// 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.ArrayList;
+import java.util.List;
+
+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.response.DataCenterIpv4SubnetResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.datacenter.DataCenterIpv4GuestSubnet;
+
+@APICommand(name = "listIpv4SubnetsForZone",
+ description = "Lists IPv4 subnets for zone.",
+ responseObject = DataCenterIpv4SubnetResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class ListIpv4SubnetsForZoneCmd extends BaseListCmd {
+
+ @Parameter(name = ApiConstants.ID,
+ type = CommandType.UUID,
+ entityType = DataCenterIpv4SubnetResponse.class,
+ description = "UUID of the IPv4 subnet.")
+ private Long id;
+
+ @Parameter(name = ApiConstants.ZONE_ID,
+ type = CommandType.UUID,
+ entityType = ZoneResponse.class,
+ description = "UUID of zone to which the IPv4 subnet belongs to.")
+ private Long zoneId;
+
+ @Parameter(name = ApiConstants.SUBNET,
+ type = CommandType.STRING,
+ description = "CIDR of the IPv4 subnet.")
+ private String subnet;
+
+ @Parameter(name = ApiConstants.ACCOUNT,
+ type = CommandType.STRING,
+ description = "the account which the IPv4 subnet is dedicated to. Must be used with the domainId parameter.")
+ private String accountName;
+
+ @Parameter(name = ApiConstants.PROJECT_ID,
+ type = CommandType.UUID,
+ entityType = ProjectResponse.class,
+ description = "project who which the IPv4 subnet is dedicated to")
+ private Long projectId;
+
+ @Parameter(name = ApiConstants.DOMAIN_ID,
+ type = CommandType.UUID,
+ entityType = DomainResponse.class,
+ description = "the domain ID which the IPv4 subnet is dedicated to.")
+ private Long domainId;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getId() {
+ return id;
+ }
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ public String getSubnet() {
+ return subnet;
+ }
+
+ public String getAccountName() {
+ return accountName;
+ }
+
+ public Long getProjectId() {
+ return projectId;
+ }
+
+ public Long getDomainId() {
+ return domainId;
+ }
+
+ @Override
+ public void execute() {
+ List extends DataCenterIpv4GuestSubnet> subnets = routedIpv4Manager.listDataCenterIpv4GuestSubnets(this);
+ ListResponse response = new ListResponse<>();
+ List subnetResponses = new ArrayList<>();
+ for (DataCenterIpv4GuestSubnet subnet : subnets) {
+ DataCenterIpv4SubnetResponse subnetResponse = routedIpv4Manager.createDataCenterIpv4SubnetResponse(subnet);
+ subnetResponses.add(subnetResponse);
+ }
+
+ response.setResponses(subnetResponses, subnets.size());
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ }
+
+}
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
new file mode 100644
index 00000000000..3e151b9b58f
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedIpv4SubnetForZoneCmd.java
@@ -0,0 +1,88 @@
+// 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 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.response.DataCenterIpv4SubnetResponse;
+import org.apache.cloudstack.datacenter.DataCenterIpv4GuestSubnet;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@APICommand(name = "releaseIpv4SubnetForZone",
+ description = "Releases an existing dedicated IPv4 subnet for a zone.",
+ responseObject = DataCenterIpv4SubnetResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class ReleaseDedicatedIpv4SubnetForZoneCmd extends BaseAsyncCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DataCenterIpv4SubnetResponse.class, required = true, description = "Id of the guest network IPv4 subnet")
+ private Long id;
+
+ public Long getId() {
+ return id;
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_ZONE_IP4_SUBNET_RELEASE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Releasing a dedicated zone IPv4 subnet " + getId();
+ }
+
+ @Override
+ public void execute() {
+ try {
+ DataCenterIpv4GuestSubnet result = routedIpv4Manager.releaseDedicatedDataCenterIpv4GuestSubnet(this);
+ if (result != null) {
+ DataCenterIpv4SubnetResponse response = routedIpv4Manager.createDataCenterIpv4SubnetResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release guest network IPv4 subnet:" + getId());
+ }
+ } catch (InvalidParameterValueException ex) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
+ } catch (CloudRuntimeException ex) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+ }
+
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
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
new file mode 100644
index 00000000000..da7a23f50d9
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateIpv4SubnetForZoneCmd.java
@@ -0,0 +1,98 @@
+// 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 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.response.DataCenterIpv4SubnetResponse;
+import org.apache.cloudstack.datacenter.DataCenterIpv4GuestSubnet;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@APICommand(name = "updateIpv4SubnetForZone",
+ description = "Updates an existing IPv4 subnet for a zone.",
+ responseObject = DataCenterIpv4SubnetResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class UpdateIpv4SubnetForZoneCmd extends BaseAsyncCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DataCenterIpv4SubnetResponse.class, required = true, description = "Id of the guest network IPv4 subnet")
+ private Long id;
+
+ @Parameter(name = ApiConstants.SUBNET,
+ type = CommandType.STRING,
+ required = true,
+ description = "The new CIDR of the IPv4 subnet.")
+ private String subnet;
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getSubnet() {
+ return subnet;
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_ZONE_IP4_SUBNET_UPDATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Updating zone IPv4 subnet " + getId();
+ }
+
+ @Override
+ public void execute() {
+ try {
+ DataCenterIpv4GuestSubnet result = routedIpv4Manager.updateDataCenterIpv4GuestSubnet(this);
+ if (result != null) {
+ DataCenterIpv4SubnetResponse response = routedIpv4Manager.createDataCenterIpv4SubnetResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update guest network IPv4 subnet:" + getId());
+ }
+ } catch (InvalidParameterValueException ex) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
+ } catch (CloudRuntimeException ex) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+ }
+
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
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
new file mode 100644
index 00000000000..1d6bffca342
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForNetworkCmd.java
@@ -0,0 +1,109 @@
+// 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.bgp;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiArgValidator;
+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.BgpPeerResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import java.util.List;
+
+@APICommand(name = "changeBgpPeersForNetwork",
+ description = "Change the BGP peers for a network.",
+ responseObject = BgpPeerResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class ChangeBgpPeersForNetworkCmd extends BaseAsyncCmd implements AdminCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.NETWORK_ID,
+ type = CommandType.UUID,
+ entityType = NetworkResponse.class,
+ required = true,
+ description = "UUID of the network which the Bgp Peers are associated to.",
+ validations = {ApiArgValidator.PositiveNumber})
+ private Long networkId;
+
+ @Parameter(name = ApiConstants.BGP_PEER_IDS,
+ type = CommandType.LIST,
+ collectionType = CommandType.UUID,
+ entityType = BgpPeerResponse.class,
+ description = "Ids of the Bgp Peer. If it is empty, all BGP peers will be unlinked.")
+ private List bgpPeerIds;
+
+ public Long getNetworkId() {
+ return networkId;
+ }
+
+ public List getBgpPeerIds() {
+ return bgpPeerIds;
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_NETWORK_BGP_PEER_UPDATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Changing Bgp Peers for network " + getNetworkId();
+ }
+
+ @Override
+ public void execute() {
+ try {
+ Network result = routedIpv4Manager.changeBgpPeersForNetwork(this);
+ if (result != null) {
+ NetworkResponse response = _responseGenerator.createNetworkResponse(getResponseView(), result);
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to change BGP Peers for network");
+ }
+ } catch (InvalidParameterValueException ex) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
+ } catch (CloudRuntimeException ex) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+ }
+
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
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
new file mode 100644
index 00000000000..0c89f3f1d43
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForVpcCmd.java
@@ -0,0 +1,109 @@
+// 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.bgp;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiArgValidator;
+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.BgpPeerResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import java.util.List;
+
+@APICommand(name = "changeBgpPeersForVpc",
+ description = "Change the BGP peers for a VPC.",
+ responseObject = BgpPeerResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class ChangeBgpPeersForVpcCmd extends BaseAsyncCmd implements AdminCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.VPC_ID,
+ type = CommandType.UUID,
+ entityType = VpcResponse.class,
+ required = true,
+ description = "UUID of the VPC which the Bgp Peers are associated to.",
+ validations = {ApiArgValidator.PositiveNumber})
+ private Long vpcId;
+
+ @Parameter(name = ApiConstants.BGP_PEER_IDS,
+ type = CommandType.LIST,
+ collectionType = CommandType.UUID,
+ entityType = BgpPeerResponse.class,
+ description = "Ids of the Bgp Peer. If it is empty, all BGP peers will be unlinked.")
+ private List bgpPeerIds;
+
+ public Long getVpcId() {
+ return vpcId;
+ }
+
+ public List getBgpPeerIds() {
+ return bgpPeerIds;
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_VPC_BGP_PEER_UPDATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Changing Bgp Peers for VPC " + getVpcId();
+ }
+
+ @Override
+ public void execute() {
+ try {
+ Vpc result = routedIpv4Manager.changeBgpPeersForVpc(this);
+ if (result != null) {
+ VpcResponse response = _responseGenerator.createVpcResponse(getResponseView(), result);
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to change BGP Peers for vpc");
+ }
+ } catch (InvalidParameterValueException ex) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
+ } catch (CloudRuntimeException ex) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+ }
+
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
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
new file mode 100644
index 00000000000..80642124938
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmd.java
@@ -0,0 +1,168 @@
+// 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.bgp;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiArgValidator;
+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.response.BgpPeerResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.network.BgpPeer;
+import org.apache.commons.collections.MapUtils;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+
+import java.util.Collection;
+import java.util.Map;
+
+@APICommand(name = "createBgpPeer",
+ description = "Creates a Bgp Peer for a zone.",
+ responseObject = BgpPeerResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = true,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class CreateBgpPeerCmd extends BaseAsyncCmd {
+
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+ @Parameter(name = ApiConstants.ZONE_ID,
+ type = CommandType.UUID,
+ entityType = ZoneResponse.class,
+ required = true,
+ description = "UUID of the zone which the Bgp Peer belongs to.",
+ validations = {ApiArgValidator.PositiveNumber})
+ private Long zoneId;
+
+ @Parameter(name = ApiConstants.IP_ADDRESS,
+ type = CommandType.STRING,
+ description = "The IPv4 address of the Bgp Peer.")
+ private String ip4Address;
+
+ @Parameter(name = ApiConstants.IP6_ADDRESS,
+ type = CommandType.STRING,
+ description = "The IPv6 address of the Bgp Peer.")
+ private String ip6Address;
+
+ @Parameter(name = ApiConstants.AS_NUMBER,
+ type = CommandType.LONG,
+ required = true,
+ description = "The AS number of the Bgp Peer.")
+ private Long asNumber;
+
+ @Parameter(name = ApiConstants.PASSWORD,
+ type = CommandType.STRING,
+ description = "The password of the Bgp Peer.")
+ private String password;
+
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "account who will own the Bgp Peer")
+ private String accountName;
+
+ @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "project who will own the Bgp Peer")
+ private Long projectId;
+
+ @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "domain ID of the account owning the Bgp Peer")
+ private Long domainId;
+
+ @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
+ description = "BGP peer details in key/value pairs.")
+ protected Map details;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ public String getIp4Address() {
+ return ip4Address;
+ }
+
+ public String getIp6Address() {
+ return ip6Address;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public Long getAsNumber() {
+ return asNumber;
+ }
+
+ public String getAccountName() {
+ return accountName;
+ }
+
+ public Long getProjectId() {
+ return projectId;
+ }
+
+ public Long getDomainId() {
+ return domainId;
+ }
+
+ public Map getDetails() {
+ if (MapUtils.isEmpty(details)) {
+ return null;
+ }
+ Collection paramsCollection = this.details.values();
+ return (Map) (paramsCollection.toArray())[0];
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_BGP_PEER_CREATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Creating Bgp Peer " + getAsNumber() + " for zone=" + getZoneId();
+ }
+
+ @Override
+ public void execute() {
+ BgpPeer result = routedIpv4Manager.createBgpPeer(this);
+ if (result != null) {
+ BgpPeerResponse response = routedIpv4Manager.createBgpPeerResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create Bgp Peer.");
+ }
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+
+}
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
new file mode 100644
index 00000000000..ec3d0ea1162
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DedicateBgpPeerCmd.java
@@ -0,0 +1,111 @@
+// 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.bgp;
+
+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.response.BgpPeerResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.network.BgpPeer;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@APICommand(name = "dedicateBgpPeer",
+ description = "Dedicates an existing Bgp Peer to an account or a domain.",
+ responseObject = BgpPeerResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class DedicateBgpPeerCmd extends BaseAsyncCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = BgpPeerResponse.class, required = true, description = "Id of the Bgp Peer")
+ private Long id;
+
+ @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "account who will own the Bgp Peer")
+ private String accountName;
+
+ @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "project who will own the Bgp Peer")
+ private Long projectId;
+
+ @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "domain ID of the account owning the Bgp Peer")
+ private Long domainId;
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getAccountName() {
+ return accountName;
+ }
+
+ public Long getProjectId() {
+ return projectId;
+ }
+
+ public Long getDomainId() {
+ return domainId;
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_BGP_PEER_DEDICATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Dedicating Bgp Peer " + getId();
+ }
+
+ @Override
+ public void execute() {
+ try {
+ BgpPeer result = routedIpv4Manager.dedicateBgpPeer(this);
+ if (result != null) {
+ BgpPeerResponse response = routedIpv4Manager.createBgpPeerResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to dedicate Bgp Peer:" + getId());
+ }
+ } catch (InvalidParameterValueException ex) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
+ } catch (CloudRuntimeException ex) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+ }
+
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
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
new file mode 100644
index 00000000000..a01711efa44
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DeleteBgpPeerCmd.java
@@ -0,0 +1,88 @@
+// 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.bgp;
+
+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.response.BgpPeerResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@APICommand(name = "deleteBgpPeer",
+ description = "Deletes an existing Bgp Peer.",
+ responseObject = SuccessResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class DeleteBgpPeerCmd extends BaseAsyncCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = BgpPeerResponse.class, required = true, description = "Id of the Bgp Peer")
+ private Long id;
+
+ public Long getId() {
+ return id;
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_BGP_PEER_DELETE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Deleting Bgp Peer " + getId();
+ }
+
+ @Override
+ public void execute() {
+ try {
+ boolean result = routedIpv4Manager.deleteBgpPeer(this);
+ if (result) {
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete Bgp Peer:" + getId());
+ }
+ } catch (InvalidParameterValueException ex) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
+ } catch (CloudRuntimeException ex) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+ }
+
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ListBgpPeersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ListBgpPeersCmd.java
new file mode 100644
index 00000000000..ea15f0970e8
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ListBgpPeersCmd.java
@@ -0,0 +1,130 @@
+// 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.bgp;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.response.BgpPeerResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.network.BgpPeer;
+
+@APICommand(name = "listBgpPeers",
+ description = "Lists Bgp Peers.",
+ responseObject = BgpPeerResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class ListBgpPeersCmd extends BaseListCmd {
+
+ @Parameter(name = ApiConstants.ID,
+ type = CommandType.UUID,
+ entityType = BgpPeerResponse.class,
+ description = "UUID of the Bgp Peer.")
+ private Long id;
+
+ @Parameter(name = ApiConstants.ZONE_ID,
+ type = CommandType.UUID,
+ entityType = ZoneResponse.class,
+ description = "UUID of zone to which the Bgp Peer belongs to.")
+ private Long zoneId;
+
+ @Parameter(name = ApiConstants.AS_NUMBER,
+ type = CommandType.LONG,
+ description = "AS number of the Bgp Peer.")
+ private Long asNumber;
+
+ @Parameter(name = ApiConstants.ACCOUNT,
+ type = CommandType.STRING,
+ description = "the account which the Bgp Peer is dedicated to. Must be used with the domainId parameter.")
+ private String accountName;
+
+ @Parameter(name = ApiConstants.PROJECT_ID,
+ type = CommandType.UUID,
+ entityType = ProjectResponse.class,
+ description = "project who which the Bgp Peer is dedicated to")
+ private Long projectId;
+
+ @Parameter(name = ApiConstants.DOMAIN_ID,
+ type = CommandType.UUID,
+ entityType = DomainResponse.class,
+ description = "the domain ID which the Bgp Peer is dedicated to.")
+ private Long domainId;
+
+ @Parameter(name = ApiConstants.IS_DEDICATED,
+ type = CommandType.BOOLEAN,
+ description = "Lists only dedicated or non-dedicated Bgp Peers. If not set, lists all dedicated and non-dedicated BGP peers the domain/account can access.")
+ private Boolean isDedicated;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getId() {
+ return id;
+ }
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ public Long getAsNumber() {
+ return asNumber;
+ }
+
+ public String getAccountName() {
+ return accountName;
+ }
+
+ public Long getProjectId() {
+ return projectId;
+ }
+
+ public Long getDomainId() {
+ return domainId;
+ }
+
+ public Boolean getDedicated() {
+ return isDedicated;
+ }
+
+ @Override
+ public void execute() {
+ List extends BgpPeer> subnets = routedIpv4Manager.listBgpPeers(this);
+ ListResponse response = new ListResponse<>();
+ List subnetResponses = new ArrayList<>();
+ for (BgpPeer subnet : subnets) {
+ BgpPeerResponse subnetResponse = routedIpv4Manager.createBgpPeerResponse(subnet);
+ subnetResponse.setObjectName("bgppeer");
+ subnetResponses.add(subnetResponse);
+ }
+
+ response.setResponses(subnetResponses, subnets.size());
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ }
+
+}
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
new file mode 100644
index 00000000000..92610c233ef
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ReleaseDedicatedBgpPeerCmd.java
@@ -0,0 +1,88 @@
+// 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.bgp;
+
+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.response.BgpPeerResponse;
+import org.apache.cloudstack.network.BgpPeer;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@APICommand(name = "releaseBgpPeer",
+ description = "Releases an existing dedicated Bgp Peer.",
+ responseObject = BgpPeerResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class ReleaseDedicatedBgpPeerCmd extends BaseAsyncCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = BgpPeerResponse.class, required = true, description = "Id of the Bgp Peer")
+ private Long id;
+
+ public Long getId() {
+ return id;
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_BGP_PEER_RELEASE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Releasing a dedicated Bgp Peer " + getId();
+ }
+
+ @Override
+ public void execute() {
+ try {
+ BgpPeer result = routedIpv4Manager.releaseDedicatedBgpPeer(this);
+ if (result != null) {
+ BgpPeerResponse response = routedIpv4Manager.createBgpPeerResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release Bgp Peer:" + getId());
+ }
+ } catch (InvalidParameterValueException ex) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
+ } catch (CloudRuntimeException ex) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+ }
+
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
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
new file mode 100644
index 00000000000..ae44330ea03
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmd.java
@@ -0,0 +1,149 @@
+// 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.bgp;
+
+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.response.BgpPeerResponse;
+import org.apache.cloudstack.network.BgpPeer;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.Collection;
+import java.util.Map;
+
+@APICommand(name = "updateBgpPeer",
+ description = "Updates an existing Bgp Peer.",
+ responseObject = BgpPeerResponse.class,
+ since = "4.20.0",
+ requestHasSensitiveInfo = true,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin})
+public class UpdateBgpPeerCmd extends BaseAsyncCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = BgpPeerResponse.class, required = true, description = "Id of the Bgp Peer")
+ private Long id;
+
+ @Parameter(name = ApiConstants.IP_ADDRESS,
+ type = CommandType.STRING,
+ description = "The IPv4 address of the Bgp Peer.")
+ private String ip4Address;
+
+ @Parameter(name = ApiConstants.IP6_ADDRESS,
+ type = CommandType.STRING,
+ description = "The IPv6 address of the Bgp Peer.")
+ private String ip6Address;
+
+ @Parameter(name = ApiConstants.AS_NUMBER,
+ type = CommandType.LONG,
+ description = "The AS number of the Bgp Peer.")
+ private Long asNumber;
+
+ @Parameter(name = ApiConstants.PASSWORD,
+ type = CommandType.STRING,
+ description = "The password of the Bgp Peer.")
+ private String password;
+
+ @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
+ description = "BGP peer details in key/value pairs.")
+ protected Map details;
+
+ @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 are removed for this resource; if false or not set, no action)")
+ private Boolean cleanupDetails;
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getIp4Address() {
+ return ip4Address;
+ }
+
+ public String getIp6Address() {
+ return ip6Address;
+ }
+
+ public Long getAsNumber() {
+ return asNumber;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public Map getDetails() {
+ if (MapUtils.isEmpty(details)) {
+ return null;
+ }
+ Collection paramsCollection = this.details.values();
+ return (Map) (paramsCollection.toArray())[0];
+ }
+
+ public boolean isCleanupDetails(){
+ return cleanupDetails == null ? false : cleanupDetails.booleanValue();
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_BGP_PEER_UPDATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Updating Bgp Peer " + getId();
+ }
+
+ @Override
+ public void execute() {
+ try {
+ BgpPeer result = routedIpv4Manager.updateBgpPeer(this);
+ if (result != null) {
+ BgpPeerResponse response = routedIpv4Manager.createBgpPeerResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update Bgp Peer:" + getId());
+ }
+ } catch (InvalidParameterValueException ex) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
+ } catch (CloudRuntimeException ex) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+ }
+
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+}
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 4562aa7da19..8f6d5413d72 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,7 +54,11 @@ public class CreateServiceOfferingCmd extends BaseCmd {
@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 = "the CPU speed of the service offering in MHz.")
+ @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.")
private Integer cpuSpeed;
@Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "The display text of the service offering, defaults to 'name'.")
@@ -242,6 +246,12 @@ public class CreateServiceOfferingCmd extends BaseCmd {
@Parameter(name = ApiConstants.ENCRYPT_ROOT, type = CommandType.BOOLEAN, description = "VMs using this offering require root volume encryption", since="4.18")
private Boolean encryptRoot;
+ @Parameter(name = ApiConstants.PURGE_RESOURCES, type = CommandType.BOOLEAN,
+ description = "Whether to cleanup instance and its associated resource from database upon expunge of the instance",
+ since="4.20")
+ private Boolean purgeResources;
+
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@@ -269,7 +279,7 @@ public class CreateServiceOfferingCmd extends BaseCmd {
public String getServiceOfferingName() {
if (StringUtils.isEmpty(serviceOfferingName)) {
- throw new InvalidParameterValueException("Failed to create service offering because offering name has not been spified.");
+ throw new InvalidParameterValueException("Failed to create service offering because offering name has not been specified.");
}
return serviceOfferingName;
}
@@ -477,6 +487,10 @@ public class CreateServiceOfferingCmd extends BaseCmd {
return false;
}
+ public boolean isPurgeResources() {
+ return Boolean.TRUE.equals(purgeResources);
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
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 7d6bae86083..e580f0d9f41 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
@@ -89,6 +89,11 @@ public class UpdateServiceOfferingCmd extends BaseCmd {
description = "state of the service offering")
private String serviceOfferingState;
+ @Parameter(name = ApiConstants.PURGE_RESOURCES, type = CommandType.BOOLEAN,
+ description = "Whether to cleanup VM and its associated resource upon expunge",
+ since="4.20")
+ private Boolean purgeResources;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -185,6 +190,10 @@ public class UpdateServiceOfferingCmd extends BaseCmd {
return state;
}
+ public boolean isPurgeResources() {
+ return Boolean.TRUE.equals(purgeResources);
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/PurgeExpungedResourcesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/PurgeExpungedResourcesCmd.java
new file mode 100644
index 00000000000..b6833f09733
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/PurgeExpungedResourcesCmd.java
@@ -0,0 +1,131 @@
+// 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.resource;
+
+
+import java.util.Date;
+
+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.ResponseObject;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.PurgeExpungedResourcesResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.resource.ResourceCleanupService;
+
+import com.cloud.event.EventTypes;
+
+@APICommand(name = "purgeExpungedResources",
+ description = "Purge expunged resources",
+ responseObject = SuccessResponse.class,
+ responseView = ResponseObject.ResponseView.Full,
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ authorized = {RoleType.Admin},
+ since = "4.20")
+public class PurgeExpungedResourcesCmd extends BaseAsyncCmd {
+
+ @Inject
+ ResourceCleanupService resourceCleanupService;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.RESOURCE_TYPE, type = BaseCmd.CommandType.STRING,
+ description = "The type of the resource which need to be purged. Supported types: " +
+ "VirtualMachine")
+ private String resourceType;
+
+ @Parameter(name = ApiConstants.BATCH_SIZE, type = CommandType.LONG,
+ description = "The size of batch used during purging")
+ private Long batchSize;
+
+ @Parameter(name = ApiConstants.START_DATE,
+ type = CommandType.DATE,
+ description = "The start date range of the expunged resources used for purging " +
+ "(use format \"yyyy-MM-dd\" or \"yyyy-MM-dd HH:mm:ss\")")
+ private Date startDate;
+
+ @Parameter(name = ApiConstants.END_DATE,
+ type = CommandType.DATE,
+ description = "The end date range of the expunged resources used for purging " +
+ "(use format \"yyyy-MM-dd\" or \"yyyy-MM-dd HH:mm:ss\")")
+ private Date endDate;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+
+ public String getResourceType() {
+ return resourceType;
+ }
+
+ public Long getBatchSize() {
+ return batchSize;
+ }
+
+ public Date getStartDate() {
+ return startDate;
+ }
+
+ public Date getEndDate() {
+ return endDate;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_PURGE_EXPUNGED_RESOURCES;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Purging expunged resources";
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public void execute() {
+ try {
+ long result = resourceCleanupService.purgeExpungedResources(this);
+ PurgeExpungedResourcesResponse response = new PurgeExpungedResourcesResponse();
+ response.setResourceCount(result);
+ response.setObjectName(getCommandName().toLowerCase());
+ setResponseObject(response);
+ } catch (Exception e) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getLocalizedMessage());
+ }
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ChangeStoragePoolScopeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ChangeStoragePoolScopeCmd.java
new file mode 100644
index 00000000000..d3b6a074610
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ChangeStoragePoolScopeCmd.java
@@ -0,0 +1,98 @@
+// 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.storage;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandResourceType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.ClusterResponse;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.storage.StoragePool;
+
+@APICommand(name = "changeStoragePoolScope", description = "Changes the scope of a storage pool when the pool is in Disabled state." +
+ "This feature is officially tested and supported for Hypervisors: KVM and VMware, Protocols: NFS and Ceph, and Storage Provider: DefaultPrimary. " +
+ "There might be extra steps involved to make this work for other hypervisors and storage options.",
+ responseObject = SuccessResponse.class, since= "4.19.1", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ChangeStoragePoolScopeCmd extends BaseAsyncCmd {
+
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = StoragePoolResponse.class, required = true, description = "the Id of the storage pool")
+ private Long id;
+
+ @Parameter(name = ApiConstants.SCOPE, type = CommandType.STRING, required = true, description = "the scope of the storage: cluster or zone")
+ private String scope;
+
+ @Parameter(name = ApiConstants.CLUSTER_ID, type = CommandType.UUID, entityType = ClusterResponse.class, description = "the Id of the cluster to use if scope is being set to Cluster")
+ private Long clusterId;
+
+ @Override
+ public ApiCommandResourceType getApiResourceType() {
+ return ApiCommandResourceType.StoragePool;
+ }
+
+ @Override
+ public Long getApiResourceId() {
+ return getId();
+ }
+
+ public String getEventType() {
+ return EventTypes.EVENT_CHANGE_STORAGE_POOL_SCOPE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ String description = "Change storage pool scope. Storage pool Id: ";
+ StoragePool pool = _entityMgr.findById(StoragePool.class, getId());
+ if (pool != null) {
+ description += pool.getUuid();
+ } else {
+ description += getId();
+ }
+ description += " to " + getScope();
+ return description;
+ }
+
+ @Override
+ public void execute() {
+ _storageService.changeStoragePoolScope(this);
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ this.setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccountId();
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public Long getClusterId() {
+ return clusterId;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java
index 293ed3103cb..57a87939b6b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java
@@ -72,7 +72,8 @@ public class ListStoragePoolsCmd extends BaseListCmd {
@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, description = "host ID of the storage pools")
private Long hostId;
-
+ @Parameter(name = ApiConstants.STORAGE_CUSTOM_STATS, type = CommandType.BOOLEAN, description = "If true, lists the custom stats of the storage pool", since = "4.18.1")
+ private Boolean customStats;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -129,6 +130,10 @@ public class ListStoragePoolsCmd extends BaseListCmd {
this.scope = scope;
}
+ public Boolean getCustomStats() {
+ return customStats != null && customStats;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateImageStoreCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateImageStoreCmd.java
index bcc438b957b..0e1631a46ba 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateImageStoreCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateImageStoreCmd.java
@@ -39,10 +39,17 @@ public class UpdateImageStoreCmd extends BaseCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ImageStoreResponse.class, required = true, description = "Image Store UUID")
private Long id;
- @Parameter(name = ApiConstants.READ_ONLY, type = CommandType.BOOLEAN, required = true, description = "If set to true, it designates the corresponding image store to read-only, " +
- "hence not considering them during storage migration")
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = false, description = "The new name for the Image Store.")
+ private String name;
+
+ @Parameter(name = ApiConstants.READ_ONLY, type = CommandType.BOOLEAN, required = false,
+ description = "If set to true, it designates the corresponding image store to read-only, hence not considering them during storage migration")
private Boolean readonly;
+ @Parameter(name = ApiConstants.CAPACITY_BYTES, type = CommandType.LONG, required = false,
+ description = "The number of bytes CloudStack can use on this image storage.\n\tNOTE: this will be overwritten by the StatsCollector as soon as there is a SSVM to query the storage.")
+ private Long capacityBytes;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -51,17 +58,25 @@ public class UpdateImageStoreCmd extends BaseCmd {
return id;
}
+ public String getName() {
+ return name;
+ }
+
public Boolean getReadonly() {
return readonly;
}
+ public Long getCapacityBytes() {
+ return capacityBytes;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() {
- ImageStore result = _storageService.updateImageStoreStatus(getId(), getReadonly());
+ ImageStore result = _storageService.updateImageStore(this);
ImageStoreResponse storeResponse = null;
if (result != null) {
storeResponse = _responseGenerator.createImageStoreResponse(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateStoragePoolCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateStoragePoolCmd.java
index 13f02ef83c2..f2d7bbeb189 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateStoragePoolCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateStoragePoolCmd.java
@@ -31,6 +31,8 @@ import org.apache.cloudstack.api.response.StoragePoolResponse;
import com.cloud.storage.StoragePool;
import com.cloud.user.Account;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.ObjectUtils;
@SuppressWarnings("rawtypes")
@APICommand(name = "updateStoragePool", description = "Updates a storage pool.", responseObject = StoragePoolResponse.class, since = "3.0.0",
@@ -147,7 +149,17 @@ public class UpdateStoragePoolCmd extends BaseCmd {
@Override
public void execute() {
- StoragePool result = _storageService.updateStoragePool(this);
+ StoragePool result = null;
+ if (ObjectUtils.anyNotNull(name, capacityIops, capacityBytes, url, isTagARule, tags) ||
+ MapUtils.isNotEmpty(details)) {
+ result = _storageService.updateStoragePool(this);
+ }
+
+ if (enabled != null) {
+ result = enabled ? _storageService.enablePrimaryStoragePool(id)
+ : _storageService.disablePrimaryStoragePool(id);
+ }
+
if (result != null) {
StoragePoolResponse response = _responseGenerator.createStoragePoolResponse(result);
response.setResponseName(getCommandName());
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/heuristics/RemoveSecondaryStorageSelectorCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/heuristics/RemoveSecondaryStorageSelectorCmd.java
index 79554f44782..468c87d4d99 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/heuristics/RemoveSecondaryStorageSelectorCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/heuristics/RemoveSecondaryStorageSelectorCmd.java
@@ -27,7 +27,7 @@ import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.secstorage.heuristics.Heuristic;
@APICommand(name = "removeSecondaryStorageSelector", description = "Removes an existing secondary storage selector.", since = "4.19.0", responseObject =
- SecondaryStorageHeuristicsResponse.class, requestHasSensitiveInfo = false, entityType = {Heuristic.class}, responseHasSensitiveInfo = false, authorized = {RoleType.Admin})
+ SuccessResponse.class, requestHasSensitiveInfo = false, entityType = {Heuristic.class}, responseHasSensitiveInfo = false, authorized = {RoleType.Admin})
public class RemoveSecondaryStorageSelectorCmd extends BaseCmd {
@Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, entityType = SecondaryStorageHeuristicsResponse.class, required = true,
description = "The unique identifier of the secondary storage selector to be removed.")
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/GenerateUsageRecordsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/GenerateUsageRecordsCmd.java
index 491b0fe85ba..a0314586d92 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/GenerateUsageRecordsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/GenerateUsageRecordsCmd.java
@@ -47,13 +47,13 @@ public class GenerateUsageRecordsCmd extends BaseCmd {
@Parameter(name = ApiConstants.END_DATE,
type = CommandType.DATE,
- required = true,
+ required = false,
description = "End date range for usage record query. Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-03.")
private Date endDate;
@Parameter(name = ApiConstants.START_DATE,
type = CommandType.DATE,
- required = true,
+ required = false,
description = "Start date range for usage record query. Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-01.")
private Date startDate;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListUsageTypesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListUsageTypesCmd.java
index 2772743c75a..b993735dba7 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListUsageTypesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListUsageTypesCmd.java
@@ -23,6 +23,7 @@ import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.UsageTypeResponse;
+import org.apache.cloudstack.usage.UsageTypes;
import com.cloud.user.Account;
@@ -37,8 +38,8 @@ public class ListUsageTypesCmd extends BaseCmd {
@Override
public void execute() {
- List result = _usageService.listUsageTypes();
- ListResponse response = new ListResponse();
+ List result = UsageTypes.listUsageTypes();
+ ListResponse response = new ListResponse<>();
response.setResponses(result);
response.setResponseName(getCommandName());
this.setResponseObject(response);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java
index 3f8d386d266..c9e1e934152 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java
@@ -66,7 +66,7 @@ public class UpdateUserCmd extends BaseCmd {
@Parameter(name = ApiConstants.CURRENT_PASSWORD, type = CommandType.STRING, description = "Current password that was being used by the user. You must inform the current password when updating the password.", acceptedOnAdminPort = false)
private String currentPassword;
- @Parameter(name = ApiConstants.SECRET_KEY, type = CommandType.STRING, description = "The secret key for the user. Must be specified with userApiKey")
+ @Parameter(name = ApiConstants.USER_SECRET_KEY, type = CommandType.STRING, description = "The secret key for the user. Must be specified with userApiKey")
private String secretKey;
@Parameter(name = ApiConstants.TIMEZONE,
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportUnmanagedInstanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportUnmanagedInstanceCmd.java
index dd897218a4d..ae6ceff26c7 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportUnmanagedInstanceCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportUnmanagedInstanceCmd.java
@@ -201,8 +201,8 @@ public class ImportUnmanagedInstanceCmd extends BaseAsyncCmd {
for (Map entry : (Collection