From 15c2e50338a514cb51e6ef3443261a7d3971f69c Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Mon, 3 Nov 2025 15:36:52 +0100 Subject: [PATCH 001/101] UI: fix typo Upload SSL certificate (#11869) --- ui/public/locales/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 4f450e940fc0..805ea1adae94 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -2623,7 +2623,7 @@ "label.upload.icon": "Upload icon", "label.upload.iso.from.local": "Upload ISO from local", "label.upload.resource.icon": "Upload icon", -"label.upload.ssl.certificate": "Upload SSL cerficicate", +"label.upload.ssl.certificate": "Upload SSL certificate", "label.upload.template.from.local": "Upload Template from local", "label.upload.volume": "Upload volume", "label.upload.volume.from.local": "Upload Volume from local", From dbda673e1fa813856deb0f0b6328dad0222b702c Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Wed, 5 Nov 2025 16:53:04 +0530 Subject: [PATCH 002/101] Updating pom.xml version numbers for release 4.23.0.0-SNAPSHOT Signed-off-by: Harikrishna Patnala --- agent/pom.xml | 2 +- api/pom.xml | 2 +- client/pom.xml | 2 +- core/pom.xml | 2 +- debian/changelog | 8 ++++---- developer/pom.xml | 2 +- engine/api/pom.xml | 2 +- engine/components-api/pom.xml | 2 +- engine/orchestration/pom.xml | 2 +- engine/pom.xml | 2 +- engine/schema/pom.xml | 2 +- engine/service/pom.xml | 2 +- engine/storage/cache/pom.xml | 2 +- engine/storage/configdrive/pom.xml | 2 +- engine/storage/datamotion/pom.xml | 2 +- engine/storage/image/pom.xml | 2 +- engine/storage/integration-test/pom.xml | 2 +- engine/storage/object/pom.xml | 2 +- engine/storage/pom.xml | 2 +- engine/storage/snapshot/pom.xml | 2 +- engine/storage/volume/pom.xml | 2 +- engine/userdata/cloud-init/pom.xml | 2 +- engine/userdata/pom.xml | 2 +- framework/agent-lb/pom.xml | 2 +- framework/ca/pom.xml | 2 +- framework/cluster/pom.xml | 2 +- framework/config/pom.xml | 2 +- framework/db/pom.xml | 2 +- framework/direct-download/pom.xml | 2 +- framework/events/pom.xml | 2 +- framework/extensions/pom.xml | 6 +++--- framework/ipc/pom.xml | 2 +- framework/jobs/pom.xml | 2 +- framework/managed-context/pom.xml | 2 +- framework/pom.xml | 2 +- framework/quota/pom.xml | 2 +- framework/rest/pom.xml | 2 +- framework/security/pom.xml | 2 +- framework/spring/lifecycle/pom.xml | 2 +- framework/spring/module/pom.xml | 2 +- plugins/acl/dynamic-role-based/pom.xml | 2 +- plugins/acl/project-role-based/pom.xml | 2 +- plugins/acl/static-role-based/pom.xml | 2 +- .../affinity-group-processors/explicit-dedication/pom.xml | 2 +- plugins/affinity-group-processors/host-affinity/pom.xml | 2 +- .../affinity-group-processors/host-anti-affinity/pom.xml | 2 +- .../non-strict-host-affinity/pom.xml | 2 +- .../non-strict-host-anti-affinity/pom.xml | 2 +- plugins/alert-handlers/snmp-alerts/pom.xml | 2 +- plugins/alert-handlers/syslog-alerts/pom.xml | 2 +- plugins/api/discovery/pom.xml | 2 +- plugins/api/rate-limit/pom.xml | 2 +- plugins/api/solidfire-intg-test/pom.xml | 2 +- plugins/api/vmware-sioc/pom.xml | 2 +- plugins/backup/dummy/pom.xml | 2 +- plugins/backup/nas/pom.xml | 2 +- plugins/backup/networker/pom.xml | 2 +- plugins/backup/veeam/pom.xml | 2 +- plugins/ca/root-ca/pom.xml | 2 +- plugins/database/mysql-ha/pom.xml | 2 +- plugins/database/quota/pom.xml | 2 +- plugins/dedicated-resources/pom.xml | 2 +- plugins/deployment-planners/implicit-dedication/pom.xml | 2 +- plugins/deployment-planners/user-concentrated-pod/pom.xml | 2 +- plugins/deployment-planners/user-dispersing/pom.xml | 2 +- plugins/drs/cluster/balanced/pom.xml | 2 +- plugins/drs/cluster/condensed/pom.xml | 2 +- plugins/event-bus/inmemory/pom.xml | 2 +- plugins/event-bus/kafka/pom.xml | 2 +- plugins/event-bus/rabbitmq/pom.xml | 2 +- plugins/event-bus/webhook/pom.xml | 2 +- plugins/ha-planners/skip-heurestics/pom.xml | 2 +- plugins/host-allocators/random/pom.xml | 2 +- plugins/hypervisors/baremetal/pom.xml | 2 +- plugins/hypervisors/external/pom.xml | 2 +- plugins/hypervisors/hyperv/pom.xml | 2 +- plugins/hypervisors/kvm/pom.xml | 2 +- plugins/hypervisors/ovm/pom.xml | 2 +- plugins/hypervisors/ovm3/pom.xml | 2 +- plugins/hypervisors/simulator/pom.xml | 2 +- plugins/hypervisors/ucs/pom.xml | 2 +- plugins/hypervisors/vmware/pom.xml | 2 +- plugins/hypervisors/xenserver/pom.xml | 2 +- plugins/integrations/cloudian/pom.xml | 2 +- plugins/integrations/kubernetes-service/pom.xml | 2 +- plugins/integrations/prometheus/pom.xml | 2 +- plugins/maintenance/pom.xml | 2 +- plugins/metrics/pom.xml | 2 +- plugins/network-elements/bigswitch/pom.xml | 2 +- plugins/network-elements/brocade-vcs/pom.xml | 2 +- plugins/network-elements/cisco-vnmc/pom.xml | 2 +- plugins/network-elements/dns-notifier/pom.xml | 2 +- plugins/network-elements/elastic-loadbalancer/pom.xml | 2 +- plugins/network-elements/globodns/pom.xml | 2 +- plugins/network-elements/internal-loadbalancer/pom.xml | 2 +- plugins/network-elements/juniper-contrail/pom.xml | 2 +- plugins/network-elements/netris/pom.xml | 2 +- plugins/network-elements/netscaler/pom.xml | 2 +- plugins/network-elements/nicira-nvp/pom.xml | 2 +- plugins/network-elements/nsx/pom.xml | 2 +- plugins/network-elements/opendaylight/pom.xml | 2 +- plugins/network-elements/ovs/pom.xml | 2 +- plugins/network-elements/palo-alto/pom.xml | 2 +- plugins/network-elements/stratosphere-ssp/pom.xml | 2 +- plugins/network-elements/tungsten/pom.xml | 2 +- plugins/network-elements/vxlan/pom.xml | 2 +- plugins/outofbandmanagement-drivers/ipmitool/pom.xml | 2 +- .../outofbandmanagement-drivers/nested-cloudstack/pom.xml | 2 +- plugins/outofbandmanagement-drivers/redfish/pom.xml | 2 +- plugins/pom.xml | 2 +- plugins/storage-allocators/random/pom.xml | 2 +- plugins/storage/image/default/pom.xml | 2 +- plugins/storage/image/s3/pom.xml | 2 +- plugins/storage/image/sample/pom.xml | 2 +- plugins/storage/image/swift/pom.xml | 2 +- plugins/storage/object/ceph/pom.xml | 2 +- plugins/storage/object/cloudian/pom.xml | 2 +- plugins/storage/object/minio/pom.xml | 2 +- plugins/storage/object/simulator/pom.xml | 2 +- plugins/storage/sharedfs/storagevm/pom.xml | 2 +- plugins/storage/volume/adaptive/pom.xml | 2 +- plugins/storage/volume/cloudbyte/pom.xml | 2 +- plugins/storage/volume/datera/pom.xml | 2 +- plugins/storage/volume/default/pom.xml | 2 +- plugins/storage/volume/flasharray/pom.xml | 2 +- plugins/storage/volume/linstor/pom.xml | 2 +- plugins/storage/volume/nexenta/pom.xml | 2 +- plugins/storage/volume/primera/pom.xml | 2 +- plugins/storage/volume/sample/pom.xml | 2 +- plugins/storage/volume/scaleio/pom.xml | 2 +- plugins/storage/volume/solidfire/pom.xml | 2 +- plugins/storage/volume/storpool/pom.xml | 2 +- plugins/user-authenticators/ldap/pom.xml | 2 +- plugins/user-authenticators/md5/pom.xml | 2 +- plugins/user-authenticators/oauth2/pom.xml | 2 +- plugins/user-authenticators/pbkdf2/pom.xml | 2 +- plugins/user-authenticators/plain-text/pom.xml | 2 +- plugins/user-authenticators/saml2/pom.xml | 2 +- plugins/user-authenticators/sha256salted/pom.xml | 2 +- plugins/user-two-factor-authenticators/static-pin/pom.xml | 2 +- plugins/user-two-factor-authenticators/totp/pom.xml | 2 +- pom.xml | 2 +- quickcloud/pom.xml | 2 +- server/pom.xml | 4 ++-- services/console-proxy/pom.xml | 2 +- services/console-proxy/rdpconsole/pom.xml | 2 +- services/console-proxy/server/pom.xml | 2 +- services/pom.xml | 2 +- services/secondary-storage/controller/pom.xml | 2 +- services/secondary-storage/pom.xml | 2 +- services/secondary-storage/server/pom.xml | 2 +- systemvm/pom.xml | 2 +- test/pom.xml | 2 +- tools/apidoc/pom.xml | 2 +- tools/checkstyle/pom.xml | 2 +- tools/devcloud-kvm/pom.xml | 2 +- tools/devcloud4/pom.xml | 2 +- tools/docker/Dockerfile | 2 +- tools/docker/Dockerfile.marvin | 4 ++-- tools/marvin/pom.xml | 2 +- tools/marvin/setup.py | 2 +- tools/pom.xml | 2 +- usage/pom.xml | 2 +- utils/pom.xml | 2 +- vmware-base/pom.xml | 2 +- 165 files changed, 172 insertions(+), 172 deletions(-) diff --git a/agent/pom.xml b/agent/pom.xml index 4fa30e4f78e2..5ab6cfe17c13 100644 --- a/agent/pom.xml +++ b/agent/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT diff --git a/api/pom.xml b/api/pom.xml index 405365451c6f..c80c35593451 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT diff --git a/client/pom.xml b/client/pom.xml index 94d844be3c42..d8fa433d5be3 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index 1bf7c28674d6..f91a330b7ba9 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT diff --git a/debian/changelog b/debian/changelog index 6d288afc4db0..02251137e9d0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,12 +1,12 @@ -cloudstack (4.22.1.0-SNAPSHOT) unstable; urgency=low +cloudstack (4.23.0.0-SNAPSHOT) unstable; urgency=low - * Update the version to 4.22.1.0-SNAPSHOT + * Update the version to 4.23.0.0-SNAPSHOT -- the Apache CloudStack project Thu, 30 Oct 2025 19:23:55 +0530 -cloudstack (4.22.1.0-SNAPSHOT-SNAPSHOT) unstable; urgency=low +cloudstack (4.23.0.0-SNAPSHOT-SNAPSHOT) unstable; urgency=low - * Update the version to 4.22.1.0-SNAPSHOT-SNAPSHOT + * Update the version to 4.23.0.0-SNAPSHOT-SNAPSHOT -- the Apache CloudStack project Thu, Aug 28 11:58:36 2025 +0530 diff --git a/developer/pom.xml b/developer/pom.xml index de6a8ef3d10a..e2fd782fd25f 100644 --- a/developer/pom.xml +++ b/developer/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT diff --git a/engine/api/pom.xml b/engine/api/pom.xml index 2f7e15aaab05..cb50ef0cd46b 100644 --- a/engine/api/pom.xml +++ b/engine/api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/engine/components-api/pom.xml b/engine/components-api/pom.xml index 8caf8ccbff69..49d41d36f83d 100644 --- a/engine/components-api/pom.xml +++ b/engine/components-api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/engine/orchestration/pom.xml b/engine/orchestration/pom.xml index cd5578d245ca..fda63d2558b0 100755 --- a/engine/orchestration/pom.xml +++ b/engine/orchestration/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/engine/pom.xml b/engine/pom.xml index 821a4f8f54ce..2de84eab85af 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/engine/schema/pom.xml b/engine/schema/pom.xml index 7d88f649245c..654cd14a25d3 100644 --- a/engine/schema/pom.xml +++ b/engine/schema/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/engine/service/pom.xml b/engine/service/pom.xml index c429ebf5da5a..9b833804064e 100644 --- a/engine/service/pom.xml +++ b/engine/service/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT cloud-engine-service war diff --git a/engine/storage/cache/pom.xml b/engine/storage/cache/pom.xml index 2e736ad42e55..ac330ca69974 100644 --- a/engine/storage/cache/pom.xml +++ b/engine/storage/cache/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/configdrive/pom.xml b/engine/storage/configdrive/pom.xml index d5ef49d7ef78..43eb249b5386 100644 --- a/engine/storage/configdrive/pom.xml +++ b/engine/storage/configdrive/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/datamotion/pom.xml b/engine/storage/datamotion/pom.xml index aa5a6d1f8f87..d3b6bb543520 100644 --- a/engine/storage/datamotion/pom.xml +++ b/engine/storage/datamotion/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/image/pom.xml b/engine/storage/image/pom.xml index 0232e404f5a7..2cdef352e7b8 100644 --- a/engine/storage/image/pom.xml +++ b/engine/storage/image/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index 2ca31465e08d..13f0b45dd21f 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/object/pom.xml b/engine/storage/object/pom.xml index a9e3aeac4674..d5f2a793948c 100644 --- a/engine/storage/object/pom.xml +++ b/engine/storage/object/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml index 72e9def90a3d..a2044c6f4f86 100644 --- a/engine/storage/pom.xml +++ b/engine/storage/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml index 14b0ce92f8b0..177ab1069d9f 100644 --- a/engine/storage/snapshot/pom.xml +++ b/engine/storage/snapshot/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/volume/pom.xml b/engine/storage/volume/pom.xml index 42399bc75622..5422218ef02b 100644 --- a/engine/storage/volume/pom.xml +++ b/engine/storage/volume/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/userdata/cloud-init/pom.xml b/engine/userdata/cloud-init/pom.xml index 2b5d55948ede..a49a8ece0cef 100644 --- a/engine/userdata/cloud-init/pom.xml +++ b/engine/userdata/cloud-init/pom.xml @@ -23,7 +23,7 @@ cloud-engine org.apache.cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/userdata/pom.xml b/engine/userdata/pom.xml index 001825841565..56c181ae0602 100644 --- a/engine/userdata/pom.xml +++ b/engine/userdata/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/framework/agent-lb/pom.xml b/framework/agent-lb/pom.xml index cba750d3c7fb..b9d728f9bdc6 100644 --- a/framework/agent-lb/pom.xml +++ b/framework/agent-lb/pom.xml @@ -24,7 +24,7 @@ cloudstack-framework org.apache.cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/framework/ca/pom.xml b/framework/ca/pom.xml index e7d85c089bb7..b090dbe40df8 100644 --- a/framework/ca/pom.xml +++ b/framework/ca/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/framework/cluster/pom.xml b/framework/cluster/pom.xml index da3de5ebf751..2dd28e8e628f 100644 --- a/framework/cluster/pom.xml +++ b/framework/cluster/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/framework/config/pom.xml b/framework/config/pom.xml index 9fbbc4a0cd72..dea2f14420ec 100644 --- a/framework/config/pom.xml +++ b/framework/config/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/framework/db/pom.xml b/framework/db/pom.xml index c03fb0654bd8..04d0fcc7e899 100644 --- a/framework/db/pom.xml +++ b/framework/db/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/framework/direct-download/pom.xml b/framework/direct-download/pom.xml index 913bef072a04..22e878178ae4 100644 --- a/framework/direct-download/pom.xml +++ b/framework/direct-download/pom.xml @@ -32,7 +32,7 @@ cloudstack-framework org.apache.cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/framework/events/pom.xml b/framework/events/pom.xml index 173b18a4df2e..3a0d37468688 100644 --- a/framework/events/pom.xml +++ b/framework/events/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/framework/extensions/pom.xml b/framework/extensions/pom.xml index 76952555698a..4d42d6840ddf 100644 --- a/framework/extensions/pom.xml +++ b/framework/extensions/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml @@ -41,13 +41,13 @@ org.apache.cloudstack cloud-engine-schema - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT compile org.apache.cloudstack cloud-engine-components-api - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT compile diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml index 0d13898f3f84..d9fa9d852714 100644 --- a/framework/ipc/pom.xml +++ b/framework/ipc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/framework/jobs/pom.xml b/framework/jobs/pom.xml index f3249727c3a4..ad342acf8d83 100644 --- a/framework/jobs/pom.xml +++ b/framework/jobs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/framework/managed-context/pom.xml b/framework/managed-context/pom.xml index c0950855ef45..70f20ecb04e3 100644 --- a/framework/managed-context/pom.xml +++ b/framework/managed-context/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/framework/pom.xml b/framework/pom.xml index 02ce0a09b817..337e5b0268b2 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT diff --git a/framework/quota/pom.xml b/framework/quota/pom.xml index 52f0d658f009..70cb3ac8cd53 100644 --- a/framework/quota/pom.xml +++ b/framework/quota/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/framework/rest/pom.xml b/framework/rest/pom.xml index bb69f909ba22..e2e787aec460 100644 --- a/framework/rest/pom.xml +++ b/framework/rest/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-framework - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml cloud-framework-rest diff --git a/framework/security/pom.xml b/framework/security/pom.xml index a36978e4ef64..30940b68f1a9 100644 --- a/framework/security/pom.xml +++ b/framework/security/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/framework/spring/lifecycle/pom.xml b/framework/spring/lifecycle/pom.xml index ff6b59567dad..90a26a7be238 100644 --- a/framework/spring/lifecycle/pom.xml +++ b/framework/spring/lifecycle/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/framework/spring/module/pom.xml b/framework/spring/module/pom.xml index 77a9646a984e..f44cffa30b10 100644 --- a/framework/spring/module/pom.xml +++ b/framework/spring/module/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/acl/dynamic-role-based/pom.xml b/plugins/acl/dynamic-role-based/pom.xml index f975afc6e5fa..0b0b2300e777 100644 --- a/plugins/acl/dynamic-role-based/pom.xml +++ b/plugins/acl/dynamic-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/acl/project-role-based/pom.xml b/plugins/acl/project-role-based/pom.xml index ae00e850aa7e..2c351bdbc8ca 100644 --- a/plugins/acl/project-role-based/pom.xml +++ b/plugins/acl/project-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/acl/static-role-based/pom.xml b/plugins/acl/static-role-based/pom.xml index ee088e3bd432..c6e790b485e6 100644 --- a/plugins/acl/static-role-based/pom.xml +++ b/plugins/acl/static-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/affinity-group-processors/explicit-dedication/pom.xml b/plugins/affinity-group-processors/explicit-dedication/pom.xml index 1d5b5303c7e5..769773e9dca3 100644 --- a/plugins/affinity-group-processors/explicit-dedication/pom.xml +++ b/plugins/affinity-group-processors/explicit-dedication/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/affinity-group-processors/host-affinity/pom.xml b/plugins/affinity-group-processors/host-affinity/pom.xml index f0c13e050361..925da93b29c7 100644 --- a/plugins/affinity-group-processors/host-affinity/pom.xml +++ b/plugins/affinity-group-processors/host-affinity/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/affinity-group-processors/host-anti-affinity/pom.xml b/plugins/affinity-group-processors/host-anti-affinity/pom.xml index 00895373ca94..9b83518d7792 100644 --- a/plugins/affinity-group-processors/host-anti-affinity/pom.xml +++ b/plugins/affinity-group-processors/host-anti-affinity/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/affinity-group-processors/non-strict-host-affinity/pom.xml b/plugins/affinity-group-processors/non-strict-host-affinity/pom.xml index fc626289a35d..f0bc9e0d7e93 100644 --- a/plugins/affinity-group-processors/non-strict-host-affinity/pom.xml +++ b/plugins/affinity-group-processors/non-strict-host-affinity/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/affinity-group-processors/non-strict-host-anti-affinity/pom.xml b/plugins/affinity-group-processors/non-strict-host-anti-affinity/pom.xml index b474f7647a9b..b12e49f62ddb 100644 --- a/plugins/affinity-group-processors/non-strict-host-anti-affinity/pom.xml +++ b/plugins/affinity-group-processors/non-strict-host-anti-affinity/pom.xml @@ -32,7 +32,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/alert-handlers/snmp-alerts/pom.xml b/plugins/alert-handlers/snmp-alerts/pom.xml index 3beb2ce8d914..ea89037aa2be 100644 --- a/plugins/alert-handlers/snmp-alerts/pom.xml +++ b/plugins/alert-handlers/snmp-alerts/pom.xml @@ -24,7 +24,7 @@ cloudstack-plugins org.apache.cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/alert-handlers/syslog-alerts/pom.xml b/plugins/alert-handlers/syslog-alerts/pom.xml index 5241ec011436..a4ae4f089530 100644 --- a/plugins/alert-handlers/syslog-alerts/pom.xml +++ b/plugins/alert-handlers/syslog-alerts/pom.xml @@ -24,7 +24,7 @@ cloudstack-plugins org.apache.cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/api/discovery/pom.xml b/plugins/api/discovery/pom.xml index 525a5583e51e..b0f29612911c 100644 --- a/plugins/api/discovery/pom.xml +++ b/plugins/api/discovery/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/api/rate-limit/pom.xml b/plugins/api/rate-limit/pom.xml index 4d802cabac4f..294ff18bcc9b 100644 --- a/plugins/api/rate-limit/pom.xml +++ b/plugins/api/rate-limit/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/api/solidfire-intg-test/pom.xml b/plugins/api/solidfire-intg-test/pom.xml index ca2a0328cade..0cc9d1aba5a2 100644 --- a/plugins/api/solidfire-intg-test/pom.xml +++ b/plugins/api/solidfire-intg-test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/api/vmware-sioc/pom.xml b/plugins/api/vmware-sioc/pom.xml index 10a1853fedc1..e523568dc506 100644 --- a/plugins/api/vmware-sioc/pom.xml +++ b/plugins/api/vmware-sioc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/backup/dummy/pom.xml b/plugins/backup/dummy/pom.xml index c15b5dcab63b..63c89cdb3e06 100644 --- a/plugins/backup/dummy/pom.xml +++ b/plugins/backup/dummy/pom.xml @@ -23,7 +23,7 @@ cloudstack-plugins org.apache.cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/backup/nas/pom.xml b/plugins/backup/nas/pom.xml index aae1e61970cc..3c7cd8ab681f 100644 --- a/plugins/backup/nas/pom.xml +++ b/plugins/backup/nas/pom.xml @@ -25,7 +25,7 @@ cloudstack-plugins org.apache.cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/backup/networker/pom.xml b/plugins/backup/networker/pom.xml index 55b827e29d14..cad2b3454355 100644 --- a/plugins/backup/networker/pom.xml +++ b/plugins/backup/networker/pom.xml @@ -25,7 +25,7 @@ cloudstack-plugins org.apache.cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/backup/veeam/pom.xml b/plugins/backup/veeam/pom.xml index dd145bc5e113..a2dcbd1d3487 100644 --- a/plugins/backup/veeam/pom.xml +++ b/plugins/backup/veeam/pom.xml @@ -23,7 +23,7 @@ cloudstack-plugins org.apache.cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/ca/root-ca/pom.xml b/plugins/ca/root-ca/pom.xml index 501ba480b80e..2224ae06c850 100644 --- a/plugins/ca/root-ca/pom.xml +++ b/plugins/ca/root-ca/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/database/mysql-ha/pom.xml b/plugins/database/mysql-ha/pom.xml index 518443c91e72..eb1b1d571f11 100644 --- a/plugins/database/mysql-ha/pom.xml +++ b/plugins/database/mysql-ha/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/database/quota/pom.xml b/plugins/database/quota/pom.xml index 5ecbefbcf2b6..52645385aaba 100644 --- a/plugins/database/quota/pom.xml +++ b/plugins/database/quota/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/dedicated-resources/pom.xml b/plugins/dedicated-resources/pom.xml index 8d4c21e9cb26..557668661f3f 100644 --- a/plugins/dedicated-resources/pom.xml +++ b/plugins/dedicated-resources/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/plugins/deployment-planners/implicit-dedication/pom.xml b/plugins/deployment-planners/implicit-dedication/pom.xml index bfc0e24a8ac8..c33d6d07293c 100644 --- a/plugins/deployment-planners/implicit-dedication/pom.xml +++ b/plugins/deployment-planners/implicit-dedication/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/deployment-planners/user-concentrated-pod/pom.xml b/plugins/deployment-planners/user-concentrated-pod/pom.xml index ebbd879076c3..20420fbb0802 100644 --- a/plugins/deployment-planners/user-concentrated-pod/pom.xml +++ b/plugins/deployment-planners/user-concentrated-pod/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/deployment-planners/user-dispersing/pom.xml b/plugins/deployment-planners/user-dispersing/pom.xml index d811b5e88d1b..85c839ceaca0 100644 --- a/plugins/deployment-planners/user-dispersing/pom.xml +++ b/plugins/deployment-planners/user-dispersing/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/drs/cluster/balanced/pom.xml b/plugins/drs/cluster/balanced/pom.xml index 5267d991b846..497dfcbede14 100644 --- a/plugins/drs/cluster/balanced/pom.xml +++ b/plugins/drs/cluster/balanced/pom.xml @@ -27,7 +27,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/drs/cluster/condensed/pom.xml b/plugins/drs/cluster/condensed/pom.xml index d34f3564db51..6e7c33ef55dc 100644 --- a/plugins/drs/cluster/condensed/pom.xml +++ b/plugins/drs/cluster/condensed/pom.xml @@ -27,7 +27,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/event-bus/inmemory/pom.xml b/plugins/event-bus/inmemory/pom.xml index 7704867bc708..5eadc3673f3c 100644 --- a/plugins/event-bus/inmemory/pom.xml +++ b/plugins/event-bus/inmemory/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/event-bus/kafka/pom.xml b/plugins/event-bus/kafka/pom.xml index 5231a723baab..c57572533ad5 100644 --- a/plugins/event-bus/kafka/pom.xml +++ b/plugins/event-bus/kafka/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/event-bus/rabbitmq/pom.xml b/plugins/event-bus/rabbitmq/pom.xml index 738cc7fce6dc..3012ac1057a7 100644 --- a/plugins/event-bus/rabbitmq/pom.xml +++ b/plugins/event-bus/rabbitmq/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/event-bus/webhook/pom.xml b/plugins/event-bus/webhook/pom.xml index 2bbd5b55c01b..cb19b224ce87 100644 --- a/plugins/event-bus/webhook/pom.xml +++ b/plugins/event-bus/webhook/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/ha-planners/skip-heurestics/pom.xml b/plugins/ha-planners/skip-heurestics/pom.xml index e010e7108fc6..43f3abf9cb1d 100644 --- a/plugins/ha-planners/skip-heurestics/pom.xml +++ b/plugins/ha-planners/skip-heurestics/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/host-allocators/random/pom.xml b/plugins/host-allocators/random/pom.xml index d55436e846d3..061caf1573ff 100644 --- a/plugins/host-allocators/random/pom.xml +++ b/plugins/host-allocators/random/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml index 384090e04507..fc4803b79029 100755 --- a/plugins/hypervisors/baremetal/pom.xml +++ b/plugins/hypervisors/baremetal/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-baremetal diff --git a/plugins/hypervisors/external/pom.xml b/plugins/hypervisors/external/pom.xml index 8359b1de3ca3..1c581f3c0e5f 100644 --- a/plugins/hypervisors/external/pom.xml +++ b/plugins/hypervisors/external/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-external diff --git a/plugins/hypervisors/hyperv/pom.xml b/plugins/hypervisors/hyperv/pom.xml index 758cee0ee63f..c67943ab2430 100644 --- a/plugins/hypervisors/hyperv/pom.xml +++ b/plugins/hypervisors/hyperv/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml index 8ed960c6bc0c..a7c5461e7980 100644 --- a/plugins/hypervisors/kvm/pom.xml +++ b/plugins/hypervisors/kvm/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/ovm/pom.xml b/plugins/hypervisors/ovm/pom.xml index 2149926348ee..d29f9afa73a0 100644 --- a/plugins/hypervisors/ovm/pom.xml +++ b/plugins/hypervisors/ovm/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/ovm3/pom.xml b/plugins/hypervisors/ovm3/pom.xml index c88284c8d297..4214ee8a71b3 100644 --- a/plugins/hypervisors/ovm3/pom.xml +++ b/plugins/hypervisors/ovm3/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/simulator/pom.xml b/plugins/hypervisors/simulator/pom.xml index f5942328e3cf..8ef011fa9710 100644 --- a/plugins/hypervisors/simulator/pom.xml +++ b/plugins/hypervisors/simulator/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-simulator diff --git a/plugins/hypervisors/ucs/pom.xml b/plugins/hypervisors/ucs/pom.xml index 521dd7416b5c..67bde3b64294 100644 --- a/plugins/hypervisors/ucs/pom.xml +++ b/plugins/hypervisors/ucs/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-ucs diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml index 355d4488ba90..7637cb7db6d0 100644 --- a/plugins/hypervisors/vmware/pom.xml +++ b/plugins/hypervisors/vmware/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/xenserver/pom.xml b/plugins/hypervisors/xenserver/pom.xml index cafa999d42dc..4d7ebf69db21 100644 --- a/plugins/hypervisors/xenserver/pom.xml +++ b/plugins/hypervisors/xenserver/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/integrations/cloudian/pom.xml b/plugins/integrations/cloudian/pom.xml index 69321f9e558c..1c806acec7ad 100644 --- a/plugins/integrations/cloudian/pom.xml +++ b/plugins/integrations/cloudian/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/integrations/kubernetes-service/pom.xml b/plugins/integrations/kubernetes-service/pom.xml index 9aad4d6d4304..6b5cec95aab9 100644 --- a/plugins/integrations/kubernetes-service/pom.xml +++ b/plugins/integrations/kubernetes-service/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/integrations/prometheus/pom.xml b/plugins/integrations/prometheus/pom.xml index 378eab52471f..6f6b34215a76 100644 --- a/plugins/integrations/prometheus/pom.xml +++ b/plugins/integrations/prometheus/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/maintenance/pom.xml b/plugins/maintenance/pom.xml index 5290b5277674..5b129863a297 100644 --- a/plugins/maintenance/pom.xml +++ b/plugins/maintenance/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/plugins/metrics/pom.xml b/plugins/metrics/pom.xml index 6cba7d8bd043..7f8e56de1835 100644 --- a/plugins/metrics/pom.xml +++ b/plugins/metrics/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/plugins/network-elements/bigswitch/pom.xml b/plugins/network-elements/bigswitch/pom.xml index b1a163eb3ee3..cd5ca8b5e999 100644 --- a/plugins/network-elements/bigswitch/pom.xml +++ b/plugins/network-elements/bigswitch/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/brocade-vcs/pom.xml b/plugins/network-elements/brocade-vcs/pom.xml index e3d7a6cf3adc..1eb716a6f9b0 100644 --- a/plugins/network-elements/brocade-vcs/pom.xml +++ b/plugins/network-elements/brocade-vcs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/cisco-vnmc/pom.xml b/plugins/network-elements/cisco-vnmc/pom.xml index 56ff642f549a..c183d03259ae 100644 --- a/plugins/network-elements/cisco-vnmc/pom.xml +++ b/plugins/network-elements/cisco-vnmc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/dns-notifier/pom.xml b/plugins/network-elements/dns-notifier/pom.xml index 7f87c49a0d48..b57bfb94e69a 100644 --- a/plugins/network-elements/dns-notifier/pom.xml +++ b/plugins/network-elements/dns-notifier/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml cloud-plugin-example-dns-notifier diff --git a/plugins/network-elements/elastic-loadbalancer/pom.xml b/plugins/network-elements/elastic-loadbalancer/pom.xml index 21ed6e32429b..22c61f71087d 100644 --- a/plugins/network-elements/elastic-loadbalancer/pom.xml +++ b/plugins/network-elements/elastic-loadbalancer/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/globodns/pom.xml b/plugins/network-elements/globodns/pom.xml index a03bb1e3cd26..70bf2287e2ac 100644 --- a/plugins/network-elements/globodns/pom.xml +++ b/plugins/network-elements/globodns/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/internal-loadbalancer/pom.xml b/plugins/network-elements/internal-loadbalancer/pom.xml index beb5a54f933b..2051a7c25bb5 100644 --- a/plugins/network-elements/internal-loadbalancer/pom.xml +++ b/plugins/network-elements/internal-loadbalancer/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml index 0b3f8bf0d203..6d76cedf8ddb 100644 --- a/plugins/network-elements/juniper-contrail/pom.xml +++ b/plugins/network-elements/juniper-contrail/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/netris/pom.xml b/plugins/network-elements/netris/pom.xml index 1a3fe5d7e29b..295fa643097f 100644 --- a/plugins/network-elements/netris/pom.xml +++ b/plugins/network-elements/netris/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/netscaler/pom.xml b/plugins/network-elements/netscaler/pom.xml index ab51db5b4809..88a8880e5095 100644 --- a/plugins/network-elements/netscaler/pom.xml +++ b/plugins/network-elements/netscaler/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/nicira-nvp/pom.xml b/plugins/network-elements/nicira-nvp/pom.xml index 40d4863decdf..10a584312071 100644 --- a/plugins/network-elements/nicira-nvp/pom.xml +++ b/plugins/network-elements/nicira-nvp/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/nsx/pom.xml b/plugins/network-elements/nsx/pom.xml index 7dc31d625f3c..e6431d074cac 100644 --- a/plugins/network-elements/nsx/pom.xml +++ b/plugins/network-elements/nsx/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/opendaylight/pom.xml b/plugins/network-elements/opendaylight/pom.xml index a71b86dfecbf..38934e16da2c 100644 --- a/plugins/network-elements/opendaylight/pom.xml +++ b/plugins/network-elements/opendaylight/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/ovs/pom.xml b/plugins/network-elements/ovs/pom.xml index 24f622548c23..ef1326cca6ee 100644 --- a/plugins/network-elements/ovs/pom.xml +++ b/plugins/network-elements/ovs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/palo-alto/pom.xml b/plugins/network-elements/palo-alto/pom.xml index 3e821ec8109a..ee16eccb162d 100644 --- a/plugins/network-elements/palo-alto/pom.xml +++ b/plugins/network-elements/palo-alto/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/stratosphere-ssp/pom.xml b/plugins/network-elements/stratosphere-ssp/pom.xml index 1703012eff36..0288c8a5dd79 100644 --- a/plugins/network-elements/stratosphere-ssp/pom.xml +++ b/plugins/network-elements/stratosphere-ssp/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/tungsten/pom.xml b/plugins/network-elements/tungsten/pom.xml index 793d754baffc..eb83c468f0c4 100644 --- a/plugins/network-elements/tungsten/pom.xml +++ b/plugins/network-elements/tungsten/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/vxlan/pom.xml b/plugins/network-elements/vxlan/pom.xml index 1192c98acafa..e350a3cb98f6 100644 --- a/plugins/network-elements/vxlan/pom.xml +++ b/plugins/network-elements/vxlan/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml index debeb7daab29..82ee440c7eee 100644 --- a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml +++ b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml b/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml index 9c5e44195abd..aefaf6d56569 100644 --- a/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml +++ b/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/redfish/pom.xml b/plugins/outofbandmanagement-drivers/redfish/pom.xml index 0d1b292812d7..eecfe1a7add5 100644 --- a/plugins/outofbandmanagement-drivers/redfish/pom.xml +++ b/plugins/outofbandmanagement-drivers/redfish/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/pom.xml b/plugins/pom.xml index 16e5ed1d8f59..e7d13871285e 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT diff --git a/plugins/storage-allocators/random/pom.xml b/plugins/storage-allocators/random/pom.xml index b1a1c2604a74..db55faba4f11 100644 --- a/plugins/storage-allocators/random/pom.xml +++ b/plugins/storage-allocators/random/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml index 1bac038c6a97..0696ca054ff0 100644 --- a/plugins/storage/image/default/pom.xml +++ b/plugins/storage/image/default/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml index 9c3ea94130dd..607830bc2e82 100644 --- a/plugins/storage/image/s3/pom.xml +++ b/plugins/storage/image/s3/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml index 586eb10f28f8..e7044868e7bf 100644 --- a/plugins/storage/image/sample/pom.xml +++ b/plugins/storage/image/sample/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml index 407106ce935e..1caffdae6c72 100644 --- a/plugins/storage/image/swift/pom.xml +++ b/plugins/storage/image/swift/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/object/ceph/pom.xml b/plugins/storage/object/ceph/pom.xml index f6138add95d3..1f5a4bc50551 100644 --- a/plugins/storage/object/ceph/pom.xml +++ b/plugins/storage/object/ceph/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/object/cloudian/pom.xml b/plugins/storage/object/cloudian/pom.xml index 81c78a8d346a..818469290def 100644 --- a/plugins/storage/object/cloudian/pom.xml +++ b/plugins/storage/object/cloudian/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/object/minio/pom.xml b/plugins/storage/object/minio/pom.xml index 61b9838de49a..d69c2a7498fa 100644 --- a/plugins/storage/object/minio/pom.xml +++ b/plugins/storage/object/minio/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/object/simulator/pom.xml b/plugins/storage/object/simulator/pom.xml index 6efbd1c41aa3..dc4ab0146067 100644 --- a/plugins/storage/object/simulator/pom.xml +++ b/plugins/storage/object/simulator/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/sharedfs/storagevm/pom.xml b/plugins/storage/sharedfs/storagevm/pom.xml index 34594898cc05..2a4ea7411e0d 100644 --- a/plugins/storage/sharedfs/storagevm/pom.xml +++ b/plugins/storage/sharedfs/storagevm/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/adaptive/pom.xml b/plugins/storage/volume/adaptive/pom.xml index e625cd66f53b..337544b9d887 100644 --- a/plugins/storage/volume/adaptive/pom.xml +++ b/plugins/storage/volume/adaptive/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/cloudbyte/pom.xml b/plugins/storage/volume/cloudbyte/pom.xml index 77dadb4ec8fe..453a03ee155d 100644 --- a/plugins/storage/volume/cloudbyte/pom.xml +++ b/plugins/storage/volume/cloudbyte/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/datera/pom.xml b/plugins/storage/volume/datera/pom.xml index 84a5e4c27480..6c4b5808a890 100644 --- a/plugins/storage/volume/datera/pom.xml +++ b/plugins/storage/volume/datera/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/default/pom.xml b/plugins/storage/volume/default/pom.xml index 02e2fb88b229..03d26fb7fd19 100644 --- a/plugins/storage/volume/default/pom.xml +++ b/plugins/storage/volume/default/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/flasharray/pom.xml b/plugins/storage/volume/flasharray/pom.xml index a6da4cf9d582..5adad7a3cdf6 100644 --- a/plugins/storage/volume/flasharray/pom.xml +++ b/plugins/storage/volume/flasharray/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/linstor/pom.xml b/plugins/storage/volume/linstor/pom.xml index ee72aab66a38..0b78f0e26a1e 100644 --- a/plugins/storage/volume/linstor/pom.xml +++ b/plugins/storage/volume/linstor/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/nexenta/pom.xml b/plugins/storage/volume/nexenta/pom.xml index d9ed6fd64a49..d1de59bd24e4 100644 --- a/plugins/storage/volume/nexenta/pom.xml +++ b/plugins/storage/volume/nexenta/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/primera/pom.xml b/plugins/storage/volume/primera/pom.xml index 4f1583a8a7b3..ac4351b2f926 100644 --- a/plugins/storage/volume/primera/pom.xml +++ b/plugins/storage/volume/primera/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/sample/pom.xml b/plugins/storage/volume/sample/pom.xml index 0a9de06ba623..425303a9eb26 100644 --- a/plugins/storage/volume/sample/pom.xml +++ b/plugins/storage/volume/sample/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/scaleio/pom.xml b/plugins/storage/volume/scaleio/pom.xml index 79a707ba7d54..b16640482c8c 100644 --- a/plugins/storage/volume/scaleio/pom.xml +++ b/plugins/storage/volume/scaleio/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/solidfire/pom.xml b/plugins/storage/volume/solidfire/pom.xml index 65a91afc10e3..65ba90b0c386 100644 --- a/plugins/storage/volume/solidfire/pom.xml +++ b/plugins/storage/volume/solidfire/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/storpool/pom.xml b/plugins/storage/volume/storpool/pom.xml index 0829575b2295..7bdc76da81fc 100644 --- a/plugins/storage/volume/storpool/pom.xml +++ b/plugins/storage/volume/storpool/pom.xml @@ -17,7 +17,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/user-authenticators/ldap/pom.xml b/plugins/user-authenticators/ldap/pom.xml index 7f58d8fa28a7..c02d3d511e6e 100644 --- a/plugins/user-authenticators/ldap/pom.xml +++ b/plugins/user-authenticators/ldap/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/md5/pom.xml b/plugins/user-authenticators/md5/pom.xml index 11f0a4272307..f0f998c42c16 100644 --- a/plugins/user-authenticators/md5/pom.xml +++ b/plugins/user-authenticators/md5/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/oauth2/pom.xml b/plugins/user-authenticators/oauth2/pom.xml index 8caf06ff8143..6ab7b9f5faba 100644 --- a/plugins/user-authenticators/oauth2/pom.xml +++ b/plugins/user-authenticators/oauth2/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/pbkdf2/pom.xml b/plugins/user-authenticators/pbkdf2/pom.xml index 75351f20f3f4..6ffa1188e13c 100644 --- a/plugins/user-authenticators/pbkdf2/pom.xml +++ b/plugins/user-authenticators/pbkdf2/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/plain-text/pom.xml b/plugins/user-authenticators/plain-text/pom.xml index ceddc54e34d4..54a9650b64ff 100644 --- a/plugins/user-authenticators/plain-text/pom.xml +++ b/plugins/user-authenticators/plain-text/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/saml2/pom.xml b/plugins/user-authenticators/saml2/pom.xml index 8802ab9260f0..4cd6f70d096c 100644 --- a/plugins/user-authenticators/saml2/pom.xml +++ b/plugins/user-authenticators/saml2/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/sha256salted/pom.xml b/plugins/user-authenticators/sha256salted/pom.xml index 2938e21e2094..2b47e010c26d 100644 --- a/plugins/user-authenticators/sha256salted/pom.xml +++ b/plugins/user-authenticators/sha256salted/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-two-factor-authenticators/static-pin/pom.xml b/plugins/user-two-factor-authenticators/static-pin/pom.xml index 1fe95fa3913d..522e2451e7e4 100644 --- a/plugins/user-two-factor-authenticators/static-pin/pom.xml +++ b/plugins/user-two-factor-authenticators/static-pin/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-two-factor-authenticators/totp/pom.xml b/plugins/user-two-factor-authenticators/totp/pom.xml index dcf051f92170..eb3cc0b1ca61 100644 --- a/plugins/user-two-factor-authenticators/totp/pom.xml +++ b/plugins/user-two-factor-authenticators/totp/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../../pom.xml diff --git a/pom.xml b/pom.xml index cc2cb759b1cc..2a36c1cc4efa 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT pom Apache CloudStack Apache CloudStack is an IaaS ("Infrastructure as a Service") cloud orchestration platform. diff --git a/quickcloud/pom.xml b/quickcloud/pom.xml index d4d759f8986a..cc0bacbd7e77 100644 --- a/quickcloud/pom.xml +++ b/quickcloud/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/server/pom.xml b/server/pom.xml index 3324cdb2e619..2b35a0f42ac8 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT @@ -194,7 +194,7 @@ org.apache.cloudstack cloud-framework-extensions - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT compile diff --git a/services/console-proxy/pom.xml b/services/console-proxy/pom.xml index 43d32fdf61b9..31a5a13a8821 100644 --- a/services/console-proxy/pom.xml +++ b/services/console-proxy/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-services - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/services/console-proxy/rdpconsole/pom.xml b/services/console-proxy/rdpconsole/pom.xml index 541648827c66..058ea891f9cd 100644 --- a/services/console-proxy/rdpconsole/pom.xml +++ b/services/console-proxy/rdpconsole/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml index cff9ae3cfcb6..3f5b9db68c2e 100644 --- a/services/console-proxy/server/pom.xml +++ b/services/console-proxy/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/services/pom.xml b/services/pom.xml index 2205e460ee0c..b6a456b159d8 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/services/secondary-storage/controller/pom.xml b/services/secondary-storage/controller/pom.xml index e3847e294fc1..d8934bbb08bf 100644 --- a/services/secondary-storage/controller/pom.xml +++ b/services/secondary-storage/controller/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml index c1d3f9016151..0cc0115c0caa 100644 --- a/services/secondary-storage/pom.xml +++ b/services/secondary-storage/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-services - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/services/secondary-storage/server/pom.xml b/services/secondary-storage/server/pom.xml index ca878ce9ba61..e6aec8a42f70 100644 --- a/services/secondary-storage/server/pom.xml +++ b/services/secondary-storage/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/systemvm/pom.xml b/systemvm/pom.xml index e2a0315300ba..9bffc45cf4eb 100644 --- a/systemvm/pom.xml +++ b/systemvm/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/test/pom.xml b/test/pom.xml index dd1bdf4ceb84..7f315bb92158 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT diff --git a/tools/apidoc/pom.xml b/tools/apidoc/pom.xml index e9b81eedd5fb..b0e081df97f4 100644 --- a/tools/apidoc/pom.xml +++ b/tools/apidoc/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/tools/checkstyle/pom.xml b/tools/checkstyle/pom.xml index 0fb0efacd608..63f840d64f21 100644 --- a/tools/checkstyle/pom.xml +++ b/tools/checkstyle/pom.xml @@ -22,7 +22,7 @@ Apache CloudStack Developer Tools - Checkstyle Configuration org.apache.cloudstack checkstyle - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT UTF-8 diff --git a/tools/devcloud-kvm/pom.xml b/tools/devcloud-kvm/pom.xml index 4990f0af8be3..a8cd23db9799 100644 --- a/tools/devcloud-kvm/pom.xml +++ b/tools/devcloud-kvm/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/tools/devcloud4/pom.xml b/tools/devcloud4/pom.xml index 1aa48c4b2d0d..1af63b439ad7 100644 --- a/tools/devcloud4/pom.xml +++ b/tools/devcloud4/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 67a986e994ab..fd813e077fd1 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -19,7 +19,7 @@ FROM ubuntu:22.04 -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.22.1.0-SNAPSHOT" Author="Apache CloudStack " +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.23.0.0-SNAPSHOT" Author="Apache CloudStack " ARG DEBIAN_FRONTEND=noninteractive diff --git a/tools/docker/Dockerfile.marvin b/tools/docker/Dockerfile.marvin index d615a78eb6bb..f0a55109402a 100644 --- a/tools/docker/Dockerfile.marvin +++ b/tools/docker/Dockerfile.marvin @@ -19,11 +19,11 @@ # build for cloudstack_home_dir not this folder FROM python:2 -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.22.1.0-SNAPSHOT" Author="Apache CloudStack " +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.23.0.0-SNAPSHOT" Author="Apache CloudStack " ENV WORK_DIR=/marvin -ENV PKG_URL=https://builds.cloudstack.org/job/build-master-marvin/lastSuccessfulBuild/artifact/tools/marvin/dist/Marvin-4.22.1.0-SNAPSHOT.tar.gz +ENV PKG_URL=https://builds.cloudstack.org/job/build-master-marvin/lastSuccessfulBuild/artifact/tools/marvin/dist/Marvin-4.23.0.0-SNAPSHOT.tar.gz RUN apt-get update && apt-get install -y vim RUN pip install --upgrade paramiko nose requests diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml index 907e9931015d..8e81a394685c 100644 --- a/tools/marvin/pom.xml +++ b/tools/marvin/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py index ad0f245d68f3..05ce9d41023c 100644 --- a/tools/marvin/setup.py +++ b/tools/marvin/setup.py @@ -27,7 +27,7 @@ raise RuntimeError("python setuptools is required to build Marvin") -VERSION = "4.22.1.0-SNAPSHOT" +VERSION = "4.23.0.0-SNAPSHOT" setup(name="Marvin", version=VERSION, diff --git a/tools/pom.xml b/tools/pom.xml index ffa363d4a265..00f055a42d4a 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/usage/pom.xml b/usage/pom.xml index 7f5b0ba527d5..e1e0b0f17c7a 100644 --- a/usage/pom.xml +++ b/usage/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT diff --git a/utils/pom.xml b/utils/pom.xml index 530e1131f78e..fe0f696e52c7 100755 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT ../pom.xml diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml index 9b7b989a8901..7c405176189c 100644 --- a/vmware-base/pom.xml +++ b/vmware-base/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.22.1.0-SNAPSHOT + 4.23.0.0-SNAPSHOT From a50de029bf1d22c2a9ef0de8591f61de0f350f92 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Thu, 6 Nov 2025 05:09:00 -0500 Subject: [PATCH 003/101] Add empty Provider value in Network/VPC Offering form (#11982) --- ui/src/views/offering/AddNetworkOffering.vue | 1 + ui/src/views/offering/AddVpcOffering.vue | 1 + 2 files changed, 2 insertions(+) diff --git a/ui/src/views/offering/AddNetworkOffering.vue b/ui/src/views/offering/AddNetworkOffering.vue index 2b3275a11ed5..abb70abda27a 100644 --- a/ui/src/views/offering/AddNetworkOffering.vue +++ b/ui/src/views/offering/AddNetworkOffering.vue @@ -135,6 +135,7 @@ return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 }" :placeholder="apiParams.provider.description" > + {{ }} {{ $t('label.nsx') }} {{ $t('label.netris') }} diff --git a/ui/src/views/offering/AddVpcOffering.vue b/ui/src/views/offering/AddVpcOffering.vue index d909cbdc3dca..32aa3e8d3583 100644 --- a/ui/src/views/offering/AddVpcOffering.vue +++ b/ui/src/views/offering/AddVpcOffering.vue @@ -83,6 +83,7 @@ return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 }" :placeholder="apiParams.provider.description" > + {{ }} {{ $t('label.nsx') }} {{ $t('label.netris') }} From 8c86f24261c5133831d8412aec6067a794a701dd Mon Sep 17 00:00:00 2001 From: Phsm Qwerty Date: Fri, 7 Nov 2025 14:31:34 +0100 Subject: [PATCH 004/101] enhancement: add instance info as Libvirt metadata (#11061) --- .../api/to/VirtualMachineMetadataTO.java | 182 +++++++++++++++ .../cloud/agent/api/to/VirtualMachineTO.java | 9 + .../resource/LibvirtComputingResource.java | 12 + .../hypervisor/kvm/resource/LibvirtVMDef.java | 209 ++++++++++++++---- .../cloud/hypervisor/HypervisorGuruBase.java | 170 +++++++++++++- .../java/com/cloud/hypervisor/KVMGuru.java | 4 +- 6 files changed, 547 insertions(+), 39 deletions(-) create mode 100644 api/src/main/java/com/cloud/agent/api/to/VirtualMachineMetadataTO.java diff --git a/api/src/main/java/com/cloud/agent/api/to/VirtualMachineMetadataTO.java b/api/src/main/java/com/cloud/agent/api/to/VirtualMachineMetadataTO.java new file mode 100644 index 000000000000..5b22afdedd53 --- /dev/null +++ b/api/src/main/java/com/cloud/agent/api/to/VirtualMachineMetadataTO.java @@ -0,0 +1,182 @@ +// 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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class VirtualMachineMetadataTO { + // VM details + private final String name; + private final String internalName; + private final String displayName; + private final String instanceUuid; + private final Integer cpuCores; + private final Integer memory; + private final Long created; + private final Long started; + + // Owner details + private final String ownerDomainUuid; + private final String ownerDomainName; + private final String ownerAccountUuid; + private final String ownerAccountName; + private final String ownerProjectUuid; + private final String ownerProjectName; + + // Host and service offering + private final String serviceOfferingName; + private final List serviceOfferingHostTags; + + // zone, pod, and cluster details + private final String zoneName; + private final String zoneUuid; + private final String podName; + private final String podUuid; + private final String clusterName; + private final String clusterUuid; + + // resource tags + private final Map resourceTags; + + public VirtualMachineMetadataTO( + String name, String internalName, String displayName, String instanceUuid, Integer cpuCores, Integer memory, Long created, Long started, + String ownerDomainUuid, String ownerDomainName, String ownerAccountUuid, String ownerAccountName, String ownerProjectUuid, String ownerProjectName, + String serviceOfferingName, List serviceOfferingHostTags, + String zoneName, String zoneUuid, String podName, String podUuid, String clusterName, String clusterUuid, Map resourceTags) { + /* + * Something failed in the metadata shall not be a fatal error, the VM can still be started + * Thus, the unknown fields just get an explicit "unknown" value so it can be fixed in case + * there are bugs on some execution paths. + * */ + + this.name = (name != null) ? name : "unknown"; + this.internalName = (internalName != null) ? internalName : "unknown"; + this.displayName = (displayName != null) ? displayName : "unknown"; + this.instanceUuid = (instanceUuid != null) ? instanceUuid : "unknown"; + this.cpuCores = (cpuCores != null) ? cpuCores : -1; + this.memory = (memory != null) ? memory : -1; + this.created = (created != null) ? created : 0; + this.started = (started != null) ? started : 0; + this.ownerDomainUuid = (ownerDomainUuid != null) ? ownerDomainUuid : "unknown"; + this.ownerDomainName = (ownerDomainName != null) ? ownerDomainName : "unknown"; + this.ownerAccountUuid = (ownerAccountUuid != null) ? ownerAccountUuid : "unknown"; + this.ownerAccountName = (ownerAccountName != null) ? ownerAccountName : "unknown"; + this.ownerProjectUuid = (ownerProjectUuid != null) ? ownerProjectUuid : "unknown"; + this.ownerProjectName = (ownerProjectName != null) ? ownerProjectName : "unknown"; + this.serviceOfferingName = (serviceOfferingName != null) ? serviceOfferingName : "unknown"; + this.serviceOfferingHostTags = (serviceOfferingHostTags != null) ? serviceOfferingHostTags : new ArrayList<>(); + this.zoneName = (zoneName != null) ? zoneName : "unknown"; + this.zoneUuid = (zoneUuid != null) ? zoneUuid : "unknown"; + this.podName = (podName != null) ? podName : "unknown"; + this.podUuid = (podUuid != null) ? podUuid : "unknown"; + this.clusterName = (clusterName != null) ? clusterName : "unknown"; + this.clusterUuid = (clusterUuid != null) ? clusterUuid : "unknown"; + + this.resourceTags = (resourceTags != null) ? resourceTags : new HashMap<>(); + } + + public String getName() { + return name; + } + + public String getInternalName() { + return internalName; + } + + public String getDisplayName() { + return displayName; + } + + public String getInstanceUuid() { + return instanceUuid; + } + + public Integer getCpuCores() { + return cpuCores; + } + + public Integer getMemory() { + return memory; + } + + public Long getCreated() { return created; } + + public Long getStarted() { + return started; + } + + public String getOwnerDomainUuid() { + return ownerDomainUuid; + } + + public String getOwnerDomainName() { + return ownerDomainName; + } + + public String getOwnerAccountUuid() { + return ownerAccountUuid; + } + + public String getOwnerAccountName() { + return ownerAccountName; + } + + public String getOwnerProjectUuid() { + return ownerProjectUuid; + } + + public String getOwnerProjectName() { + return ownerProjectName; + } + + public String getserviceOfferingName() { + return serviceOfferingName; + } + + public List getserviceOfferingHostTags() { + return serviceOfferingHostTags; + } + + public String getZoneName() { + return zoneName; + } + + public String getZoneUuid() { + return zoneUuid; + } + + public String getPodName() { + return podName; + } + + public String getPodUuid() { + return podUuid; + } + + public String getClusterName() { + return clusterName; + } + + public String getClusterUuid() { + return clusterUuid; + } + + public Map getResourceTags() { return resourceTags; } +} 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 cffb98740805..e26cc1e9f029 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 @@ -89,6 +89,7 @@ public class VirtualMachineTO { private DeployAsIsInfoTO deployAsIsInfo; private String metadataManufacturer; private String metadataProductName; + private VirtualMachineMetadataTO metadata; 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) { @@ -494,6 +495,14 @@ public void setMetadataProductName(String metadataProductName) { this.metadataProductName = metadataProductName; } + public VirtualMachineMetadataTO getMetadata() { + return metadata; + } + + public void setMetadata(VirtualMachineMetadataTO metadata) { + this.metadata = metadata; + } + @Override public String toString() { return String.format("VM {id: \"%s\", name: \"%s\", uuid: \"%s\", type: \"%s\"}", id, name, uuid, type); diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 0aa094e56d99..fbfe3ef20eb0 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -69,6 +69,7 @@ import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; +import com.cloud.agent.api.to.VirtualMachineMetadataTO; import org.apache.cloudstack.api.ApiConstants.IoDriverPolicy; import org.apache.cloudstack.command.CommandInfo; import org.apache.cloudstack.command.ReconcileCommandService; @@ -199,6 +200,7 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogAction; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogModel; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.MetadataDef; import com.cloud.hypervisor.kvm.resource.rolling.maintenance.RollingMaintenanceAgentExecutor; import com.cloud.hypervisor.kvm.resource.rolling.maintenance.RollingMaintenanceExecutor; import com.cloud.hypervisor.kvm.resource.rolling.maintenance.RollingMaintenanceServiceExecutor; @@ -3011,9 +3013,19 @@ private void configureVM(VirtualMachineTO vmTO, LibvirtVMDef vm, Map components = new HashMap(); private static final int NUMBER_OF_IOTHREADS = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.IOTHREADS); + public static class MetadataDef { + private VirtualMachineMetadataTO metaTO; + + public MetadataDef(VirtualMachineMetadataTO data) { + metaTO = data; + } + + public VirtualMachineMetadataTO getMetadata() { + return metaTO; + } + + @Override + public String toString() { + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + docFactory.setNamespaceAware(true); + Document doc = null; + try { + doc = docFactory.newDocumentBuilder().newDocument(); + } catch (ParserConfigurationException e) { + LOGGER.warn("Could not create a new DOM XML document. The metadata will not be included in the libvirt domain XML: {}", e.getMessage()); + return ""; + } + Element metadata = doc.createElement("metadata"); // + Element instance = doc.createElementNS("http://cloudstack.apache.org/instance", "cloudstack:instance"); // + + Element zone = doc.createElement("cloudstack:zone"); + zone.setAttribute("uuid", metaTO.getZoneUuid()); + zone.setTextContent(metaTO.getZoneName()); + instance.appendChild(zone); + + Element pod = doc.createElement("cloudstack:pod"); + pod.setAttribute("uuid", metaTO.getPodUuid()); + pod.setTextContent(metaTO.getPodName()); + instance.appendChild(pod); + + Element cluster = doc.createElement("cloudstack:cluster"); + cluster.setAttribute("uuid", metaTO.getClusterUuid()); + cluster.setTextContent(metaTO.getClusterName()); + instance.appendChild(cluster); + + Element instanceName = doc.createElement("cloudstack:name"); + instanceName.setTextContent(metaTO.getName()); + instance.appendChild(instanceName); + + Element instanceInternalName = doc.createElement("cloudstack:internal_name"); + instanceInternalName.setTextContent(metaTO.getInternalName()); + instance.appendChild(instanceInternalName); + + Element instanceDisplayName = doc.createElement("cloudstack:display_name"); + instanceDisplayName.setTextContent(metaTO.getDisplayName()); + instance.appendChild(instanceDisplayName); + + Element instanceUuid = doc.createElement("cloudstack:uuid"); + instanceUuid.setTextContent(metaTO.getInstanceUuid()); + instance.appendChild(instanceUuid); + + Element serviceOffering = doc.createElement("cloudstack:service_offering"); // + + Element computeOfferingName = doc.createElement("cloudstack:name"); + computeOfferingName.setTextContent(metaTO.getserviceOfferingName()); + serviceOffering.appendChild(computeOfferingName); + + Element cpu = doc.createElement("cloudstack:cpu"); + cpu.setTextContent(metaTO.getCpuCores().toString()); + serviceOffering.appendChild(cpu); + + Element memory = doc.createElement("cloudstack:memory"); + memory.setTextContent(metaTO.getMemory().toString()); + serviceOffering.appendChild(memory); + + Element hostTags = doc.createElement("cloudstack:host_tags"); + List tags = metaTO.getserviceOfferingHostTags(); + if (tags != null) { + for (String i : metaTO.getserviceOfferingHostTags()) { + Element tag = doc.createElement("cloudstack:tag"); + tag.setTextContent(i); + hostTags.appendChild(tag); + } + } + serviceOffering.appendChild(hostTags); + + instance.appendChild(serviceOffering); // + + Element creationTime = doc.createElement("cloudstack:created_at"); + creationTime.setTextContent( + LocalDateTime.ofInstant(Instant.ofEpochSecond(metaTO.getCreated()), ZoneOffset.UTC).format(ISO_LOCAL_DATE_TIME) + ); + instance.appendChild(creationTime); + + Element startedTime = doc.createElement("cloudstack:started_at"); + startedTime.setTextContent( + LocalDateTime.ofInstant(Instant.ofEpochSecond(metaTO.getStarted()), ZoneOffset.UTC).format(ISO_LOCAL_DATE_TIME) + ); + instance.appendChild(startedTime); + + Element owner = doc.createElement("cloudstack:owner"); // + + Element domain = doc.createElement("cloudstack:domain"); + domain.setAttribute("uuid", metaTO.getOwnerDomainUuid()); + domain.setTextContent(metaTO.getOwnerDomainName()); + owner.appendChild(domain); + + Element account = doc.createElement("cloudstack:account"); + account.setAttribute("uuid", metaTO.getOwnerAccountUuid()); + account.setTextContent(metaTO.getOwnerAccountName()); + owner.appendChild(account); + + Element project = doc.createElement("cloudstack:project"); + project.setAttribute("uuid", metaTO.getOwnerProjectUuid()); + project.setTextContent(metaTO.getOwnerProjectName()); + owner.appendChild(project); + + instance.appendChild(owner); // + + Element resourceTags = doc.createElement("cloudstack:resource_tags"); // + for (Map.Entry entry : metaTO.getResourceTags().entrySet()) { + Element tag = doc.createElement("cloudstack:resource_tag"); // + tag.setAttribute("key", entry.getKey()); + tag.setTextContent(entry.getValue()); + resourceTags.appendChild(tag); // + } + instance.appendChild(resourceTags); // + + metadata.appendChild(instance); // + doc.appendChild(metadata); // + + Transformer transformer = null; + try { + transformer = TransformerFactory.newInstance().newTransformer(); + } catch (TransformerConfigurationException e) { + LOGGER.warn("Could not create an XML transformer. The metadata will not be included in the libvirt domain XML: {}", e.getMessage()); + return ""; + } + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + + DOMSource domSource = new DOMSource(doc); + StringWriter writer = new StringWriter(); + StreamResult result = new StreamResult(writer); + try { + transformer.transform(domSource, result); + } catch (TransformerException e) { + LOGGER.warn("Could not generate metadata XML. The metadata will not be included in the libvirt domain XML: {}", e.getMessage()); + return ""; + } + + return writer.toString(); + } + } + public static class GuestDef { enum GuestType { KVM, XEN, EXE, LXC @@ -2163,34 +2334,6 @@ public String toString() { } } - public class MetadataDef { - Map customNodes = new HashMap<>(); - - public T getMetadataNode(Class fieldClass) { - T field = (T) customNodes.get(fieldClass.getName()); - if (field == null) { - try { - field = fieldClass.newInstance(); - customNodes.put(field.getClass().getName(), field); - } catch (InstantiationException | IllegalAccessException e) { - LOGGER.debug("No default constructor available in class " + fieldClass.getName() + ", ignoring exception", e); - } - } - return field; - } - - @Override - public String toString() { - StringBuilder fsBuilder = new StringBuilder(); - fsBuilder.append("\n"); - for (Object field : customNodes.values()) { - fsBuilder.append(field.toString()); - } - fsBuilder.append("\n"); - return fsBuilder.toString(); - } - } - public static class RngDef { enum RngModel { VIRTIO("virtio"); @@ -2493,15 +2636,6 @@ public DevicesDef getDevices() { return null; } - public MetadataDef getMetaData() { - MetadataDef o = (MetadataDef) components.get(MetadataDef.class.toString()); - if (o == null) { - o = new MetadataDef(); - addComp(o); - } - return o; - } - @Override public String toString() { StringBuilder vmBuilder = new StringBuilder(); @@ -2513,6 +2647,7 @@ public String toString() { if (_desc != null) { vmBuilder.append("" + _desc + "\n"); } + for (Object o : components.values()) { vmBuilder.append(o.toString()); } diff --git a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java index d40b5b226986..928107be9cec 100644 --- a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java @@ -16,6 +16,9 @@ // under the License. package com.cloud.hypervisor; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -24,18 +27,31 @@ import javax.inject.Inject; import com.cloud.agent.api.to.GPUDeviceTO; +import com.cloud.agent.api.to.VirtualMachineMetadataTO; import com.cloud.cpu.CPU; +import com.cloud.dc.ClusterVO; import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; +import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.gpu.VgpuProfileVO; import com.cloud.gpu.dao.VgpuProfileDao; import com.cloud.network.vpc.VpcVO; import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.projects.ProjectVO; +import com.cloud.projects.dao.ProjectDao; +import com.cloud.server.ResourceTag; +import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.dao.UserVmDao; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.backup.Backup; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -97,7 +113,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis @Inject protected AccountManager accountManager; @Inject - private DomainDao domainDao; + protected DomainDao domainDao; @Inject private DataCenterDao dcDao; @Inject @@ -125,7 +141,19 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis @Inject private UserVmManager userVmManager; @Inject + protected UserVmDao userVmDao; + @Inject + protected ProjectDao projectDao; + @Inject + protected ClusterDao clusterDao; + @Inject + protected DataCenterDao dataCenterDao; + @Inject + protected HostPodDao hostPodDao; + @Inject private ConfigurationManager configurationManager; + @Inject + ResourceTagDao tagsDao; public static ConfigKey VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor = new ConfigKey("Advanced", Boolean.class, "vm.min.memory.equals.memory.divided.by.mem.overprovisioning.factor", "true", "If we set this to 'true', a minimum memory (memory/ mem.overprovisioning.factor) will be set to the VM, independent of using a scalable service offering or not.", true, ConfigKey.Scope.Cluster); @@ -470,4 +498,144 @@ public boolean removeVMTemplateOutOfBand(DataStoreTO templateLocation, String te logger.error("Unsupported operation: cannot remove template file"); return false; } + + /** + * Generates VirtualMachineMetadataTO object from VirtualMachineProfile + * It is a helper function to be used in the inherited classes to avoid repetition + * while generating metadata for multiple Guru implementations + * + * @param vmProfile virtual machine profile object + * @return A VirtualMachineMetadataTO ready to be appended to VirtualMachineTO object + * @see KVMGuru + */ + protected VirtualMachineMetadataTO makeVirtualMachineMetadata(VirtualMachineProfile vmProfile) { + String vmName = "unknown", + instanceName = "unknown", + displayName = "unknown", + instanceUuid = "unknown", + clusterName = "unknown", + clusterUuid = "unknown", + zoneUuid = "unknown", + zoneName = "unknown", + podUuid = "unknown", + podName = "unknown", + domainUuid = "unknown", + domainName = "unknown", + accountUuid = "unknown", + accountName = "unknown", + projectName = "", // the project can be empty + projectUuid = "", // the project can be empty + serviceOfferingName = "unknown"; + long created = 0L; + Integer cpuCores = -1, memory = -1; + List serviceOfferingTags = new ArrayList<>(); + HashMap resourceTags = new HashMap<>(); + + UserVmVO vmVO = userVmDao.findById(vmProfile.getVirtualMachine().getId()); + if (vmVO != null) { + instanceUuid = vmVO.getUuid(); + vmName = vmVO.getHostName(); // this returns the VM name field + instanceName = vmVO.getInstanceName(); + displayName = vmVO.getDisplayName(); + created = vmVO.getCreated().getTime() / 1000L; + + HostVO host = hostDao.findById(vmVO.getHostId()); + if (host != null) { + // Find zone and cluster + Long clusterId = host.getClusterId(); + ClusterVO cluster = clusterDao.findById(clusterId); + + if (cluster != null) { + clusterName = cluster.getName(); + clusterUuid = cluster.getUuid(); + + DataCenterVO zone = dataCenterDao.findById(cluster.getDataCenterId()); + if (zone != null) { + zoneUuid = zone.getUuid(); + zoneName = zone.getName(); + } + + HostPodVO pod = hostPodDao.findById(cluster.getPodId()); + if (pod != null) { + podUuid = pod.getUuid(); + podName = pod.getName(); + } + } + } else { + logger.warn("Could not find the Host object for the virtual machine (null value returned). Libvirt metadata for cluster, pod, zone will not be populated."); + } + + DomainVO domain = domainDao.findById(vmVO.getDomainId()); + if (domain != null) { + domainUuid = domain.getUuid(); + domainName = domain.getName(); + } else { + logger.warn("Could not find the Domain object for the virtual machine (null value returned). Libvirt metadata for domain will not be populated."); + } + + Account account = accountManager.getAccount(vmVO.getAccountId()); + if (account != null) { + accountUuid = account.getUuid(); + accountName = account.getName(); + + ProjectVO project = projectDao.findByProjectAccountId(account.getId()); + if (project != null) { + projectName = project.getName(); + projectUuid = project.getUuid(); + } + } else { + logger.warn("Could not find the Account object for the virtual machine (null value returned). Libvirt metadata for account and project will not be populated."); + } + + List resourceTagsList = tagsDao.listBy(vmVO.getId(), ResourceTag.ResourceObjectType.UserVm); + if (resourceTagsList != null) { + for (ResourceTag tag : resourceTagsList) { + resourceTags.put(tag.getKey(), tag.getValue()); + } + } + } else { + logger.warn("Could not find the VirtualMachine object by its profile (null value returned). Libvirt metadata will not be populated."); + } + + ServiceOffering serviceOffering = vmProfile.getServiceOffering(); + if (serviceOffering != null) { + serviceOfferingName = serviceOffering.getName(); + cpuCores = serviceOffering.getCpu(); + memory = serviceOffering.getRamSize(); + + String hostTagsCommaSeparated = serviceOffering.getHostTag(); + if (hostTagsCommaSeparated != null) { // when service offering has no host tags, this value is null + serviceOfferingTags = Arrays.asList(hostTagsCommaSeparated.split(",")); + } + } else { + logger.warn("Could not find the ServiceOffering object by its profile (null value returned). Libvirt metadata for service offering will not be populated."); + } + + + return new VirtualMachineMetadataTO( + vmName, // name + instanceName, // internalName + displayName, // displayName + instanceUuid , // instanceUUID + cpuCores, // cpuCores + memory, // memory + created, // created, unix epoch in seconds + System.currentTimeMillis() / 1000L, // started, unix epoch in seconds + domainUuid, // ownerDomainUUID + domainName, // ownerDomainName + accountUuid, // ownerAccountUUID + accountName, // ownerAccountName + projectUuid, + projectName, + serviceOfferingName, + serviceOfferingTags, // serviceOfferingTags + zoneName, + zoneUuid, + podName, + podUuid, + clusterName, + clusterUuid, + resourceTags + ); + } } diff --git a/server/src/main/java/com/cloud/hypervisor/KVMGuru.java b/server/src/main/java/com/cloud/hypervisor/KVMGuru.java index 64881df4c826..d907e726b202 100644 --- a/server/src/main/java/com/cloud/hypervisor/KVMGuru.java +++ b/server/src/main/java/com/cloud/hypervisor/KVMGuru.java @@ -155,7 +155,6 @@ protected void setVmQuotaPercentage(VirtualMachineTO to, VirtualMachineProfile v } @Override - public VirtualMachineTO implement(VirtualMachineProfile vm) { VirtualMachineTO to = toVirtualMachineTO(vm); setVmQuotaPercentage(to, vm); @@ -170,6 +169,9 @@ public VirtualMachineTO implement(VirtualMachineProfile vm) { configureVmOsDescription(virtualMachine, to, host); configureVmMemoryAndCpuCores(to, host, virtualMachine, vm); + + to.setMetadata(makeVirtualMachineMetadata(vm)); + return to; } From 40c8bc528d3201d88ead398a4c82ed1f50fffde7 Mon Sep 17 00:00:00 2001 From: Davi Torres <90287660+daviftorres@users.noreply.github.com> Date: Tue, 11 Nov 2025 09:33:07 -0500 Subject: [PATCH 005/101] Keeping consistency with other error messages. (#11649) Co-authored-by: Davi Torres Co-authored-by: dahn --- .../command/user/loadbalancer/UpdateLBHealthCheckPolicyCmd.java | 2 +- .../command/user/loadbalancer/UpdateLBStickinessPolicyCmd.java | 2 +- .../cloudstack/api/command/user/vpn/UpdateVpnConnectionCmd.java | 2 +- .../cloudstack/api/command/user/vpn/UpdateVpnGatewayCmd.java | 2 +- engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java | 2 +- .../src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java | 2 +- server/src/main/java/com/cloud/api/query/QueryManagerImpl.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBHealthCheckPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBHealthCheckPolicyCmd.java index fdd98fc3a0a4..8609c87d8f1d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBHealthCheckPolicyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBHealthCheckPolicyCmd.java @@ -63,7 +63,7 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - return "Update load balancer health check policy ID= " + id; + return "Update load balancer health check policy ID = " + id; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBStickinessPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBStickinessPolicyCmd.java index b2137cf262d8..21c18d584ab0 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBStickinessPolicyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBStickinessPolicyCmd.java @@ -62,7 +62,7 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - return "Update load balancer stickiness policy ID= " + id; + return "Update load balancer stickiness policy ID = " + id; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnConnectionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnConnectionCmd.java index 62dd6167b753..efa809a2d782 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnConnectionCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnConnectionCmd.java @@ -66,7 +66,7 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - return "Updating site-to-site VPN connection id= " + id; + return "Updating site-to-site VPN connection ID = " + id; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnGatewayCmd.java index 9fe5ae0480f7..e614920d8de3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnGatewayCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnGatewayCmd.java @@ -63,7 +63,7 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - return "Update site-to-site VPN gateway id= " + id; + return "Update site-to-site VPN gateway ID = " + id; } @Override diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java index 41bcb3155e54..d3775fe35409 100644 --- a/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java @@ -782,7 +782,7 @@ public List> countVmsBySize(long dcId, int li result.add(new Ternary(rs.getInt(1), rs.getInt(2), rs.getInt(3))); } } catch (Exception e) { - logger.warn("Error counting vms by size for dcId= " + dcId, e); + logger.warn("Error counting vms by size for Data Center ID = " + dcId, e); } return result; } diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java index 6ac49967540a..339573c10fa3 100755 --- a/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -886,7 +886,7 @@ public Long countByZoneAndStateAndHostTag(long dcId, State state, String hostTag return rs.getLong(1); } } catch (Exception e) { - logger.warn(String.format("Error counting vms by host tag for dcId= %s, hostTag= %s", dcId, hostTag), e); + logger.warn(String.format("Error counting vms by host tag for dcId = %s, hostTag = %s", dcId, hostTag), e); } return 0L; } diff --git a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java index e1dc73a3225d..4b469abe1fc2 100644 --- a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java @@ -2106,7 +2106,7 @@ private Pair, Integer> listProjectsInternal(ListProjectsCmd } if (domainId != null && !domainId.equals(caller.getDomainId())) { - throw new PermissionDeniedException("Can't list domain id= " + domainId + " projects; unauthorized"); + throw new PermissionDeniedException("Can't list domain ID = " + domainId + " projects; unauthorized"); } if (StringUtils.isNotEmpty(username) && !username.equals(user.getUsername())) { From 23fb0e2ccb44ba42dae530b81729d2441fd8b039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20B=C3=B6ck?= <89930804+erikbocks@users.noreply.github.com> Date: Tue, 11 Nov 2025 14:13:00 -0300 Subject: [PATCH 006/101] Update GUI Kubernetes logo (#11895) --- ui/src/assets/icons/kubernetes.svg | 5 +++++ ui/src/components/header/CreateMenu.vue | 6 ++++-- ui/src/config/section/compute.js | 3 ++- ui/src/config/section/image.js | 3 ++- ui/src/utils/renderIcon.js | 5 +++-- 5 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 ui/src/assets/icons/kubernetes.svg diff --git a/ui/src/assets/icons/kubernetes.svg b/ui/src/assets/icons/kubernetes.svg new file mode 100644 index 000000000000..db1f37bdfee1 --- /dev/null +++ b/ui/src/assets/icons/kubernetes.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ui/src/components/header/CreateMenu.vue b/ui/src/components/header/CreateMenu.vue index 8c39ec5b8a07..aa1d020bdb60 100644 --- a/ui/src/components/header/CreateMenu.vue +++ b/ui/src/components/header/CreateMenu.vue @@ -26,7 +26,7 @@ @@ -50,6 +50,8 @@ + + diff --git a/ui/src/config/section/tools.js b/ui/src/config/section/tools.js index a07228ca87b4..5b7f4b9af325 100644 --- a/ui/src/config/section/tools.js +++ b/ui/src/config/section/tools.js @@ -116,6 +116,10 @@ export default { name: 'details', component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue'))) }, + { + name: 'filters', + component: shallowRef(defineAsyncComponent(() => import('@/components/view/WebhookFiltersTab.vue'))) + }, { name: 'recent.deliveries', component: shallowRef(defineAsyncComponent(() => import('@/components/view/WebhookDeliveriesTab.vue'))) From c465caf81e743b1a0d6f919e472e2d82d1c71a66 Mon Sep 17 00:00:00 2001 From: dahn Date: Tue, 6 Jan 2026 08:17:37 +0100 Subject: [PATCH 052/101] Adjust close periods (#12376) --- .github/workflows/stale.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index f12fbe93de66..e90c75979b6d 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -33,9 +33,11 @@ jobs: stale-issue-message: 'This issue is stale because it has been open for 120 days with no activity. It may be removed by administrators of this project at any time. Remove the stale label or comment to request for removal of it to prevent this.' stale-pr-message: 'This PR is stale because it has been open for 120 days with no activity. It may be removed by administrators of this project at any time. Remove the stale label or comment to request for removal of it to prevent this.' close-issue-message: 'This issue was closed because it has been stale for 120 days with no activity.' - close-pr-message: 'This PR was closed because it has been stale for 120 days with no activity.' + close-pr-message: 'This PR was closed because it has been stale for 240 days with no activity.' stale-issue-label: 'no-issue-activity' stale-pr-label: 'no-pr-activity' days-before-stale: 120 + days-before-close: -1 + days-before-pr-close: 240 exempt-issue-labels: 'gsoc,good-first-issue,long-term-plan' exempt-pr-labels: 'status:ready-for-merge,status:needs-testing,status:on-hold' From e47d7bc6ff12167f97932c922475ce8cb6593abe Mon Sep 17 00:00:00 2001 From: John Bampton Date: Thu, 8 Jan 2026 02:22:52 +1000 Subject: [PATCH 053/101] [CI] Dependabot: add a cooldown period for new releases (#12384) --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 88985cbdef1e..41b307863fc3 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -26,3 +26,5 @@ updates: directory: "/" # Location of package manifests schedule: interval: "daily" + cooldown: + default-days: 7 From fd1c67f47390d2d4ff8e121d83de7284e0211c1b Mon Sep 17 00:00:00 2001 From: John Bampton Date: Thu, 8 Jan 2026 20:26:40 +1000 Subject: [PATCH 054/101] Standardize and auto add license headers to properties files (#12231) --- .pre-commit-config.yaml | 10 +++++++ .../hypervisors/ovm3/sonar-project.properties | 28 +++++++++---------- .../ovm3/src/test/resources/log4j.properties | 28 +++++++++---------- .../src/test/resources/log4j.properties | 26 +++++++++-------- systemvm/agent/conf/environment.properties | 17 +++++++++++ 5 files changed, 69 insertions(+), 40 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ef0b0c204ebd..26adafcbf268 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -62,6 +62,16 @@ repos: - .github/workflows/license-templates/LICENSE.txt - --fuzzy-match-generates-todo exclude: ^(CHANGES|ISSUE_TEMPLATE|PULL_REQUEST_TEMPLATE)\.md$|^ui/docs/(full|smoke)-test-plan\.template\.md$ + - id: insert-license + name: add license for all properties files + description: automatically adds a licence header to all properties files that don't have a license header + files: \.properties$ + args: + - --comment-style + - '|#|' + - --license-filepath + - .github/workflows/license-templates/LICENSE.txt + - --fuzzy-match-generates-todo - id: insert-license name: add license for all Shell files description: automatically adds a licence header to all Shell files that don't have a license header diff --git a/plugins/hypervisors/ovm3/sonar-project.properties b/plugins/hypervisors/ovm3/sonar-project.properties index d632dfb9f916..7355f1df4f78 100644 --- a/plugins/hypervisors/ovm3/sonar-project.properties +++ b/plugins/hypervisors/ovm3/sonar-project.properties @@ -1,19 +1,19 @@ -#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 +# 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 +# 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. +# 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. # Required metadata sonar.projectKey=cloud-plugin-hypervisor-ovm3 diff --git a/plugins/hypervisors/ovm3/src/test/resources/log4j.properties b/plugins/hypervisors/ovm3/src/test/resources/log4j.properties index 82ee5c55c4c0..0f72e39d8554 100644 --- a/plugins/hypervisors/ovm3/src/test/resources/log4j.properties +++ b/plugins/hypervisors/ovm3/src/test/resources/log4j.properties @@ -1,19 +1,19 @@ -#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 +# 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 +# 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. +# 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. # Root logger option log4j.rootLogger=DEBUG, stdout diff --git a/plugins/network-elements/globodns/src/test/resources/log4j.properties b/plugins/network-elements/globodns/src/test/resources/log4j.properties index 1bac606ff63d..8b1d961f7b63 100644 --- a/plugins/network-elements/globodns/src/test/resources/log4j.properties +++ b/plugins/network-elements/globodns/src/test/resources/log4j.properties @@ -1,17 +1,19 @@ -# 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 +# 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 +# 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. +# 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. # Define the root logger with appender file #log = /var/log/log4j diff --git a/systemvm/agent/conf/environment.properties b/systemvm/agent/conf/environment.properties index 269acad91525..20ca1a2b4322 100644 --- a/systemvm/agent/conf/environment.properties +++ b/systemvm/agent/conf/environment.properties @@ -1,2 +1,19 @@ +# 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. + paths.script=../../scripts/storage/secondary/ paths.pid=. From bc76f2042d74ecee12a4cbea95e70b4bd75aae85 Mon Sep 17 00:00:00 2001 From: Tonitzpp <134986282+Tonitzpp@users.noreply.github.com> Date: Thu, 8 Jan 2026 09:55:34 -0300 Subject: [PATCH 055/101] Change migration volume exception messages (#12367) Co-authored-by: toni.zamparetti Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../main/java/com/cloud/storage/VolumeApiServiceImpl.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index 4f03e7881737..bdf9bc1bc1d2 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -2179,14 +2179,16 @@ public Volume changeDiskOfferingForVolumeInternal(Long volumeId, Long newDiskOff } Collections.shuffle(suitableStoragePoolsWithEnoughSpace); MigrateVolumeCmd migrateVolumeCmd = new MigrateVolumeCmd(volume.getId(), suitableStoragePoolsWithEnoughSpace.get(0).getId(), newDiskOffering.getId(), true); + String volumeUuid = volume.getUuid(); try { Volume result = migrateVolume(migrateVolumeCmd); volume = (result != null) ? _volsDao.findById(result.getId()) : null; if (volume == null) { - throw new CloudRuntimeException(String.format("Volume change offering operation failed for volume: %s migration failed to storage pool %s", volume, suitableStoragePools.get(0))); + throw new CloudRuntimeException("Change offering for the volume failed."); } } catch (Exception e) { - throw new CloudRuntimeException(String.format("Volume change offering operation failed for volume: %s migration failed to storage pool %s due to %s", volume, suitableStoragePools.get(0), e.getMessage())); + logger.error("Volume change offering operation failed for volume ID: {} migration failed to storage pool {} due to {}", volumeUuid, suitableStoragePoolsWithEnoughSpace.get(0).getId(), e.getMessage()); + throw new CloudRuntimeException("Change offering for the volume failed.", e); } } @@ -2199,7 +2201,7 @@ public Volume changeDiskOfferingForVolumeInternal(Long volumeId, Long newDiskOff if (volumeMigrateRequired) { logger.warn(String.format("Volume change offering operation succeeded for volume ID: %s but volume resize operation failed, so please try resize volume operation separately", volume.getUuid())); } else { - throw new CloudRuntimeException(String.format("Volume change offering operation failed for volume ID: %s due to resize volume operation failed", volume.getUuid())); + throw new CloudRuntimeException(String.format("Volume disk offering change operation failed for volume ID [%s] because the volume resize operation failed.", volume.getUuid())); } } } From 1ef636577167cc7cc7a6ce63c54b54c1ab32aabf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20B=C3=B6ck?= <89930804+erikbocks@users.noreply.github.com> Date: Fri, 9 Jan 2026 05:23:46 -0300 Subject: [PATCH 056/101] Change internal ID to UUID in user disable event (#11824) --- .../cloudstack/api/command/admin/user/DisableUserCmd.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java index 974c1c7bebed..6ce669d8523d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java @@ -78,12 +78,12 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - return "disabling user: " + getId(); + return "disabling user: " + this._uuidMgr.getUuid(User.class, getId()); } @Override public void execute() { - CallContext.current().setEventDetails("UserId: " + getId()); + CallContext.current().setEventDetails("User ID: " + this._uuidMgr.getUuid(User.class, getId())); UserAccount user = _regionService.disableUser(this); if (user != null) { From 1b861dad48fe4987b691eab7ed102638d5c1f550 Mon Sep 17 00:00:00 2001 From: "Suyang(Dawson) Chen" Date: Fri, 9 Jan 2026 03:30:17 -0500 Subject: [PATCH 057/101] Cleanup: Standardize logger message formatting in ApiServer.java (#11188) --- .../src/main/java/com/cloud/api/ApiServer.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/server/src/main/java/com/cloud/api/ApiServer.java b/server/src/main/java/com/cloud/api/ApiServer.java index 5a3c8c2c7179..95aca28b53f2 100644 --- a/server/src/main/java/com/cloud/api/ApiServer.java +++ b/server/src/main/java/com/cloud/api/ApiServer.java @@ -461,14 +461,14 @@ public boolean start() { final Long snapshotLimit = ConcurrentSnapshotsThresholdPerHost.value(); if (snapshotLimit == null || snapshotLimit <= 0) { - logger.debug("Global concurrent snapshot config parameter " + ConcurrentSnapshotsThresholdPerHost.value() + " is less or equal 0; defaulting to unlimited"); + logger.debug("Global concurrent snapshot config parameter {} is less or equal 0; defaulting to unlimited", ConcurrentSnapshotsThresholdPerHost.value()); } else { dispatcher.setCreateSnapshotQueueSizeLimit(snapshotLimit); } final Long migrationLimit = VolumeApiService.ConcurrentMigrationsThresholdPerDatastore.value(); if (migrationLimit == null || migrationLimit <= 0) { - logger.debug("Global concurrent migration config parameter " + VolumeApiService.ConcurrentMigrationsThresholdPerDatastore.value() + " is less or equal 0; defaulting to unlimited"); + logger.debug("Global concurrent migration config parameter {} is less or equal 0; defaulting to unlimited", VolumeApiService.ConcurrentMigrationsThresholdPerDatastore.value()); } else { dispatcher.setMigrateQueueSizeLimit(migrationLimit); } @@ -647,7 +647,7 @@ public String handleRequest(final Map params, final String responseType, final S logValue = (value == null) ? "'null'" : value[0]; } - logger.trace(" key: " + keyStr + ", value: " + logValue); + logger.trace(" key: {}, value: {}", keyStr, logValue); } } throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "Invalid request, no command sent"); @@ -707,7 +707,7 @@ public String handleRequest(final Map params, final String responseType, final S buf.append(obj.getUuid()); buf.append(" "); } - logger.info("PermissionDenied: " + ex.getMessage() + " on objs: [" + buf + "]"); + logger.info("PermissionDenied: {} on objs: [{}]", ex.getMessage(), buf); } else { logger.info("PermissionDenied: {}", ex.getMessage()); } @@ -1035,7 +1035,7 @@ public boolean verifyRequest(final Map requestParameters, fina // if api/secret key are passed to the parameters if ((signature == null) || (apiKey == null)) { - logger.debug("Expired session, missing signature, or missing apiKey -- ignoring request. Signature: " + signature + ", apiKey: " + apiKey); + logger.warn("Expired session, missing signature, or missing apiKey -- ignoring request. Signature: {}, apiKey: {}", signature, apiKey); return false; // no signature, bad request } @@ -1258,7 +1258,7 @@ public ResponseObject loginUser(final HttpSession session, final String username float offsetInHrs = 0f; if (timezone != null) { final TimeZone t = TimeZone.getTimeZone(timezone); - logger.info("Current user logged in under " + timezone + " timezone"); + logger.info("Current user logged in under {} timezone", timezone); final java.util.Date date = new java.util.Date(); final long longDate = date.getTime(); @@ -1410,9 +1410,9 @@ private void checkCommandAvailable(final User user, final String commandName, fi final Boolean apiSourceCidrChecksEnabled = ApiServiceConfiguration.ApiSourceCidrChecksEnabled.value(); if (apiSourceCidrChecksEnabled) { - logger.debug("CIDRs from which account '" + account.toString() + "' is allowed to perform API calls: " + accessAllowedCidrs); + logger.debug("CIDRs from which account '{}' is allowed to perform API calls: {}", account.toString(), accessAllowedCidrs); if (!NetUtils.isIpInCidrList(remoteAddress, accessAllowedCidrs.split(","))) { - logger.warn("Request by account '" + account.toString() + "' was denied since " + remoteAddress + " does not match " + accessAllowedCidrs); + logger.warn("Request by account '{}' was denied since {} does not match {}", account.toString(), remoteAddress, accessAllowedCidrs); throw new OriginDeniedException("Calls from disallowed origin", account, remoteAddress); } } From 2358632253a0a0da74b81028e6c63aeb49df7e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20B=C3=B6ck?= <89930804+erikbocks@users.noreply.github.com> Date: Mon, 12 Jan 2026 04:20:31 -0300 Subject: [PATCH 058/101] Fixed User type accounts being able to change resource limits of their own domain and account (#12046) Co-authored-by: Lucas Martins <56271185+lucas-a-martins@users.noreply.github.com> --- .../com/cloud/resourcelimit/ResourceLimitManagerImpl.java | 5 +++++ .../cloud/resourcelimit/ResourceLimitManagerImplTest.java | 1 + 2 files changed, 6 insertions(+) diff --git a/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 9a6c8a85f18e..648abf0d9384 100644 --- a/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -903,6 +903,11 @@ protected void addTaggedResourceLimits(List limits, ResourceTyp public ResourceLimitVO updateResourceLimit(Long accountId, Long domainId, Integer typeId, Long max, String tag) { Account caller = CallContext.current().getCallingAccount(); + if (caller.getType().equals(Account.Type.NORMAL)) { + logger.info("Throwing exception because only root admins and domain admins are allowed to update resource limits."); + throw new PermissionDeniedException("Your account does not have the permission to update resource limits."); + } + if (max == null) { max = (long)Resource.RESOURCE_UNLIMITED; } else if (max < Resource.RESOURCE_UNLIMITED) { diff --git a/server/src/test/java/com/cloud/resourcelimit/ResourceLimitManagerImplTest.java b/server/src/test/java/com/cloud/resourcelimit/ResourceLimitManagerImplTest.java index a968a2da0b7d..0b0b8c5e43fe 100644 --- a/server/src/test/java/com/cloud/resourcelimit/ResourceLimitManagerImplTest.java +++ b/server/src/test/java/com/cloud/resourcelimit/ResourceLimitManagerImplTest.java @@ -147,6 +147,7 @@ public void setUp() throws Exception { overrideDefaultConfigValue(ResourceLimitService.ResourceLimitStorageTags, "_defaultValue", StringUtils.join(storageTags, ",")); Account account = mock(Account.class); + when(account.getType()).thenReturn(Account.Type.ADMIN); User user = mock(User.class); CallContext.register(user, account); } From b8813c7b243787b8b33080d7fea3327d709bcccf Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Mon, 12 Jan 2026 16:50:15 +0530 Subject: [PATCH 059/101] UI: Add info for 'Use primary storage replication' in snapshot view(s) (#11943) --- .../api/command/user/snapshot/CopySnapshotCmd.java | 6 +++++- .../api/command/user/snapshot/CreateSnapshotCmd.java | 5 ++++- .../command/user/snapshot/CreateSnapshotPolicyCmd.java | 6 +++++- .../com/cloud/storage/snapshot/SnapshotManager.java | 4 +++- ui/src/views/storage/FormSchedule.vue | 8 +++++++- ui/src/views/storage/SnapshotZones.vue | 7 ++++++- ui/src/views/storage/TakeSnapshot.vue | 10 ++++++++-- 7 files changed, 38 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CopySnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CopySnapshotCmd.java index ac54ebbd8f8c..519f9876b960 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CopySnapshotCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CopySnapshotCmd.java @@ -97,7 +97,11 @@ public class CopySnapshotCmd extends BaseAsyncCmd implements UserCmd { "The snapshot will always be made available in the zone in which the volume is present. Currently supported for StorPool only") protected List storagePoolIds; - @Parameter (name = ApiConstants.USE_STORAGE_REPLICATION, type=CommandType.BOOLEAN, required = false, since = "4.21.0", description = "This parameter enables the option the snapshot to be copied to supported primary storage") + @Parameter (name = ApiConstants.USE_STORAGE_REPLICATION, + type=CommandType.BOOLEAN, + since = "4.21.0", + description = "Enables the snapshot to be copied to the supported primary storages when the config 'use.storage.replication' is set to true for the storage or globally. " + + "This is supported only for StorPool storage for now.") protected Boolean useStorageReplication; ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java index 3a49bad8fcb9..f78112d679fe 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java @@ -112,7 +112,10 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd { since = "4.21.0") protected List storagePoolIds; - @Parameter (name = ApiConstants.USE_STORAGE_REPLICATION, type=CommandType.BOOLEAN, required = false, description = "This parameter enables the option the snapshot to be copied to supported primary storage") + @Parameter (name = ApiConstants.USE_STORAGE_REPLICATION, + type=CommandType.BOOLEAN, + description = "Enables the snapshot to be copied to the supported primary storages when the config 'use.storage.replication' is set to true for the storage or globally. " + + "This is supported only for StorPool storage for now.") protected Boolean useStorageReplication; private String syncObjectType = BaseAsyncCmd.snapshotHostSyncObject; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotPolicyCmd.java index 24d756befaba..b1e7b2a00040 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotPolicyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotPolicyCmd.java @@ -94,7 +94,11 @@ public class CreateSnapshotPolicyCmd extends BaseCmd { since = "4.21.0") protected List storagePoolIds; - @Parameter (name = ApiConstants.USE_STORAGE_REPLICATION, type=CommandType.BOOLEAN, required = false, since = "4.21.0", description = "This parameter enables the option the snapshot to be copied to supported primary storage") + @Parameter (name = ApiConstants.USE_STORAGE_REPLICATION, + type=CommandType.BOOLEAN, + since = "4.21.0", + description = "Enables the snapshot to be copied to the supported primary storages when the config 'use.storage.replication' is set to true for the storage or globally. " + + "This is supported only for StorPool storage for now.") protected Boolean useStorageReplication; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// diff --git a/server/src/main/java/com/cloud/storage/snapshot/SnapshotManager.java b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManager.java index b245a3719694..10dcc2683de8 100644 --- a/server/src/main/java/com/cloud/storage/snapshot/SnapshotManager.java +++ b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManager.java @@ -68,7 +68,9 @@ public interface SnapshotManager extends Configurable { "Whether to show chain size (sum of physical size of snapshot and all its parents) for incremental snapshots in the snapshot response", true, ConfigKey.Scope.Global, null); - public static final ConfigKey UseStorageReplication = new ConfigKey(Boolean.class, "use.storage.replication", "Snapshots", "false", "For snapshot copy to another primary storage in a different zone. Supports only StorPool storage for now", true, ConfigKey.Scope.StoragePool, null); + ConfigKey UseStorageReplication = new ConfigKey<>(Boolean.class, "use.storage.replication", "Snapshots", "false", + "For snapshot copy to another primary storage in a different zone. This is supported only for StorPool storage for now.", + true, ConfigKey.Scope.StoragePool, null); void deletePoliciesForVolume(Long volumeId); diff --git a/ui/src/views/storage/FormSchedule.vue b/ui/src/views/storage/FormSchedule.vue index 433e399d2a8c..baecd3bb5be8 100644 --- a/ui/src/views/storage/FormSchedule.vue +++ b/ui/src/views/storage/FormSchedule.vue @@ -174,7 +174,10 @@ - + + @@ -310,6 +313,9 @@ export default { storagePools: [] } }, + beforeCreate () { + this.apiParams = this.$getApiParams('createSnapshotPolicy') + }, created () { this.initForm() this.volumeId = this.resource.id diff --git a/ui/src/views/storage/SnapshotZones.vue b/ui/src/views/storage/SnapshotZones.vue index ed46ce4172ad..f37996a3f293 100644 --- a/ui/src/views/storage/SnapshotZones.vue +++ b/ui/src/views/storage/SnapshotZones.vue @@ -137,7 +137,10 @@ - + + @@ -236,6 +239,7 @@ import { isAdmin } from '@/role' import OsLogo from '@/components/widgets/OsLogo' import ResourceIcon from '@/components/view/ResourceIcon' import TooltipButton from '@/components/widgets/TooltipButton' +import TooltipLabel from '@/components/widgets/TooltipLabel' import BulkActionProgress from '@/components/view/BulkActionProgress' import Status from '@/components/widgets/Status' import eventBus from '@/config/eventBus' @@ -244,6 +248,7 @@ export default { name: 'SnapshotZones', components: { TooltipButton, + TooltipLabel, OsLogo, ResourceIcon, BulkActionProgress, diff --git a/ui/src/views/storage/TakeSnapshot.vue b/ui/src/views/storage/TakeSnapshot.vue index fc80e6d775f9..9e17e0683b83 100644 --- a/ui/src/views/storage/TakeSnapshot.vue +++ b/ui/src/views/storage/TakeSnapshot.vue @@ -66,7 +66,10 @@ - + + @@ -93,7 +96,10 @@ - + + From a566af35f5c8c34f6694a60dcd76f195d7caa6d4 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Thu, 15 Jan 2026 19:14:51 +0100 Subject: [PATCH 060/101] Review comment on pull request #12436 --- pull/12436 | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 pull/12436 diff --git a/pull/12436 b/pull/12436 new file mode 100644 index 000000000000..ca31e875a3e2 --- /dev/null +++ b/pull/12436 @@ -0,0 +1,35 @@ +Thanks for the changes — overall these look reasonable, but I have a few comments and suggestions: + +1) Bug in DeployVnfAppliance.vue +- The new check uses .filter(...) in a boolean context: + (this.vnfNicNetworks[deviceId].service.filter(svc => svc.name === 'SecurityGroupProvider')) +- In JavaScript, an array (including an empty array) is truthy, so this condition will always evaluate to true even when there are no matching services. This is likely a functional bug. +- Suggested fix: use .some or check length: + this.vnfNicNetworks[deviceId].service && this.vnfNicNetworks[deviceId].service.some(svc => svc.name === 'SecurityGroupProvider') + or + Array.isArray(this.vnfNicNetworks[deviceId].service) && this.vnfNicNetworks[deviceId].service.filter(...).length > 0 + +2) Expanded details in network.js and VnfAppliancesTab.vue — performance and consistency +- You expanded the API "details" from 'servoff,tmpl,nics' to 'group,nics,secgrp,tmpl,servoff,diskoff,iso,volume,affgrp,backoff'. That will return many more fields and could affect performance (more data transferred / processed). Please confirm all newly requested details are required for the UI use-cases in these views. +- Also note an inconsistency in parameter casing: + - ui/src/config/section/network.js uses isvnf: true (lowercase 'v') + - ui/src/views/network/VnfAppliancesTab.vue uses isVnf: true (camelCase) + Verify which exact param the backend expects (case-sensitive). Recommend standardizing to the correct form across files. + +3) Logic change in DeployVnfAppliance.vue — intent clarification +- Previously the code checked zone.securitygroupsenabled for Shared networks. The new code checks whether the network has the SecurityGroupProvider service. Please confirm this is the intended semantic change (i.e., switching from a zone-level setting to checking per-network provider capability). If both checks are relevant, combine them appropriately. + +4) Localization text change +- The new label "Configure network rules for VNF's management interfaces" is fine and shorter. Minor nit: consider removing the possessive and using "Configure network rules for VNF management interfaces" to match other labels' style, but this is optional. + +5) Safety / defensive coding +- In places where you access this.vnfNicNetworks[deviceId].service, add defensive checks (Array.isArray(...)) before calling array methods to avoid runtime errors if service is undefined. + +6) Testing suggestions +- Please test deploy flows in zones/networks: + - Shared network with SecurityGroupProvider present + - Shared network without SecurityGroupProvider + - Isolated networks and VPC cases + - Confirm that expanding "details" doesn't degrade list performance in views that call the API frequently. + +If you'd like, I can re-run these checks or suggest a patch for the .some change. Thanks! \ No newline at end of file From b31c2f4cae1a9c4d29e9e5a745b1c77df7d93c81 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Thu, 15 Jan 2026 19:17:12 +0100 Subject: [PATCH 061/101] Revert "Review comment on pull request #12436" This reverts commit a566af35f5c8c34f6694a60dcd76f195d7caa6d4. --- pull/12436 | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 pull/12436 diff --git a/pull/12436 b/pull/12436 deleted file mode 100644 index ca31e875a3e2..000000000000 --- a/pull/12436 +++ /dev/null @@ -1,35 +0,0 @@ -Thanks for the changes — overall these look reasonable, but I have a few comments and suggestions: - -1) Bug in DeployVnfAppliance.vue -- The new check uses .filter(...) in a boolean context: - (this.vnfNicNetworks[deviceId].service.filter(svc => svc.name === 'SecurityGroupProvider')) -- In JavaScript, an array (including an empty array) is truthy, so this condition will always evaluate to true even when there are no matching services. This is likely a functional bug. -- Suggested fix: use .some or check length: - this.vnfNicNetworks[deviceId].service && this.vnfNicNetworks[deviceId].service.some(svc => svc.name === 'SecurityGroupProvider') - or - Array.isArray(this.vnfNicNetworks[deviceId].service) && this.vnfNicNetworks[deviceId].service.filter(...).length > 0 - -2) Expanded details in network.js and VnfAppliancesTab.vue — performance and consistency -- You expanded the API "details" from 'servoff,tmpl,nics' to 'group,nics,secgrp,tmpl,servoff,diskoff,iso,volume,affgrp,backoff'. That will return many more fields and could affect performance (more data transferred / processed). Please confirm all newly requested details are required for the UI use-cases in these views. -- Also note an inconsistency in parameter casing: - - ui/src/config/section/network.js uses isvnf: true (lowercase 'v') - - ui/src/views/network/VnfAppliancesTab.vue uses isVnf: true (camelCase) - Verify which exact param the backend expects (case-sensitive). Recommend standardizing to the correct form across files. - -3) Logic change in DeployVnfAppliance.vue — intent clarification -- Previously the code checked zone.securitygroupsenabled for Shared networks. The new code checks whether the network has the SecurityGroupProvider service. Please confirm this is the intended semantic change (i.e., switching from a zone-level setting to checking per-network provider capability). If both checks are relevant, combine them appropriately. - -4) Localization text change -- The new label "Configure network rules for VNF's management interfaces" is fine and shorter. Minor nit: consider removing the possessive and using "Configure network rules for VNF management interfaces" to match other labels' style, but this is optional. - -5) Safety / defensive coding -- In places where you access this.vnfNicNetworks[deviceId].service, add defensive checks (Array.isArray(...)) before calling array methods to avoid runtime errors if service is undefined. - -6) Testing suggestions -- Please test deploy flows in zones/networks: - - Shared network with SecurityGroupProvider present - - Shared network without SecurityGroupProvider - - Isolated networks and VPC cases - - Confirm that expanding "details" doesn't degrade list performance in views that call the API frequently. - -If you'd like, I can re-run these checks or suggest a patch for the .some change. Thanks! \ No newline at end of file From 002d9768b2886f34ab2a572bfa462583e5dd5680 Mon Sep 17 00:00:00 2001 From: Abhisar Sinha <63767682+abh1sar@users.noreply.github.com> Date: Mon, 19 Jan 2026 13:18:37 +0530 Subject: [PATCH 062/101] Add settings to mark cryptographic algorithms in vpn customer gateways as excluded or obsolete (#12193) This PR introduces several configuration settings using which an operator can mark certain cryptographic algorithms and parameters as excluded or obsolete for VPN Customer Gateway creation for Site-to-Site VPN. Cloud providers following modern security frameworks (e.g., ISO 27001/27017) are required to enforce and communicate approved cryptographic standards. CloudStack currently accepts several weak or deprecated algorithms without guidance to users. This PR closes that gap by giving operators explicit control over what is disallowed vs discouraged, improving security posture without breaking existing deployments. These settings are: 1. vpn.customer.gateway.excluded.encryption.algorithms 2. vpn.customer.gateway.excluded.hashing.algorithms 3. vpn.customer.gateway.excluded.ike.versions 4. vpn.customer.gateway.excluded.dh.group 5. vpn.customer.gateway.obsolete.encryption.algorithms 6. vpn.customer.gateway.obsolete.hashing.algorithms 7. vpn.customer.gateway.obsolete.ike.versions 8. vpn.customer.gateway.obsolete.dh.group --- .../main/java/com/cloud/event/EventTypes.java | 2 + .../apache/cloudstack/alert/AlertService.java | 1 + .../apache/cloudstack/api/ApiConstants.java | 4 + .../user/config/ListCapabilitiesCmd.java | 16 + .../api/response/CapabilitiesResponse.java | 10 + .../Site2SiteCustomerGatewayResponse.java | 16 + .../ConfigKeyScheduledExecutionWrapper.java | 2 +- .../com/cloud/alert/AlertManagerImpl.java | 3 +- .../java/com/cloud/api/ApiResponseHelper.java | 13 + .../network/vpn/Site2SiteVpnManager.java | 6 + .../network/vpn/Site2SiteVpnManagerImpl.java | 279 +++++- .../cloud/server/ManagementServerImpl.java | 56 +- .../vpn/Site2SiteVpnManagerImplTest.java | 944 ++++++++++++++++++ .../vpc/MockSite2SiteVpnManagerImpl.java | 17 +- ui/public/locales/en.json | 22 +- ui/src/components/view/ListView.vue | 8 + ui/src/config/section/network.js | 10 +- .../network/CreateVpnCustomerGateway.vue | 360 +------ .../network/UpdateVpnCustomerGateway.vue | 129 +++ ui/src/views/network/VpnCustomerGateway.vue | 581 +++++++++++ 20 files changed, 2122 insertions(+), 357 deletions(-) create mode 100644 server/src/test/java/com/cloud/network/vpn/Site2SiteVpnManagerImplTest.java create mode 100644 ui/src/views/network/UpdateVpnCustomerGateway.vue create mode 100644 ui/src/views/network/VpnCustomerGateway.vue diff --git a/api/src/main/java/com/cloud/event/EventTypes.java b/api/src/main/java/com/cloud/event/EventTypes.java index 38e601c790a7..d2989a8ffdc9 100644 --- a/api/src/main/java/com/cloud/event/EventTypes.java +++ b/api/src/main/java/com/cloud/event/EventTypes.java @@ -503,6 +503,7 @@ public class EventTypes { public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE = "VPN.S2S.CUSTOMER.GATEWAY.CREATE"; public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE = "VPN.S2S.CUSTOMER.GATEWAY.DELETE"; public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE = "VPN.S2S.CUSTOMER.GATEWAY.UPDATE"; + public static final String EVENT_S2S_VPN_GATEWAY_OBSOLETE_PARAMS = "VPN.S2S.GATEWAY.OBSOLETE.PARAMS"; public static final String EVENT_S2S_VPN_CONNECTION_CREATE = "VPN.S2S.CONNECTION.CREATE"; public static final String EVENT_S2S_VPN_CONNECTION_DELETE = "VPN.S2S.CONNECTION.DELETE"; public static final String EVENT_S2S_VPN_CONNECTION_RESET = "VPN.S2S.CONNECTION.RESET"; @@ -1151,6 +1152,7 @@ public class EventTypes { entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE, Site2SiteCustomerGateway.class); entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE, Site2SiteCustomerGateway.class); entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE, Site2SiteCustomerGateway.class); + entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_OBSOLETE_PARAMS, Site2SiteCustomerGateway.class); entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_CREATE, Site2SiteVpnConnection.class); entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_DELETE, Site2SiteVpnConnection.class); entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_RESET, Site2SiteVpnConnection.class); diff --git a/api/src/main/java/org/apache/cloudstack/alert/AlertService.java b/api/src/main/java/org/apache/cloudstack/alert/AlertService.java index d8e471756a02..cc3188feeca5 100644 --- a/api/src/main/java/org/apache/cloudstack/alert/AlertService.java +++ b/api/src/main/java/org/apache/cloudstack/alert/AlertService.java @@ -74,6 +74,7 @@ private AlertType(short type, String name, boolean isDefault) { public static final AlertType ALERT_TYPE_VR_PUBLIC_IFACE_MTU = new AlertType((short)32, "ALERT.VR.PUBLIC.IFACE.MTU", true); public static final AlertType ALERT_TYPE_VR_PRIVATE_IFACE_MTU = new AlertType((short)32, "ALERT.VR.PRIVATE.IFACE.MTU", true); public static final AlertType ALERT_TYPE_EXTENSION_PATH_NOT_READY = new AlertType((short)33, "ALERT.TYPE.EXTENSION.PATH.NOT.READY", true); + public static final AlertType ALERT_TYPE_VPN_GATEWAY_OBSOLETE_PARAMETERS = new AlertType((short)34, "ALERT.S2S.VPN.GATEWAY.OBSOLETE.PARAMETERS", true); public static final AlertType ALERT_TYPE_BACKUP_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_BACKUP_STORAGE, "ALERT.STORAGE.BACKUP", true); public static final AlertType ALERT_TYPE_OBJECT_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_OBJECT_STORAGE, "ALERT.STORAGE.OBJECT", true); 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 3e36d933772b..896031806d53 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -1364,6 +1364,10 @@ public class ApiConstants { public static final String RECURSIVE_DOMAINS = "recursivedomains"; + public static final String VPN_CUSTOMER_GATEWAY_PARAMETERS = "vpncustomergatewayparameters"; + public static final String OBSOLETE_PARAMETERS = "obsoleteparameters"; + public static final String EXCLUDED_PARAMETERS = "excludedparameters"; + /** * This enum specifies IO Drivers, each option controls specific policies on I/O. * Qemu guests support "threads" and "native" options Since 0.8.8 ; "io_uring" is supported Since 6.3.0 (QEMU 5.0). diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java index ed1bd7b063b2..94b6062b6212 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java @@ -21,7 +21,9 @@ import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.CapabilitiesResponse; +import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.config.ApiServiceConfiguration; import com.cloud.user.Account; @@ -30,12 +32,22 @@ requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListCapabilitiesCmd extends BaseCmd { + @Parameter(name = ApiConstants.DOMAIN_ID, + type = CommandType.UUID, + entityType = DomainResponse.class, + description = "the domain for listing capabilities.", + since = "4.23.0") + private Long domainId; @Override public long getEntityOwnerId() { return Account.ACCOUNT_ID_SYSTEM; } + public Long getDomainId() { + return domainId; + } + @Override public void execute() { Map capabilities = _mgr.listCapabilities(this); @@ -76,6 +88,10 @@ public void execute() { response.setExtensionsPath((String)capabilities.get(ApiConstants.EXTENSIONS_PATH)); response.setDynamicScalingEnabled((Boolean) capabilities.get(ApiConstants.DYNAMIC_SCALING_ENABLED)); response.setAdditionalConfigEnabled((Boolean) capabilities.get(ApiConstants.ADDITONAL_CONFIG_ENABLED)); + if (capabilities.containsKey(ApiConstants.VPN_CUSTOMER_GATEWAY_PARAMETERS)) { + Map vpnCustomerGatewayParameters = (Map) capabilities.get(ApiConstants.VPN_CUSTOMER_GATEWAY_PARAMETERS); + response.setVpnCustomerGatewayParameters(vpnCustomerGatewayParameters); + } response.setObjectName("capability"); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java index 930d1a50de0f..816216962808 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java @@ -16,6 +16,8 @@ // under the License. package org.apache.cloudstack.api.response; +import java.util.Map; + import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; @@ -153,6 +155,10 @@ public class CapabilitiesResponse extends BaseResponse { @Param(description = "true if additional configurations or extraconfig can be passed to Instances", since = "4.20.2") private Boolean additionalConfigEnabled; + @SerializedName(ApiConstants.VPN_CUSTOMER_GATEWAY_PARAMETERS) + @Param(description = "Excluded and obsolete VPN customer gateway cryptographic parameters") + private Map vpnCustomerGatewayParameters; + public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) { this.securityGroupsEnabled = securityGroupsEnabled; } @@ -280,4 +286,8 @@ public void setDynamicScalingEnabled(Boolean dynamicScalingEnabled) { public void setAdditionalConfigEnabled(Boolean additionalConfigEnabled) { this.additionalConfigEnabled = additionalConfigEnabled; } + + public void setVpnCustomerGatewayParameters(Map vpnCustomerGatewayParameters) { + this.vpnCustomerGatewayParameters = vpnCustomerGatewayParameters; + } } diff --git a/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java index 4e5820279a2e..b121ef7ce61e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java @@ -114,6 +114,14 @@ public class Site2SiteCustomerGatewayResponse extends BaseResponseWithAnnotation @Param(description = "Which IKE Version to use, one of ike (autoselect), IKEv1, or IKEv2. Defaults to ike") private String ikeVersion; + @SerializedName(ApiConstants.OBSOLETE_PARAMETERS) + @Param(description = "Contains the list of obsolete/insecure cryptographic parameters that the vpn customer gateway is using.", since = "4.23.0") + private String obsoleteParameters; + + @SerializedName(ApiConstants.EXCLUDED_PARAMETERS) + @Param(description = "Contains the list of excluded/not allowed cryptographic parameters that the vpn customer gateway is using.", since = "4.23.0") + private String excludedParameters; + public void setId(String id) { this.id = id; } @@ -202,4 +210,12 @@ public void setDomainPath(String domainPath) { this.domainPath = domainPath; } + public void setContainsObsoleteParameters(String obsoleteParameters) { + this.obsoleteParameters = obsoleteParameters; + } + + public void setContainsExcludedParameters(String excludedParameters) { + this.excludedParameters = excludedParameters; + } + } diff --git a/framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigKeyScheduledExecutionWrapper.java b/framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigKeyScheduledExecutionWrapper.java index b8d7e7829711..a02ee8abee09 100644 --- a/framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigKeyScheduledExecutionWrapper.java +++ b/framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigKeyScheduledExecutionWrapper.java @@ -66,7 +66,7 @@ public ConfigKeyScheduledExecutionWrapper(ScheduledExecutorService executorServi this.unit = unit; } - protected ConfigKeyScheduledExecutionWrapper(ScheduledExecutorService executorService, Runnable command, + public ConfigKeyScheduledExecutionWrapper(ScheduledExecutorService executorService, Runnable command, ConfigKey configKey, int enableIntervalSeconds, TimeUnit unit) { validateArgs(executorService, command, configKey); this.executorService = executorService; diff --git a/server/src/main/java/com/cloud/alert/AlertManagerImpl.java b/server/src/main/java/com/cloud/alert/AlertManagerImpl.java index 3eab3fbfeb1b..308c4443cb8b 100644 --- a/server/src/main/java/com/cloud/alert/AlertManagerImpl.java +++ b/server/src/main/java/com/cloud/alert/AlertManagerImpl.java @@ -112,7 +112,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi , AlertType.ALERT_TYPE_OOBM_AUTH_ERROR , AlertType.ALERT_TYPE_HA_ACTION , AlertType.ALERT_TYPE_CA_CERT - , AlertType.ALERT_TYPE_EXTENSION_PATH_NOT_READY); + , AlertType.ALERT_TYPE_EXTENSION_PATH_NOT_READY + , AlertType.ALERT_TYPE_VPN_GATEWAY_OBSOLETE_PARAMETERS); private static final long INITIAL_CAPACITY_CHECK_DELAY = 30L * 1000L; // Thirty seconds expressed in milliseconds. diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index 3c7eeaf3b8f9..ce794cf5388f 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -50,6 +50,7 @@ import com.cloud.dc.dao.VlanDetailsDao; import com.cloud.hypervisor.Hypervisor; import com.cloud.network.vpc.VpcGateway; +import com.cloud.network.vpn.Site2SiteVpnManager; import com.cloud.storage.BucketVO; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; @@ -528,6 +529,8 @@ public class ApiResponseHelper implements ResponseGenerator { @Inject RoutedIpv4Manager routedIpv4Manager; @Inject + Site2SiteVpnManager site2SiteVpnManager; + @Inject ResourceIconManager resourceIconManager; public static String getPrettyDomainPath(String path) { @@ -3884,6 +3887,16 @@ public Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(S response.setRemoved(result.getRemoved()); response.setIkeVersion(result.getIkeVersion()); response.setSplitConnections(result.getSplitConnections()); + + Set obsoleteParameters = site2SiteVpnManager.getObsoleteVpnGatewayParameters(result); + if (CollectionUtils.isNotEmpty(obsoleteParameters)) { + response.setContainsObsoleteParameters(obsoleteParameters.toString()); + } + Set excludedParameters = site2SiteVpnManager.getExcludedVpnGatewayParameters(result); + if (CollectionUtils.isNotEmpty(excludedParameters)) { + response.setContainsExcludedParameters(excludedParameters.toString()); + } + response.setObjectName("vpncustomergateway"); response.setHasAnnotation(annotationDao.hasAnnotations(result.getUuid(), AnnotationService.EntityType.VPN_CUSTOMER_GATEWAY.name(), _accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId()))); diff --git a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManager.java b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManager.java index 25c84d6d956b..9cf604f85070 100644 --- a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManager.java +++ b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManager.java @@ -17,11 +17,17 @@ package com.cloud.network.vpn; import java.util.List; +import java.util.Set; +import com.cloud.network.Site2SiteCustomerGateway; import com.cloud.network.dao.Site2SiteVpnConnectionVO; import com.cloud.vm.DomainRouterVO; public interface Site2SiteVpnManager extends Site2SiteVpnService { + Set getExcludedVpnGatewayParameters(Site2SiteCustomerGateway customerGw); + + Set getObsoleteVpnGatewayParameters(Site2SiteCustomerGateway customerGw); + boolean cleanupVpnConnectionByVpc(long vpcId); boolean cleanupVpnGatewayByVpc(long vpcId); diff --git a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index ad1d1f02682e..09236eb0d6e7 100644 --- a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -17,15 +17,22 @@ package com.cloud.network.vpn; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.framework.config.Configurable; import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Component; +import org.apache.cloudstack.alert.AlertService; import org.apache.cloudstack.annotation.AnnotationService; import org.apache.cloudstack.annotation.dao.AnnotationDao; import org.apache.cloudstack.api.command.user.vpn.CreateVpnConnectionCmd; @@ -41,9 +48,16 @@ import org.apache.cloudstack.api.command.user.vpn.UpdateVpnCustomerGatewayCmd; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.ConfigKeyScheduledExecutionWrapper; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; +import com.cloud.utils.concurrency.NamedThreadFactory; + +import com.cloud.alert.AlertManager; import com.cloud.configuration.Config; import com.cloud.event.ActionEvent; +import com.cloud.event.ActionEventUtils; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; @@ -72,9 +86,11 @@ import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.User; import com.cloud.user.dao.AccountDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; +import com.cloud.utils.StringUtils; import com.cloud.utils.Ternary; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; @@ -88,7 +104,52 @@ import com.cloud.vm.dao.DomainRouterDao; @Component -public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpnManager { +public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpnManager, Configurable { + + // Configuration keys for VPN gateway cryptographic parameter controls + public static final ConfigKey VpnCustomerGatewayExcludedEncryptionAlgorithms = new ConfigKey( + ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.excluded.encryption.algorithms", "", + "Comma-separated list of encryption algorithms that are excluded and cannot be selected by end users for VPN Customer Gateways." + + "Applies to both IKE and ESP phases. Allowed values are aes128, aes192 and aes256 and 3des.", + true, ConfigKey.Scope.Domain); + public static final ConfigKey VpnCustomerGatewayExcludedHashingAlgorithms = new ConfigKey( + ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.excluded.hashing.algorithms", "", + "Comma-separated list of hashing algorithms that are excluded and cannot be selected by end users for VPN Customer Gateways." + + "Applies to both IKE and ESP phases. Allowed values are sha1, sha256, sha384 and sha512 and md5.", + true, ConfigKey.Scope.Domain); + public static final ConfigKey VpnCustomerGatewayExcludedIkeVersions = new ConfigKey( + ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.excluded.ike.versions", "", + "Comma-separated list of IKE versions that are excluded and cannot be selected by end users for VPN Customer Gateways. Allowed values are ikev, ikev1 and ikev2.", + true, ConfigKey.Scope.Domain); + public static final ConfigKey VpnCustomerGatewayExcludedDhGroup = new ConfigKey( + ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.excluded.dh.group", "", + "Comma-separated list of Diffie-Hellman groups that are excluded and cannot be selected by end users for VPN Customer Gateways." + + "Applies to both IKE and ESP phases. Allowed values are modp1024, modp1536, modp2048, modp3072, modp4096, modp6144 and modp8192.", + true, ConfigKey.Scope.Domain); + public static final ConfigKey VpnCustomerGatewayObsoleteEncryptionAlgorithms = new ConfigKey( + ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.obsolete.encryption.algorithms", "", + "Comma-separated list of encryption algorithms that are marked as obsolete/insecure for VPN Customer Gateways." + + "Applies to both IKE and ESP phases. Allowed values are aes128, aes192 and aes256 and 3des.", + true, ConfigKey.Scope.Domain); + public static final ConfigKey VpnCustomerGatewayObsoleteHashingAlgorithms = new ConfigKey( + ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.obsolete.hashing.algorithms", "", + "Comma-separated list of hashing algorithms that are marked as obsolete/insecure for VPN Customer Gateways." + + "Applies to both IKE and ESP phases. Allowed values are sha1, sha256, sha384 and sha512 and md5.", + true, ConfigKey.Scope.Domain); + public static final ConfigKey VpnCustomerGatewayObsoleteIkeVersions = new ConfigKey( + ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.obsolete.ike.versions", "", + "Comma-separated list of IKE versions that are marked as obsolete/insecure for VPN Customer Gateways. Allowed values are ikev, ikev1 and ikev2.", + true, ConfigKey.Scope.Domain); + public static final ConfigKey VpnCustomerGatewayObsoleteDhGroup = new ConfigKey( + ConfigKey.CATEGORY_NETWORK, String.class, "vpn.customer.gateway.obsolete.dh.group", "", + "Comma-separated list of Diffie-Hellman groups that are marked as obsolete/insecure for VPN Customer Gateways." + + "Applies to both IKE and ESP phases. Allowed values are modp1024, modp1536, modp2048, modp3072, modp4096, modp6144 and modp8192.", + true, ConfigKey.Scope.Domain); + public static final ConfigKey VpnCustomerGatewayObsoleteCheckInterval = new ConfigKey( + ConfigKey.CATEGORY_NETWORK, Long.class, "vpn.customer.gateway.obsolete.check.interval", "0", + "Interval in hours to periodically check VPN customer gateways for obsolete/excluded parameters and generate events and alerts. " + + "Set to 0 to disable. Default: 0 (disabled).", + true, ConfigKey.Scope.Global); List _s2sProviders; @Inject @@ -117,9 +178,12 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn private IpAddressManager ipAddressManager; @Inject private VpcManager vpcManager; + @Inject + private AlertManager _alertMgr; int _connLimit; int _subnetsLimit; + private ScheduledExecutorService _vpnCheckExecutor; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -127,6 +191,7 @@ public boolean configure(String name, Map params) throws Configu _connLimit = NumbersUtil.parseInt(configs.get(Config.Site2SiteVpnConnectionPerVpnGatewayLimit.key()), 4); _subnetsLimit = NumbersUtil.parseInt(configs.get(Config.Site2SiteVpnSubnetsPerCustomerGatewayLimit.key()), 10); assert (_s2sProviders.iterator().hasNext()) : "Did not get injected with a list of S2S providers!"; + _vpnCheckExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpnCustomerGateway-ExcludedAndObsoleteCheck")); return true; } @@ -146,7 +211,7 @@ public Site2SiteVpnGateway createVpnGateway(CreateVpnGatewayCmd cmd) { } Site2SiteVpnGatewayVO gws = _vpnGatewayDao.findByVpcId(vpcId); if (gws != null) { - throw new InvalidParameterValueException(String.format("The VPN gateway of VPC %s already existed!", vpc)); + throw new InvalidParameterValueException(String.format("The VPN gateway of VPC %s already exists!", vpc)); } IPAddressVO requestedIp = _ipAddressDao.findById(cmd.getIpAddressId()); @@ -187,6 +252,113 @@ private IPAddressVO getIpAddressIdForVpn(Long vpcId, Long vpcOferingId, IPAddres } } + private void validateVpnCryptographicParameters(String ikePolicy, String espPolicy, String ikeVersion, Long domainId) { + String excludedEncryption = VpnCustomerGatewayExcludedEncryptionAlgorithms.valueIn(domainId); + String excludedHashing = VpnCustomerGatewayExcludedHashingAlgorithms.valueIn(domainId); + String excludedIkeVersions = VpnCustomerGatewayExcludedIkeVersions.valueIn(domainId); + String excludedDhGroup = VpnCustomerGatewayExcludedDhGroup.valueIn(domainId); + + Set excludedParameters = getVpnGatewayParametersInBlockedList(ikePolicy, espPolicy, ikeVersion, + excludedEncryption, excludedHashing, excludedIkeVersions, excludedDhGroup); + if (!excludedParameters.isEmpty()) { + throw new InvalidParameterValueException("The following excluded cryptographic parameter(s) cannot be used in a VPN Customer Gateway: " + excludedParameters.toString()); + } + } + + @Override + public Set getExcludedVpnGatewayParameters(Site2SiteCustomerGateway customerGw) { + Long domainId = customerGw.getDomainId(); + String excludedEncryption = VpnCustomerGatewayExcludedEncryptionAlgorithms.valueIn(domainId); + String excludedHashing = VpnCustomerGatewayExcludedHashingAlgorithms.valueIn(domainId); + String excludedIkeVersions = VpnCustomerGatewayExcludedIkeVersions.valueIn(domainId); + String excludedDhGroup = VpnCustomerGatewayExcludedDhGroup.valueIn(domainId); + + return getVpnGatewayParametersInBlockedList(customerGw.getIkePolicy(), customerGw.getEspPolicy(), customerGw.getIkeVersion(), + excludedEncryption, excludedHashing, excludedIkeVersions, excludedDhGroup); + } + + @Override + public Set getObsoleteVpnGatewayParameters(Site2SiteCustomerGateway customerGw) { + Long domainId = customerGw.getDomainId(); + String obsoleteEncryption = VpnCustomerGatewayObsoleteEncryptionAlgorithms.valueIn(domainId); + String obsoleteHashing = VpnCustomerGatewayObsoleteHashingAlgorithms.valueIn(domainId); + String obsoleteIkeVersions = VpnCustomerGatewayObsoleteIkeVersions.valueIn(domainId); + String obsoleteDhGroup = VpnCustomerGatewayObsoleteDhGroup.valueIn(domainId); + + return getVpnGatewayParametersInBlockedList(customerGw.getIkePolicy(), customerGw.getEspPolicy(), customerGw.getIkeVersion(), + obsoleteEncryption, obsoleteHashing, obsoleteIkeVersions, obsoleteDhGroup); + } + + private Set getVpnGatewayParametersInBlockedList(String ikePolicy, String espPolicy, String ikeVersion, + String blockedEncryptionList, String blockedHashingList, + String blockedIkeVersionList, String blockedDhGroupList) { + + Set blockedParameters = new HashSet<>(); + if (StringUtils.isEmpty(blockedEncryptionList) + && StringUtils.isEmpty(blockedHashingList) + && StringUtils.isEmpty(blockedIkeVersionList) + && StringUtils.isEmpty(blockedDhGroupList)) { + return blockedParameters; + } + + if (isParameterInList(ikeVersion, blockedIkeVersionList)) { + blockedParameters.add(ikeVersion); + } + + Set ikePolicyResult = getVpnGatewayPolicyParametersInBlockedList(ikePolicy, "IKE", blockedEncryptionList, blockedHashingList, blockedDhGroupList); + if (CollectionUtils.isNotEmpty(ikePolicyResult)) { + blockedParameters.addAll(ikePolicyResult); + } + + Set espPolicyResult = getVpnGatewayPolicyParametersInBlockedList(espPolicy, "ESP", blockedEncryptionList, blockedHashingList, blockedDhGroupList); + if (CollectionUtils.isNotEmpty(espPolicyResult)) { + blockedParameters.addAll(espPolicyResult); + } + + return blockedParameters; + } + + private Set getVpnGatewayPolicyParametersInBlockedList(String policy, String policyType, String blockedEncryptionList, String blockedHashingList, String blockedDhGroupList) { + + String trimmedPolicy = policy.trim(); + String cipherHash = trimmedPolicy.split(";")[0]; + String[] parts = cipherHash.split("-"); + + String encryption = parts[0].trim(); + String hashing = parts.length > 1 ? parts[1].trim() : ""; + + Set blockedParameters = new HashSet<>(); + if (isParameterInList(encryption, blockedEncryptionList)) { + blockedParameters.add(encryption); + } + + if (isParameterInList(hashing, blockedHashingList)) { + blockedParameters.add(hashing); + } + + if (!trimmedPolicy.equals(cipherHash)) { + String dhGroup = trimmedPolicy.split(";")[1].trim(); + if (isParameterInList(dhGroup, blockedDhGroupList)) { + blockedParameters.add(dhGroup); + } + } + return blockedParameters; + } + + private boolean isParameterInList(String parameter, String list) { + if (StringUtils.isEmpty(list) || StringUtils.isEmpty(parameter)) { + return false; + } + + String[] entries = list.split(","); + for (String item : entries) { + if (item != null && item.trim().equalsIgnoreCase(parameter.trim())) { + return true; + } + } + return false; + } + protected void checkCustomerGatewayCidrList(String guestCidrList) { String[] cidrList = guestCidrList.split(","); if (cidrList.length > _subnetsLimit) { @@ -235,6 +407,13 @@ public Site2SiteCustomerGateway createCustomerGateway(CreateVpnCustomerGatewayCm if (!NetUtils.isValidS2SVpnPolicy("esp", espPolicy)) { throw new InvalidParameterValueException("The customer gateway ESP policy " + espPolicy + " is invalid!"); } + + String ikeVersion = cmd.getIkeVersion(); + if (ikeVersion == null) { + ikeVersion = "ike"; + } + validateVpnCryptographicParameters(ikePolicy, espPolicy, ikeVersion, owner.getDomainId()); + Long ikeLifetime = cmd.getIkeLifetime(); if (ikeLifetime == null) { // Default value of lifetime is 1 day @@ -264,7 +443,7 @@ public Site2SiteCustomerGateway createCustomerGateway(CreateVpnCustomerGatewayCm long accountId = owner.getAccountId(); if (_customerGatewayDao.findByNameAndAccountId(name, accountId) != null) { - throw new InvalidParameterValueException("The customer gateway with name " + name + " already existed!"); + throw new InvalidParameterValueException("The customer gateway with name " + name + " already exists!"); } Boolean splitConnections = cmd.getSplitConnections(); @@ -272,11 +451,6 @@ public Site2SiteCustomerGateway createCustomerGateway(CreateVpnCustomerGatewayCm splitConnections = false; } - String ikeVersion = cmd.getIkeVersion(); - if (ikeVersion == null) { - ikeVersion = "ike"; - } - checkCustomerGatewayCidrList(peerCidrList); Site2SiteCustomerGatewayVO gw = @@ -374,7 +548,7 @@ private void validateVpnConnectionOfTheRightAccount(Site2SiteCustomerGateway cus private void validateVpnConnectionDoesntExist(Site2SiteCustomerGateway customerGateway, Site2SiteVpnGateway vpnGateway) { if (_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(vpnGateway.getId(), customerGateway.getId()) != null) { - throw new InvalidParameterValueException(String.format("The vpn connection with customer gateway %s and vpn gateway %s already existed!", customerGateway, vpnGateway)); + throw new InvalidParameterValueException(String.format("The vpn connection with customer gateway %s and vpn gateway %s already exists!", customerGateway, vpnGateway)); } } @@ -521,6 +695,10 @@ public Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCm if (!NetUtils.isValidS2SVpnPolicy("esp", espPolicy)) { throw new InvalidParameterValueException("The customer gateway ESP policy" + espPolicy + " is invalid!"); } + + String ikeVersion = cmd.getIkeVersion(); + validateVpnCryptographicParameters(ikePolicy, espPolicy, ikeVersion, gw.getDomainId()); + Long ikeLifetime = cmd.getIkeLifetime(); if (ikeLifetime == null) { // Default value of lifetime is 1 day @@ -550,14 +728,12 @@ public Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCm Boolean splitConnections = cmd.getSplitConnections(); - String ikeVersion = cmd.getIkeVersion(); - checkCustomerGatewayCidrList(guestCidrList); long accountId = gw.getAccountId(); Site2SiteCustomerGatewayVO existedGw = _customerGatewayDao.findByNameAndAccountId(name, accountId); if (existedGw != null && existedGw.getId() != gw.getId()) { - throw new InvalidParameterValueException("The customer gateway with name " + name + " already existed!"); + throw new InvalidParameterValueException("The customer gateway with name " + name + " already exists!"); } gw.setName(name); @@ -977,4 +1153,83 @@ public Site2SiteVpnGateway updateVpnGateway(Long id, String customId, Boolean fo return _vpnGatewayDao.findById(id); } + + @Override + public boolean start() { + ConfigKeyScheduledExecutionWrapper runner = new ConfigKeyScheduledExecutionWrapper( + _vpnCheckExecutor, + new CheckVpnCustomerGatewayObsoleteParametersTask(), + VpnCustomerGatewayObsoleteCheckInterval, + 3600, + TimeUnit.HOURS); + runner.start(); + return true; + } + + @Override + public boolean stop() { + if (_vpnCheckExecutor != null) { + _vpnCheckExecutor.shutdownNow(); + } + return true; + } + + @Override + public String getConfigComponentName() { + return Site2SiteVpnManager.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] { VpnCustomerGatewayExcludedEncryptionAlgorithms, VpnCustomerGatewayExcludedHashingAlgorithms, + VpnCustomerGatewayExcludedIkeVersions, VpnCustomerGatewayExcludedDhGroup, VpnCustomerGatewayObsoleteEncryptionAlgorithms, + VpnCustomerGatewayObsoleteHashingAlgorithms, VpnCustomerGatewayObsoleteIkeVersions, VpnCustomerGatewayObsoleteDhGroup, + VpnCustomerGatewayObsoleteCheckInterval}; + } + + protected class CheckVpnCustomerGatewayObsoleteParametersTask extends ManagedContextRunnable { + + @Override + protected void runInContext() { + List allGateways = _customerGatewayDao.listAll(); + int obsoleteCount = 0; + int excludedCount = 0; + + for (Site2SiteCustomerGatewayVO gateway : allGateways) { + Set excludedParameters = getExcludedVpnGatewayParameters(gateway); + Set obsoleteParameters = getObsoleteVpnGatewayParameters(gateway); + + List message = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(excludedParameters)) { + excludedCount++; + message.add("excluded parameter(s) " + excludedParameters.toString()); + } + if (CollectionUtils.isNotEmpty(obsoleteParameters)) { + obsoleteCount++; + message.add("obsolete parameter(s) " + obsoleteParameters.toString()); + } + + if (CollectionUtils.isNotEmpty(message)) { + Account account = _accountDao.findById(gateway.getAccountId()); + String description = String.format("VPN customer gateway '%s' (Account: %s) contains %s.", + gateway.getName(), account.getAccountName(), String.join(" and ", message)); + ActionEventUtils.onActionEvent(User.UID_SYSTEM, gateway.getAccountId(), gateway.getDomainId(), + EventTypes.EVENT_S2S_VPN_GATEWAY_OBSOLETE_PARAMS, description, + gateway.getId(), Site2SiteCustomerGateway.class.getSimpleName()); + } + } + + List message = new ArrayList<>(); + if (excludedCount > 0) { + message.add("excluded parameters: " + excludedCount); + } + if (obsoleteCount > 0) { + message.add("obsolete parameters: " + obsoleteCount); + } + if (CollectionUtils.isNotEmpty(message)) { + String subject = String.format("VPN customer gateways using " + String.join(", ", message)); + _alertMgr.sendAlert(AlertService.AlertType.ALERT_TYPE_VPN_GATEWAY_OBSOLETE_PARAMETERS, 0L, 0L, subject, null); + } + } + } } diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java b/server/src/main/java/com/cloud/server/ManagementServerImpl.java index 47dcf60eb32d..8ee35cc35ec0 100644 --- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java +++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java @@ -720,6 +720,7 @@ import com.cloud.deploy.DeploymentPlanner; import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.deploy.DeploymentPlanningManager; +import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; @@ -761,6 +762,7 @@ import com.cloud.network.Network; import com.cloud.network.NetworkModel; import com.cloud.network.Networks; +import com.cloud.network.vpn.Site2SiteVpnManagerImpl; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.LoadBalancerDao; @@ -4778,6 +4780,14 @@ public Map listCapabilities(final ListCapabilitiesCmd cmd) { final Map capabilities = new HashMap<>(); final Account caller = getCaller(); + Long domainId = cmd.getDomainId(); + if (domainId == null) { + domainId = caller.getDomainId(); + } else { + Domain domain = _domainDao.findById(domainId); + _accountService.checkAccess(caller, domain); + } + final boolean isCallerRootAdmin = _accountService.isRootAdmin(caller.getId()); final boolean isCallerAdmin = isCallerRootAdmin || _accountService.isAdmin(caller.getId()); boolean securityGroupsEnabled = false; @@ -4812,7 +4822,7 @@ public Map listCapabilities(final ListCapabilitiesCmd cmd) { final boolean allowUserExpungeRecoverVolume = (VolumeApiServiceImpl.AllowUserExpungeRecoverVolume.valueIn(caller.getId()) | isCallerAdmin); final boolean allowUserForceStopVM = (UserVmManager.AllowUserForceStopVm.valueIn(caller.getId()) | isCallerAdmin); - final boolean allowUserViewAllDomainAccounts = (QueryService.AllowUserViewAllDomainAccounts.valueIn(caller.getDomainId())); + final boolean allowUserViewAllDomainAccounts = (QueryService.AllowUserViewAllDomainAccounts.valueIn(domainId)); final boolean kubernetesServiceEnabled = Boolean.parseBoolean(_configDao.getValue("cloud.kubernetes.service.enabled")); final boolean kubernetesClusterExperimentalFeaturesEnabled = Boolean.parseBoolean(_configDao.getValue("cloud.kubernetes.cluster.experimental.features.enabled")); @@ -4865,9 +4875,53 @@ public Map listCapabilities(final ListCapabilitiesCmd cmd) { } capabilities.put(ApiConstants.ADDITONAL_CONFIG_ENABLED, UserVmManager.EnableAdditionalVmConfig.valueIn(caller.getId())); + Map vpnParams = getVpnCustomerGatewayParameters(domainId); + if (!vpnParams.isEmpty()) { + capabilities.put(ApiConstants.VPN_CUSTOMER_GATEWAY_PARAMETERS, vpnParams); + } + return capabilities; } + private Map getVpnCustomerGatewayParameters(Long domainId) { + Map vpnParams = new HashMap<>(); + + String excludedEncryption = Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms.valueIn(domainId); + String excludedHashing = Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms.valueIn(domainId); + String excludedIkeVersions = Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions.valueIn(domainId); + String excludedDhGroup = Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup.valueIn(domainId); + String obsoleteEncryption = Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms.valueIn(domainId); + String obsoleteHashing = Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms.valueIn(domainId); + String obsoleteIkeVersions = Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions.valueIn(domainId); + String obsoleteDhGroup = Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup.valueIn(domainId); + + if (!excludedEncryption.isEmpty()) { + vpnParams.put("excludedencryptionalgorithms", excludedEncryption); + } + if (!obsoleteEncryption.isEmpty()) { + vpnParams.put("obsoleteencryptionalgorithms", obsoleteEncryption); + } + if (!excludedHashing.isEmpty()) { + vpnParams.put("excludedhashingalgorithms", excludedHashing); + } + if (!obsoleteHashing.isEmpty()) { + vpnParams.put("obsoletehashingalgorithms", obsoleteHashing); + } + if (!excludedIkeVersions.isEmpty()) { + vpnParams.put("excludedikeversions", excludedIkeVersions); + } + if (!obsoleteIkeVersions.isEmpty()) { + vpnParams.put("obsoleteikeversions", obsoleteIkeVersions); + } + if (!excludedDhGroup.isEmpty()) { + vpnParams.put("excludeddhgroups", excludedDhGroup); + } + if (!obsoleteDhGroup.isEmpty()) { + vpnParams.put("obsoletedhgroups", obsoleteDhGroup); + } + return vpnParams; + } + @Override public GuestOSVO getGuestOs(final Long guestOsId) { return _guestOSDao.findById(guestOsId); diff --git a/server/src/test/java/com/cloud/network/vpn/Site2SiteVpnManagerImplTest.java b/server/src/test/java/com/cloud/network/vpn/Site2SiteVpnManagerImplTest.java new file mode 100644 index 000000000000..291d3a4aa812 --- /dev/null +++ b/server/src/test/java/com/cloud/network/vpn/Site2SiteVpnManagerImplTest.java @@ -0,0 +1,944 @@ +/* + * 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.vpn; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnConnection.State; +import com.cloud.network.Site2SiteVpnGateway; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.Site2SiteCustomerGatewayDao; +import com.cloud.network.dao.Site2SiteCustomerGatewayVO; +import com.cloud.network.dao.Site2SiteVpnConnectionDao; +import com.cloud.network.dao.Site2SiteVpnConnectionVO; +import com.cloud.network.dao.Site2SiteVpnGatewayDao; +import com.cloud.network.dao.Site2SiteVpnGatewayVO; +import com.cloud.network.element.Site2SiteVpnServiceProvider; +import com.cloud.network.vpc.VpcManager; +import com.cloud.network.vpc.VpcVO; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; +import com.cloud.user.User; +import com.cloud.user.UserVO; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.DomainRouterVO; +import org.apache.cloudstack.acl.SecurityChecker; +import org.apache.cloudstack.annotation.dao.AnnotationDao; +import org.apache.cloudstack.api.command.user.vpn.CreateVpnConnectionCmd; +import org.apache.cloudstack.api.command.user.vpn.CreateVpnCustomerGatewayCmd; +import org.apache.cloudstack.api.command.user.vpn.CreateVpnGatewayCmd; +import org.apache.cloudstack.api.command.user.vpn.DeleteVpnConnectionCmd; +import org.apache.cloudstack.api.command.user.vpn.DeleteVpnCustomerGatewayCmd; +import org.apache.cloudstack.api.command.user.vpn.DeleteVpnGatewayCmd; +import org.apache.cloudstack.api.command.user.vpn.ResetVpnConnectionCmd; +import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.Silent.class) +public class Site2SiteVpnManagerImplTest { + + @Mock + private Site2SiteCustomerGatewayDao _customerGatewayDao; + @Mock + private Site2SiteVpnGatewayDao _vpnGatewayDao; + @Mock + private Site2SiteVpnConnectionDao _vpnConnectionDao; + @Mock + private VpcDao _vpcDao; + @Mock + private IPAddressDao _ipAddressDao; + @Mock + private VpcManager _vpcMgr; + @Mock + private AccountManager _accountMgr; + @Mock + private AnnotationDao annotationDao; + @Mock + private List _s2sProviders; + @Mock + VpcOfferingServiceMapDao vpcOfferingServiceMapDao; + + @InjectMocks + private Site2SiteVpnManagerImpl site2SiteVpnManager; + + private AccountVO account; + private UserVO user; + private VpcVO vpc; + private IPAddressVO ipAddress; + private Site2SiteVpnGatewayVO vpnGateway; + private Site2SiteCustomerGatewayVO customerGateway; + private Site2SiteVpnConnectionVO vpnConnection; + + private static final Long ACCOUNT_ID = 1L; + private static final Long DOMAIN_ID = 2L; + private static final Long VPC_ID = 3L; + private static final Long VPN_GATEWAY_ID = 4L; + private static final Long CUSTOMER_GATEWAY_ID = 5L; + private static final Long VPN_CONNECTION_ID = 6L; + private static final Long IP_ADDRESS_ID = 7L; + + @Before + public void setUp() throws Exception { + account = new AccountVO("testaccount", DOMAIN_ID, "networkdomain", Account.Type.NORMAL, UUID.randomUUID().toString()); + account.setId(ACCOUNT_ID); + user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", + UUID.randomUUID().toString(), User.Source.UNKNOWN); + CallContext.register(user, account); + + vpc = mock(VpcVO.class); + when(vpc.getId()).thenReturn(VPC_ID); + when(vpc.getAccountId()).thenReturn(ACCOUNT_ID); + when(vpc.getDomainId()).thenReturn(DOMAIN_ID); + when(vpc.getCidr()).thenReturn("10.0.0.0/16"); + + ipAddress = mock(IPAddressVO.class); + when(ipAddress.getId()).thenReturn(IP_ADDRESS_ID); + when(ipAddress.getVpcId()).thenReturn(VPC_ID); + + vpnGateway = mock(Site2SiteVpnGatewayVO.class); + when(vpnGateway.getId()).thenReturn(VPN_GATEWAY_ID); + when(vpnGateway.getVpcId()).thenReturn(VPC_ID); + when(vpnGateway.getAccountId()).thenReturn(ACCOUNT_ID); + when(vpnGateway.getDomainId()).thenReturn(DOMAIN_ID); + + customerGateway = mock(Site2SiteCustomerGatewayVO.class); + when(customerGateway.getId()).thenReturn(CUSTOMER_GATEWAY_ID); + when(customerGateway.getAccountId()).thenReturn(ACCOUNT_ID); + when(customerGateway.getDomainId()).thenReturn(DOMAIN_ID); + when(customerGateway.getGuestCidrList()).thenReturn("192.168.1.0/24"); + when(customerGateway.getIkePolicy()).thenReturn("aes128-sha256;modp2048"); + when(customerGateway.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(customerGateway.getIkeVersion()).thenReturn("ike"); + + vpnConnection = new Site2SiteVpnConnectionVO(ACCOUNT_ID, DOMAIN_ID, VPN_GATEWAY_ID, CUSTOMER_GATEWAY_ID, false); + vpnConnection.setState(State.Pending); + + when(_accountMgr.getAccount(ACCOUNT_ID)).thenReturn(account); + doNothing().when(_accountMgr).checkAccess(any(Account.class), nullable(SecurityChecker.AccessType.class), anyBoolean(), any()); + } + + @After + public void tearDown() throws Exception { + resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions); + resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms); + resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms); + resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup); + resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions); + resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms); + resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms); + resetConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup); + CallContext.unregister(); + } + + private void setConfigKeyValue(ConfigKey configKey, String value) { + try { + Field valueField = ConfigKey.class.getDeclaredField("_value"); + valueField.setAccessible(true); + valueField.set(configKey, value); + + Field dynamicField = ConfigKey.class.getDeclaredField("_isDynamic"); + dynamicField.setAccessible(true); + dynamicField.setBoolean(configKey, false); + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException("Failed to set ConfigKey value", e); + } + } + + private void resetConfigKeyValue(ConfigKey configKey) { + try { + Field valueField = ConfigKey.class.getDeclaredField("_value"); + valueField.setAccessible(true); + valueField.set(configKey, null); + + Field dynamicField = ConfigKey.class.getDeclaredField("_isDynamic"); + dynamicField.setAccessible(true); + dynamicField.setBoolean(configKey, true); + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException("Failed to reset ConfigKey value", e); + } + } + + @Test + public void testCreateVpnGatewaySuccess() { + CreateVpnGatewayCmd cmd = mock(CreateVpnGatewayCmd.class); + when(cmd.getVpcId()).thenReturn(VPC_ID); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + when(cmd.isDisplay()).thenReturn(true); + + when(_vpcDao.findById(VPC_ID)).thenReturn(vpc); + when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(null); + when(_ipAddressDao.listByAssociatedVpc(VPC_ID, true)).thenReturn(List.of(ipAddress)); + when(_vpnGatewayDao.persist(any(Site2SiteVpnGatewayVO.class))).thenReturn(vpnGateway); + + Site2SiteVpnGateway result = site2SiteVpnManager.createVpnGateway(cmd); + + assertNotNull(result); + verify(_vpnGatewayDao).persist(any(Site2SiteVpnGatewayVO.class)); + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateVpnGatewayInvalidVpc() { + CreateVpnGatewayCmd cmd = mock(CreateVpnGatewayCmd.class); + when(cmd.getVpcId()).thenReturn(VPC_ID); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + when(_vpcDao.findById(VPC_ID)).thenReturn(null); + + site2SiteVpnManager.createVpnGateway(cmd); + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateVpnGatewayAlreadyExists() { + CreateVpnGatewayCmd cmd = mock(CreateVpnGatewayCmd.class); + when(cmd.getVpcId()).thenReturn(VPC_ID); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + when(_vpcDao.findById(VPC_ID)).thenReturn(vpc); + when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(vpnGateway); + + site2SiteVpnManager.createVpnGateway(cmd); + } + + @Test(expected = CloudRuntimeException.class) + public void testCreateVpnGatewayNoSourceNatIp() { + CreateVpnGatewayCmd cmd = mock(CreateVpnGatewayCmd.class); + when(cmd.getVpcId()).thenReturn(VPC_ID); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + when(_vpcDao.findById(VPC_ID)).thenReturn(vpc); + when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(null); + when(_ipAddressDao.listByAssociatedVpc(VPC_ID, true)).thenReturn(new ArrayList<>()); + + site2SiteVpnManager.createVpnGateway(cmd); + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateCustomerGatewayInvalidIp() { + CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class); + when(cmd.getGatewayIp()).thenReturn("invalid-ip"); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + try (MockedStatic netUtilsMock = Mockito.mockStatic(NetUtils.class)) { + netUtilsMock.when(() -> NetUtils.isValidIp4("invalid-ip")).thenReturn(false); + netUtilsMock.when(() -> NetUtils.verifyDomainName("invalid-ip")).thenReturn(false); + + site2SiteVpnManager.createCustomerGateway(cmd); + } + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateCustomerGatewayInvalidCidrList() { + CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class); + when(cmd.getGatewayIp()).thenReturn("1.2.3.4"); + when(cmd.getGuestCidrList()).thenReturn("invalid-cidr"); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + try (MockedStatic netUtilsMock = Mockito.mockStatic(NetUtils.class)) { + netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidCidrList("invalid-cidr")).thenReturn(false); + + site2SiteVpnManager.createCustomerGateway(cmd); + } + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateCustomerGatewayInvalidIkePolicy() { + CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class); + when(cmd.getGatewayIp()).thenReturn("1.2.3.4"); + when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24"); + when(cmd.getIkePolicy()).thenReturn("invalid-policy"); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + try (MockedStatic netUtilsMock = Mockito.mockStatic(NetUtils.class)) { + netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidCidrList("192.168.1.0/24")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "invalid-policy")).thenReturn(false); + + site2SiteVpnManager.createCustomerGateway(cmd); + } + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateCustomerGatewayInvalidEspPolicy() { + CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class); + when(cmd.getGatewayIp()).thenReturn("1.2.3.4"); + when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24"); + when(cmd.getIkePolicy()).thenReturn("aes128-sha256;modp2048"); + when(cmd.getEspPolicy()).thenReturn("invalid-policy"); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + try (MockedStatic netUtilsMock = Mockito.mockStatic(NetUtils.class)) { + netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidCidrList("192.168.1.0/24")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "aes128-sha256;modp2048")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "invalid-policy")).thenReturn(false); + + site2SiteVpnManager.createCustomerGateway(cmd); + } + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateCustomerGatewayWithExcludedParameters() throws Exception { + CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class); + when(cmd.getName()).thenReturn("test-gateway"); + when(cmd.getGatewayIp()).thenReturn("1.2.3.4"); + when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24"); + when(cmd.getIpsecPsk()).thenReturn("test-psk"); + when(cmd.getIkePolicy()).thenReturn("3des-sha256;modp2048"); + when(cmd.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(cmd.getIkeVersion()).thenReturn("ike"); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, "3des"); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, ""); + + try (MockedStatic netUtilsMock = Mockito.mockStatic(NetUtils.class)) { + netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidCidrList("192.168.1.0/24")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "3des-sha256;modp2048")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "aes128-sha256;modp2048")).thenReturn(true); + + site2SiteVpnManager.createCustomerGateway(cmd); + } + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateCustomerGatewayDuplicateName() { + CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class); + when(cmd.getName()).thenReturn("test-gateway"); + when(cmd.getGatewayIp()).thenReturn("1.2.3.4"); + when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24"); + when(cmd.getIkePolicy()).thenReturn("aes128-sha256;modp2048"); + when(cmd.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + try (MockedStatic netUtilsMock = Mockito.mockStatic(NetUtils.class)) { + netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidCidrList("192.168.1.0/24")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "aes128-sha256;modp2048")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "aes128-sha256;modp2048")).thenReturn(true); + + when(_customerGatewayDao.findByNameAndAccountId("test-gateway", ACCOUNT_ID)).thenReturn(customerGateway); + + site2SiteVpnManager.createCustomerGateway(cmd); + } + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateCustomerGatewayInvalidIkeLifetime() { + CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class); + when(cmd.getGatewayIp()).thenReturn("1.2.3.4"); + when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24"); + when(cmd.getIkePolicy()).thenReturn("aes128-sha256;modp2048"); + when(cmd.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(cmd.getIkeLifetime()).thenReturn(86401L); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + try (MockedStatic netUtilsMock = Mockito.mockStatic(NetUtils.class)) { + netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidCidrList("192.168.1.0/24")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "aes128-sha256;modp2048")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "aes128-sha256;modp2048")).thenReturn(true); + + site2SiteVpnManager.createCustomerGateway(cmd); + } + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateCustomerGatewayInvalidEspLifetime() { + CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class); + when(cmd.getGatewayIp()).thenReturn("1.2.3.4"); + when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24"); + when(cmd.getIkePolicy()).thenReturn("aes128-sha256;modp2048"); + when(cmd.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(cmd.getEspLifetime()).thenReturn(86401L); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + try (MockedStatic netUtilsMock = Mockito.mockStatic(NetUtils.class)) { + netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidCidrList("192.168.1.0/24")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "aes128-sha256;modp2048")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "aes128-sha256;modp2048")).thenReturn(true); + + site2SiteVpnManager.createCustomerGateway(cmd); + } + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateCustomerGatewayTooManySubnets() { + CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class); + when(cmd.getGatewayIp()).thenReturn("1.2.3.4"); + String tooManyCidrs = "192.168.1.0/24,192.168.2.0/24,192.168.3.0/24,192.168.4.0/24,192.168.5.0/24," + + "192.168.6.0/24,192.168.7.0/24,192.168.8.0/24,192.168.9.0/24,192.168.10.0/24,192.168.11.0/24"; + when(cmd.getGuestCidrList()).thenReturn(tooManyCidrs); + when(cmd.getIkePolicy()).thenReturn("aes128-sha256;modp2048"); + when(cmd.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + try (MockedStatic netUtilsMock = Mockito.mockStatic(NetUtils.class)) { + netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidCidrList(tooManyCidrs)).thenReturn(true); + netUtilsMock.when(() -> NetUtils.getCleanIp4CidrList(tooManyCidrs)).thenReturn(tooManyCidrs); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "aes128-sha256;modp2048")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "aes128-sha256;modp2048")).thenReturn(true); + + site2SiteVpnManager.createCustomerGateway(cmd); + } + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateCustomerGatewayOverlappingSubnets() { + CreateVpnCustomerGatewayCmd cmd = mock(CreateVpnCustomerGatewayCmd.class); + when(cmd.getGatewayIp()).thenReturn("1.2.3.4"); + when(cmd.getGuestCidrList()).thenReturn("192.168.1.0/24,192.168.1.0/25"); + when(cmd.getIkePolicy()).thenReturn("aes128-sha256;modp2048"); + when(cmd.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + try (MockedStatic netUtilsMock = Mockito.mockStatic(NetUtils.class)) { + String cidrList = "192.168.1.0/24,192.168.1.0/25"; + netUtilsMock.when(() -> NetUtils.isValidIp4("1.2.3.4")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidCidrList(cidrList)).thenReturn(true); + netUtilsMock.when(() -> NetUtils.getCleanIp4CidrList(cidrList)).thenReturn(cidrList); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("ike", "aes128-sha256;modp2048")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isValidS2SVpnPolicy("esp", "aes128-sha256;modp2048")).thenReturn(true); + netUtilsMock.when(() -> NetUtils.isNetworksOverlap("192.168.1.0/24", "192.168.1.0/25")).thenReturn(true); + + site2SiteVpnManager.createCustomerGateway(cmd); + } + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateVpnConnectionCidrOverlapWithVpc() { + CreateVpnConnectionCmd cmd = mock(CreateVpnConnectionCmd.class); + when(cmd.getVpnGatewayId()).thenReturn(VPN_GATEWAY_ID); + when(cmd.getCustomerGatewayId()).thenReturn(CUSTOMER_GATEWAY_ID); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + Site2SiteCustomerGatewayVO customerGw = mock(Site2SiteCustomerGatewayVO.class); + when(customerGw.getGuestCidrList()).thenReturn("10.0.0.0/24"); + when(customerGw.getAccountId()).thenReturn(ACCOUNT_ID); + when(customerGw.getDomainId()).thenReturn(DOMAIN_ID); + + when(_customerGatewayDao.findById(CUSTOMER_GATEWAY_ID)).thenReturn(customerGw); + when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway); + when(_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(VPN_GATEWAY_ID, CUSTOMER_GATEWAY_ID)).thenReturn(null); + when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(vpnGateway); + when(_vpcDao.findById(VPC_ID)).thenReturn(vpc); + + try (MockedStatic netUtilsMock = Mockito.mockStatic(NetUtils.class)) { + netUtilsMock.when(() -> NetUtils.isNetworksOverlap("10.0.0.0/16", "10.0.0.0/24")).thenReturn(true); + + site2SiteVpnManager.createVpnConnection(cmd); + } + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateVpnConnectionExceedsLimit() { + CreateVpnConnectionCmd cmd = mock(CreateVpnConnectionCmd.class); + when(cmd.getVpnGatewayId()).thenReturn(VPN_GATEWAY_ID); + when(cmd.getCustomerGatewayId()).thenReturn(CUSTOMER_GATEWAY_ID); + when(cmd.getEntityOwnerId()).thenReturn(ACCOUNT_ID); + + when(_customerGatewayDao.findById(CUSTOMER_GATEWAY_ID)).thenReturn(customerGateway); + when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway); + when(_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(VPN_GATEWAY_ID, CUSTOMER_GATEWAY_ID)).thenReturn(null); + when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(vpnGateway); + when(_vpcDao.findById(VPC_ID)).thenReturn(vpc); + + List existingConns = new ArrayList<>(); + for (int i = 0; i < 4; i++) { + existingConns.add(mock(Site2SiteVpnConnectionVO.class)); + } + when(_vpnConnectionDao.listByVpnGatewayId(VPN_GATEWAY_ID)).thenReturn(existingConns); + + site2SiteVpnManager.createVpnConnection(cmd); + } + + @Test + public void testDeleteCustomerGatewaySuccess() { + DeleteVpnCustomerGatewayCmd cmd = mock(DeleteVpnCustomerGatewayCmd.class); + when(cmd.getId()).thenReturn(CUSTOMER_GATEWAY_ID); + + when(_customerGatewayDao.findById(CUSTOMER_GATEWAY_ID)).thenReturn(customerGateway); + when(_vpnConnectionDao.listByCustomerGatewayId(CUSTOMER_GATEWAY_ID)).thenReturn(new ArrayList<>()); + + boolean result = site2SiteVpnManager.deleteCustomerGateway(cmd); + + assertTrue(result); + verify(_customerGatewayDao).remove(CUSTOMER_GATEWAY_ID); + } + + @Test(expected = InvalidParameterValueException.class) + public void testDeleteCustomerGatewayWithConnections() { + DeleteVpnCustomerGatewayCmd cmd = mock(DeleteVpnCustomerGatewayCmd.class); + when(cmd.getId()).thenReturn(CUSTOMER_GATEWAY_ID); + + when(_customerGatewayDao.findById(CUSTOMER_GATEWAY_ID)).thenReturn(customerGateway); + when(_vpnConnectionDao.listByCustomerGatewayId(CUSTOMER_GATEWAY_ID)).thenReturn(List.of(vpnConnection)); + + site2SiteVpnManager.deleteCustomerGateway(cmd); + } + + @Test + public void testDeleteVpnGatewaySuccess() { + DeleteVpnGatewayCmd cmd = mock(DeleteVpnGatewayCmd.class); + when(cmd.getId()).thenReturn(VPN_GATEWAY_ID); + + when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway); + when(_vpnConnectionDao.listByVpnGatewayId(VPN_GATEWAY_ID)).thenReturn(new ArrayList<>()); + + boolean result = site2SiteVpnManager.deleteVpnGateway(cmd); + + assertTrue(result); + verify(_vpnGatewayDao).remove(VPN_GATEWAY_ID); + } + + @Test(expected = InvalidParameterValueException.class) + public void testDeleteVpnGatewayWithConnections() { + DeleteVpnGatewayCmd cmd = mock(DeleteVpnGatewayCmd.class); + when(cmd.getId()).thenReturn(VPN_GATEWAY_ID); + + when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway); + when(_vpnConnectionDao.listByVpnGatewayId(VPN_GATEWAY_ID)).thenReturn(List.of(vpnConnection)); + + site2SiteVpnManager.deleteVpnGateway(cmd); + } + + @Test + public void testDeleteVpnConnectionSuccess() throws ResourceUnavailableException { + DeleteVpnConnectionCmd cmd = mock(DeleteVpnConnectionCmd.class); + when(cmd.getId()).thenReturn(VPN_CONNECTION_ID); + + when(_vpnConnectionDao.findById(VPN_CONNECTION_ID)).thenReturn(vpnConnection); + vpnConnection.setState(State.Pending); + when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway); + when(_vpcMgr.applyStaticRouteForVpcVpnIfNeeded(anyLong(), anyBoolean())).thenReturn(true); + + boolean result = site2SiteVpnManager.deleteVpnConnection(cmd); + + assertTrue(result); + verify(_vpnConnectionDao).remove(VPN_CONNECTION_ID); + } + + @Test + public void testStartVpnConnectionSuccess() throws ResourceUnavailableException { + when(_vpnConnectionDao.acquireInLockTable(VPN_CONNECTION_ID)).thenReturn(vpnConnection); + vpnConnection.setState(State.Pending); + when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway); + Site2SiteVpnServiceProvider provider = mock(Site2SiteVpnServiceProvider.class); + when(provider.startSite2SiteVpn(any(Site2SiteVpnConnection.class))).thenReturn(true); + when(_s2sProviders.iterator()).thenReturn(List.of(provider).iterator()); + when(_vpnConnectionDao.persist(any(Site2SiteVpnConnectionVO.class))).thenReturn(vpnConnection); + when(_vpcMgr.applyStaticRouteForVpcVpnIfNeeded(anyLong(), anyBoolean())).thenReturn(true); + + Site2SiteVpnConnection result = site2SiteVpnManager.startVpnConnection(VPN_CONNECTION_ID); + + assertNotNull(result); + verify(_vpnConnectionDao, org.mockito.Mockito.atLeastOnce()).persist(any(Site2SiteVpnConnectionVO.class)); + } + + @Test(expected = InvalidParameterValueException.class) + public void testStartVpnConnectionWrongState() throws ResourceUnavailableException { + when(_vpnConnectionDao.acquireInLockTable(VPN_CONNECTION_ID)).thenReturn(vpnConnection); + vpnConnection.setState(State.Connected); + + site2SiteVpnManager.startVpnConnection(VPN_CONNECTION_ID); + } + + @Test + public void testResetVpnConnectionSuccess() throws ResourceUnavailableException { + ResetVpnConnectionCmd cmd = mock(ResetVpnConnectionCmd.class); + when(cmd.getId()).thenReturn(VPN_CONNECTION_ID); + + when(_vpnConnectionDao.findById(VPN_CONNECTION_ID)).thenReturn(vpnConnection); + vpnConnection.setState(State.Connected); + when(_vpnConnectionDao.acquireInLockTable(VPN_CONNECTION_ID)).thenReturn(vpnConnection); + when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway); + Site2SiteVpnServiceProvider provider = mock(Site2SiteVpnServiceProvider.class); + when(provider.stopSite2SiteVpn(any(Site2SiteVpnConnection.class))).thenReturn(true); + when(provider.startSite2SiteVpn(any(Site2SiteVpnConnection.class))).thenReturn(true); + when(_s2sProviders.iterator()).thenReturn(List.of(provider).iterator()); + when(_vpnConnectionDao.persist(any(Site2SiteVpnConnectionVO.class))).thenReturn(vpnConnection); + when(_vpcMgr.applyStaticRouteForVpcVpnIfNeeded(anyLong(), anyBoolean())).thenReturn(true); + + Site2SiteVpnConnection result = site2SiteVpnManager.resetVpnConnection(cmd); + + assertNotNull(result); + } + + @Test + public void testCleanupVpnConnectionByVpc() { + when(_vpnConnectionDao.listByVpcId(VPC_ID)).thenReturn(List.of(vpnConnection)); + + boolean result = site2SiteVpnManager.cleanupVpnConnectionByVpc(VPC_ID); + + assertTrue(result); + verify(_vpnConnectionDao).remove(vpnConnection.getId()); + } + + @Test + public void testCleanupVpnGatewayByVpc() { + when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(vpnGateway); + when(_vpnConnectionDao.listByVpnGatewayId(VPN_GATEWAY_ID)).thenReturn(new ArrayList<>()); + + boolean result = site2SiteVpnManager.cleanupVpnGatewayByVpc(VPC_ID); + + assertTrue(result); + verify(_vpnGatewayDao).remove(VPN_GATEWAY_ID); + } + + @Test + public void testCleanupVpnGatewayByVpcNotFound() { + when(_vpnGatewayDao.findByVpcId(VPC_ID)).thenReturn(null); + + boolean result = site2SiteVpnManager.cleanupVpnGatewayByVpc(VPC_ID); + + assertTrue(result); + verify(_vpnGatewayDao, never()).remove(anyLong()); + } + + @Test + public void testGetConnectionsForRouter() { + DomainRouterVO router = mock(DomainRouterVO.class); + when(router.getVpcId()).thenReturn(VPC_ID); + when(_vpnConnectionDao.listByVpcId(VPC_ID)).thenReturn(List.of(vpnConnection)); + + List result = site2SiteVpnManager.getConnectionsForRouter(router); + + assertNotNull(result); + assertEquals(1, result.size()); + } + + @Test + public void testGetConnectionsForRouterNoVpc() { + DomainRouterVO router = mock(DomainRouterVO.class); + when(router.getVpcId()).thenReturn(null); + + List result = site2SiteVpnManager.getConnectionsForRouter(router); + + assertNotNull(result); + assertTrue(result.isEmpty()); + } + + @Test + public void testDeleteCustomerGatewayByAccount() { + when(_customerGatewayDao.listByAccountId(ACCOUNT_ID)).thenReturn(List.of(customerGateway)); + when(_vpnConnectionDao.listByCustomerGatewayId(CUSTOMER_GATEWAY_ID)).thenReturn(new ArrayList<>()); + + boolean result = site2SiteVpnManager.deleteCustomerGatewayByAccount(ACCOUNT_ID); + + assertTrue(result); + verify(_customerGatewayDao).remove(CUSTOMER_GATEWAY_ID); + } + + @Test + public void testReconnectDisconnectedVpnByVpc() throws ResourceUnavailableException { + Site2SiteVpnConnectionVO conn = mock(Site2SiteVpnConnectionVO.class); + when(conn.getId()).thenReturn(VPN_CONNECTION_ID); + when(conn.getState()).thenReturn(State.Disconnected); + when(conn.getCustomerGatewayId()).thenReturn(CUSTOMER_GATEWAY_ID); + when(conn.getVpnGatewayId()).thenReturn(VPN_GATEWAY_ID); + when(_vpnConnectionDao.listByVpcId(VPC_ID)).thenReturn(List.of(conn)); + when(_customerGatewayDao.findById(CUSTOMER_GATEWAY_ID)).thenReturn(customerGateway); + when(_vpnConnectionDao.acquireInLockTable(VPN_CONNECTION_ID)).thenReturn(conn); + when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway); + Site2SiteVpnServiceProvider provider = mock(Site2SiteVpnServiceProvider.class); + when(provider.startSite2SiteVpn(any(Site2SiteVpnConnection.class))).thenReturn(true); + when(_s2sProviders.iterator()).thenReturn(List.of(provider).iterator()); + when(_vpnConnectionDao.persist(any(Site2SiteVpnConnectionVO.class))).thenReturn(conn); + when(_vpcMgr.applyStaticRouteForVpcVpnIfNeeded(anyLong(), anyBoolean())).thenReturn(true); + + site2SiteVpnManager.reconnectDisconnectedVpnByVpc(VPC_ID); + + verify(_vpnConnectionDao, org.mockito.Mockito.atLeastOnce()).persist(any(Site2SiteVpnConnectionVO.class)); + } + + @Test + public void testUpdateVpnConnection() { + when(_vpnConnectionDao.findById(VPN_CONNECTION_ID)).thenReturn(vpnConnection); + when(_vpnConnectionDao.update(anyLong(), any(Site2SiteVpnConnectionVO.class))).thenReturn(true); + when(_vpnConnectionDao.findById(VPN_CONNECTION_ID)).thenReturn(vpnConnection); + + Site2SiteVpnConnection result = site2SiteVpnManager.updateVpnConnection(VPN_CONNECTION_ID, "custom-id", true); + + assertNotNull(result); + } + + @Test + public void testUpdateVpnGateway() { + when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway); + when(_vpnGatewayDao.update(anyLong(), any(Site2SiteVpnGatewayVO.class))).thenReturn(true); + when(_vpnGatewayDao.findById(VPN_GATEWAY_ID)).thenReturn(vpnGateway); + + Site2SiteVpnGateway result = site2SiteVpnManager.updateVpnGateway(VPN_GATEWAY_ID, "custom-id", true); + + assertNotNull(result); + } + + @Test + public void testVpnGatewayContainsExcludedParametersWithExcludedIkeVersion() throws Exception { + Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class); + when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getIkeVersion()).thenReturn("ikev1"); + when(gw.getDomainId()).thenReturn(DOMAIN_ID); + + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, "ikev1"); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, ""); + + java.util.Set result = site2SiteVpnManager.getExcludedVpnGatewayParameters(gw); + assertFalse("Should detect excluded IKE version", result.isEmpty()); + assertEquals("Should detect excluded IKE version", "[ikev1]", result.toString()); + } + + @Test + public void testVpnGatewayContainsExcludedParametersWithExcludedEncryption() throws Exception { + Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class); + when(gw.getIkePolicy()).thenReturn("3des-sha256;modp2048"); + when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getIkeVersion()).thenReturn("ike"); + when(gw.getDomainId()).thenReturn(DOMAIN_ID); + + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, "3des"); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, ""); + + java.util.Set result = site2SiteVpnManager.getExcludedVpnGatewayParameters(gw); + assertFalse("Should detect excluded encryption algorithm", result.isEmpty()); + assertEquals("Should detect excluded encryption algorithm", "[3des]", result.toString()); + } + + @Test + public void testVpnGatewayContainsExcludedParametersWithExcludedHashing() throws Exception { + Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class); + when(gw.getIkePolicy()).thenReturn("aes128-md5;modp2048"); + when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getIkeVersion()).thenReturn("ike"); + when(gw.getDomainId()).thenReturn(DOMAIN_ID); + + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, "aes128"); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, "md5"); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, ""); + + java.util.Set result = site2SiteVpnManager.getExcludedVpnGatewayParameters(gw); + assertFalse("Should detect excluded algorithms", result.isEmpty()); + assertEquals("Should detect excluded algorithms", "[aes128, md5]", result.toString()); + } + + @Test + public void testVpnGatewayContainsExcludedParametersWithExcludedDhGroup() { + Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class); + when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp1024"); + when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getIkeVersion()).thenReturn("ike"); + when(gw.getDomainId()).thenReturn(DOMAIN_ID); + + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, "modp1024"); + + java.util.Set result = site2SiteVpnManager.getExcludedVpnGatewayParameters(gw); + assertFalse("Should detect excluded DH group", result.isEmpty()); + assertEquals("Should detect excluded DH group", "[modp1024]", result.toString()); + } + + @Test + public void testVpnGatewayContainsExcludedParametersNoExcludedParameters() { + Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class); + when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getIkeVersion()).thenReturn("ike"); + when(gw.getDomainId()).thenReturn(DOMAIN_ID); + + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, ""); + + java.util.Set result = site2SiteVpnManager.getExcludedVpnGatewayParameters(gw); + assertTrue("Should not detect excluded parameters when none are configured", result.isEmpty()); + } + + @Test + public void testVpnGatewayContainsExcludedParametersWithExcludedEspPolicy() { + Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class); + when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getEspPolicy()).thenReturn("3des-sha256;modp2048"); + when(gw.getIkeVersion()).thenReturn("ike"); + when(gw.getDomainId()).thenReturn(DOMAIN_ID); + + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedIkeVersions, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedEncryptionAlgorithms, "3des"); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedHashingAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayExcludedDhGroup, ""); + + java.util.Set result = site2SiteVpnManager.getExcludedVpnGatewayParameters(gw); + assertFalse("Should detect excluded encryption in ESP policy", result.isEmpty()); + assertEquals("Should detect excluded encryption in ESP policy", "[3des]", result.toString()); + } + + @Test + public void testVpnGatewayContainsObsoleteParametersWithObsoleteIkeVersion() { + Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class); + when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getIkeVersion()).thenReturn("ikev1"); + when(gw.getDomainId()).thenReturn(DOMAIN_ID); + + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions, "ikev1"); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup, ""); + + java.util.Set result = site2SiteVpnManager.getObsoleteVpnGatewayParameters(gw); + assertFalse("Should detect obsolete IKE version", result.isEmpty()); + assertEquals("Should detect obsolete IKE version", "[ikev1]", result.toString()); + } + + @Test + public void testVpnGatewayContainsObsoleteParametersWithObsoleteEncryption() { + Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class); + when(gw.getIkePolicy()).thenReturn("3des-sha256;modp2048"); + when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getIkeVersion()).thenReturn("ike"); + when(gw.getDomainId()).thenReturn(DOMAIN_ID); + + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms, "3des"); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup, ""); + + java.util.Set result = site2SiteVpnManager.getObsoleteVpnGatewayParameters(gw); + assertFalse("Should detect obsolete encryption algorithm", result.isEmpty()); + assertEquals("Should detect obsolete encryption algorithm", "[3des]", result.toString()); + } + + @Test + public void testVpnGatewayContainsObsoleteParametersWithObsoleteHashing() { + Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class); + when(gw.getIkePolicy()).thenReturn("aes128-md5;modp2048"); + when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getIkeVersion()).thenReturn("ike"); + when(gw.getDomainId()).thenReturn(DOMAIN_ID); + + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms, "md5"); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup, ""); + + java.util.Set result = site2SiteVpnManager.getObsoleteVpnGatewayParameters(gw); + assertFalse("Should detect obsolete hashing algorithm", result.isEmpty()); + assertEquals("Should detect obsolete hashing algorithm", "[md5]", result.toString()); + } + + @Test + public void testVpnGatewayContainsObsoleteParametersWithObsoleteDhGroup() { + Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class); + when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp1024"); + when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getIkeVersion()).thenReturn("ike"); + when(gw.getDomainId()).thenReturn(DOMAIN_ID); + + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup, "modp1024"); + + java.util.Set result = site2SiteVpnManager.getObsoleteVpnGatewayParameters(gw); + assertFalse("Should detect obsolete DH group", result.isEmpty()); + assertEquals("Should detect obsolete DH group", "[modp1024]", result.toString()); + } + + @Test + public void testVpnGatewayContainsObsoleteParametersNoObsoleteParameters() { + Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class); + when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getEspPolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getIkeVersion()).thenReturn("ike"); + when(gw.getDomainId()).thenReturn(DOMAIN_ID); + + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup, ""); + + java.util.Set result = site2SiteVpnManager.getObsoleteVpnGatewayParameters(gw); + assertTrue("Should not detect obsolete parameters when none are configured", result.isEmpty()); + } + + @Test + public void testVpnGatewayContainsObsoleteParametersWithObsoleteEspPolicy() { + Site2SiteCustomerGatewayVO gw = mock(Site2SiteCustomerGatewayVO.class); + when(gw.getIkePolicy()).thenReturn("aes128-sha256;modp2048"); + when(gw.getEspPolicy()).thenReturn("3des-sha256;modp2048"); + when(gw.getIkeVersion()).thenReturn("ike"); + when(gw.getDomainId()).thenReturn(DOMAIN_ID); + + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteIkeVersions, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteEncryptionAlgorithms, "3des"); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteHashingAlgorithms, ""); + setConfigKeyValue(Site2SiteVpnManagerImpl.VpnCustomerGatewayObsoleteDhGroup, ""); + + java.util.Set result = site2SiteVpnManager.getObsoleteVpnGatewayParameters(gw); + assertFalse("Should detect obsolete encryption in ESP policy", result.isEmpty()); + assertEquals("Should detect obsolete encryption in ESP policy", "[3des]", result.toString()); + } +} diff --git a/server/src/test/java/com/cloud/vpc/MockSite2SiteVpnManagerImpl.java b/server/src/test/java/com/cloud/vpc/MockSite2SiteVpnManagerImpl.java index 3558eed1cfa1..af6c1c599aab 100644 --- a/server/src/test/java/com/cloud/vpc/MockSite2SiteVpnManagerImpl.java +++ b/server/src/test/java/com/cloud/vpc/MockSite2SiteVpnManagerImpl.java @@ -23,7 +23,6 @@ import com.cloud.network.Site2SiteVpnGateway; import com.cloud.network.dao.Site2SiteVpnConnectionVO; import com.cloud.network.vpn.Site2SiteVpnManager; -import com.cloud.network.vpn.Site2SiteVpnService; import com.cloud.utils.Pair; import com.cloud.utils.component.ManagerBase; import com.cloud.vm.DomainRouterVO; @@ -41,11 +40,13 @@ import org.springframework.stereotype.Component; import javax.naming.ConfigurationException; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; @Component -public class MockSite2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpnManager, Site2SiteVpnService { +public class MockSite2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpnManager { /* (non-Javadoc) * @see com.cloud.network.vpn.Site2SiteVpnService#createVpnGateway(org.apache.cloudstack.api.commands.CreateVpnGatewayCmd) @@ -275,4 +276,16 @@ public Site2SiteVpnGateway updateVpnGateway(Long id, String customId, Boolean fo return null; } + @Override + public Set getExcludedVpnGatewayParameters(Site2SiteCustomerGateway customerGw) { + // TODO Auto-generated method stub + return new HashSet<>(); + } + + @Override + public Set getObsoleteVpnGatewayParameters(Site2SiteCustomerGateway customerGw) { + // TODO Auto-generated method stub + return new HashSet<>(); + } + } diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 86df45411e9e..c20827f2100b 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -807,7 +807,7 @@ "label.delete.tungsten.service.group": "Delete Service Group", "label.delete.volumes": "Data volumes to be deleted", "label.delete.vpn.connection": "Delete VPN connection", -"label.delete.vpn.customer.gateway": "Delete VPN customer gateway", +"label.delete.vpn.customer.gateway": "Delete VPN Customer Gateway", "label.delete.vpn.gateway": "Delete VPN gateway", "label.delete.vpn.user": "Delete VPN User", "label.delete.webhook": "Delete Webhook", @@ -2629,6 +2629,7 @@ "label.update.to": "updated to", "label.update.traffic.label": "Update traffic labels", "label.update.vmware.datacenter": "Update VMWare datacenter", +"label.update.vpn.customer.gateway": "Update VPN Customer Gateway", "label.update.webhook": "Update Webhook", "label.updating": "Updating", "label.upgrade.router.newer.template": "Upgrade router to use newer Template", @@ -3093,8 +3094,8 @@ "message.add.volume": "Please fill in the following data to add a new volume.", "message.add.vpn.connection.failed": "Adding VPN connection failed", "message.add.vpn.connection.processing": "Adding VPN Connection...", -"message.add.vpn.customer.gateway": "Adding VPN customer gateway", -"message.add.vpn.customer.gateway.processing": "Creation of VPN customer gateway is in progress", +"message.add.vpn.customer.gateway": "Adding VPN Customer Gateway", +"message.add.vpn.customer.gateway.processing": "Creation of VPN Customer Gateway is in progress", "message.add.vpn.gateway": "Please confirm that you want to add a VPN Gateway.", "message.add.vpn.gateway.failed": "Adding VPN gateway failed", "message.add.vpn.gateway.processing": "Adding VPN gateway...", @@ -3242,7 +3243,7 @@ "message.create.volume.failed": "Failed to create Volume.", "message.create.volume.processing": "Volume creation in progress", "message.create.vpc.offering": "VPC offering created.", -"message.create.vpn.customer.gateway.failed": "VPN customer gateway creation failed.", +"message.create.vpn.customer.gateway.failed": "VPN Customer Gateway creation failed.", "message.creating.autoscale.vmgroup": "Creating AutoScaling Group", "message.creating.autoscale.vmprofile": "Creating AutoScale Instance profile", "message.creating.autoscale.scaledown.conditions": "Creating ScaleDown conditions", @@ -3293,7 +3294,7 @@ "message.delete.tungsten.tag": "Are you sure you want to remove this Tag from this Policy?", "message.delete.user": "Please confirm that you would like to delete this User.", "message.delete.vpn.connection": "Please confirm that you want to delete VPN connection.", -"message.delete.vpn.customer.gateway": "Please confirm that you want to delete this VPN customer gateway.", +"message.delete.vpn.customer.gateway": "Please confirm that you want to delete this VPN Customer Gateway.", "message.delete.vpn.gateway": "Please confirm that you want to delete this VPN Gateway.", "message.delete.vpn.gateway.failed": "Failed to delete VPN Gateway.", "message.delete.webhook": "Please confirm that you want to delete this Webhook.", @@ -3834,7 +3835,7 @@ "message.success.add.tungsten.routing.policy": "Successfully added Tungsten-Fabric routing policy", "message.success.add.vpc": "Successfully added a Virtual Private Cloud", "message.success.add.vpc.network": "Successfully added a VPC network", -"message.success.add.vpn.customer.gateway": "Successfully added VPN customer gateway", +"message.success.add.vpn.customer.gateway": "Successfully added VPN Customer Gateway", "message.success.add.vpn.gateway": "Successfully added VPN gateway", "message.success.add.webhook.filter": "Successfully added Webhook Filter", "message.success.assign.sslcert": "Successfully assigned SSL certificate", @@ -3960,6 +3961,7 @@ "message.success.update.network": "Successfully updated Network", "message.success.update.template": "Successfully updated Template", "message.success.update.user": "Successfully updated User", +"message.success.update.vpn.customer.gateway": "Successfully updated VPN Customer Gateway", "message.success.upgrade.kubernetes": "Successfully upgraded Kubernetes Cluster", "message.success.upload": "Successfully uploaded", "message.success.upload.description": "This ISO file has been uploaded. Please check its status in the Templates menu.", @@ -3987,6 +3989,9 @@ "message.update.condition.failed": "Failed to update condition", "message.update.condition.processing": "Updating condition...", "message.update.failed": "Update failed", +"message.update.vpn.customer.gateway": "Update VPN Customer Gateway", +"message.update.vpn.customer.gateway.failed": "Updating the VPN Customer Gateway failed", +"message.update.vpn.customer.gateway.processing": "Updating VPN Customer Gateway...", "message.test.webhook.delivery": "Test delivery to the Webhook with an optional payload", "message.two.factor.authorization.failed": "Unable to verify 2FA with provided code, please retry.", "message.two.fa.auth": "Open the two-factor authentication app on your mobile device to view your authentication code.", @@ -4074,6 +4079,11 @@ "message.volumes.managed": "Volumes controlled by CloudStack.", "message.volumes.unmanaged": "Volumes not controlled by CloudStack.", "message.vpc.restart.required": "Restart is required for VPC(s). Click here to view VPC(s) which require restart.", +"message.vpn.customer.gateway.contains.excluded.obsolete.parameters": "This VPN Customer Gateway contains cryptographic parameters that are marked as excluded or obsolete by the Administrator. Consider changing them using the Update VPN Customer Gateway form.", +"message.vpn.customer.gateway.excluded.parameter": " is marked as excluded. Please choose another value.", +"message.vpn.customer.gateway.obsolete.parameter": " is marked as obsolete/insecure. Please choose another value.", +"message.vpn.customer.gateway.obsolete.parameter.tooltip": "This parameter value is marked as obsolete/insecure.", +"message.vr.alert.upon.network.offering.creation.l2": "As virtual routers are not created for L2 Networks, the compute offering will not be used.", "message.vr.alert.upon.network.offering.creation.others": "As none of the obligatory services for creating a virtual router (VPN, DHCP, DNS, Firewall, LB, UserData, SourceNat, StaticNat, PortForwarding) are enabled, the virtual router will not be created and the compute offering will not be used.", "message.warn.change.primary.storage.scope": "This feature is tested and supported for the following configurations:
KVM - NFS/Ceph - DefaultPrimary
VMware - NFS - DefaultPrimary
*There might be extra steps involved to make it work for other configurations.", "message.warn.filetype": "jpg, jpeg, png, bmp and svg are the only supported image formats.", diff --git a/ui/src/components/view/ListView.vue b/ui/src/components/view/ListView.vue index ba75465d8924..375fddcb55c6 100644 --- a/ui/src/components/view/ListView.vue +++ b/ui/src/components/view/ListView.vue @@ -170,6 +170,14 @@ + +   + + + + import('@/views/network/UpdateVpnCustomerGateway.vue'))) }, { api: 'deleteVpnCustomerGateway', diff --git a/ui/src/views/network/CreateVpnCustomerGateway.vue b/ui/src/views/network/CreateVpnCustomerGateway.vue index f71fc4709e8d..155765a276f5 100644 --- a/ui/src/views/network/CreateVpnCustomerGateway.vue +++ b/ui/src/views/network/CreateVpnCustomerGateway.vue @@ -15,352 +15,58 @@ // specific language governing permissions and limitations // under the License. + - diff --git a/ui/src/views/network/UpdateVpnCustomerGateway.vue b/ui/src/views/network/UpdateVpnCustomerGateway.vue new file mode 100644 index 000000000000..2d54e8e031ed --- /dev/null +++ b/ui/src/views/network/UpdateVpnCustomerGateway.vue @@ -0,0 +1,129 @@ +// 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. + + + diff --git a/ui/src/views/network/VpnCustomerGateway.vue b/ui/src/views/network/VpnCustomerGateway.vue new file mode 100644 index 000000000000..c1b1ed78ce06 --- /dev/null +++ b/ui/src/views/network/VpnCustomerGateway.vue @@ -0,0 +1,581 @@ +// 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. + + + + From 8b2f1f19c27bebf908f9cda53ec1fadd005e2520 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Mon, 19 Jan 2026 03:51:47 -0500 Subject: [PATCH 063/101] Support dedicating backup offerings to domains (#12194) * Add support for dedicating backup offerings to domains * Add tests and UI support and update response params * add license header * exclude backupofferingdetailsvo from sonar * fix pre-commit checks - missing / extra EOF line * add test * EOF * filter backup offerings by domain id * add unit tests * add more unit tests and remove response file from code coverage check * update checks * address review comments: extract common code, fix tests * added bean definition * address comments * add unit tests to increase coverage * pre-commit check failure fix * address merge issue * allow updating backup offering when only domain id is modified --- .../java/com/cloud/user/AccountService.java | 3 + .../cloudstack/acl/SecurityChecker.java | 4 + .../cloudstack/api/BaseBackupListCmd.java | 2 +- .../admin/backup/ImportBackupOfferingCmd.java | 22 ++ .../admin/backup/UpdateBackupOfferingCmd.java | 28 +- .../network/UpdateNetworkOfferingCmd.java | 65 +--- .../admin/offering/UpdateDiskOfferingCmd.java | 62 +-- .../offering/UpdateServiceOfferingCmd.java | 62 +-- .../admin/vpc/UpdateVPCOfferingCmd.java | 64 +-- .../offering/DomainAndZoneIdResolver.java | 114 ++++++ .../api/response/BackupOfferingResponse.java | 19 + .../cloudstack/backup/BackupManager.java | 2 + .../offering/DomainAndZoneIdResolverTest.java | 149 +++++++ .../backup/BackupOfferingDetailsVO.java | 86 ++++ .../cloudstack/backup/BackupOfferingVO.java | 7 + .../backup/dao/BackupOfferingDaoImpl.java | 23 +- .../backup/dao/BackupOfferingDetailsDao.java | 32 ++ .../dao/BackupOfferingDetailsDaoImpl.java | 101 +++++ ...s-between-management-and-usage-context.xml | 3 +- .../META-INF/db/schema-42210to42300.sql | 10 + .../dao/BackupOfferingDetailsDaoImplTest.java | 251 ++++++++++++ .../hypervisors/ovm3/sonar-project.properties | 2 +- .../management/MockAccountManager.java | 6 + pom.xml | 2 + .../java/com/cloud/acl/DomainChecker.java | 33 ++ .../ConfigurationManagerImpl.java | 47 +-- .../com/cloud/network/vpc/VpcManagerImpl.java | 31 +- .../com/cloud/user/AccountManagerImpl.java | 16 + .../java/com/cloud/utils/DomainHelper.java | 63 +++ .../cloudstack/backup/BackupManagerImpl.java | 117 +++++- .../core/spring-server-core-misc-context.xml | 2 + .../java/com/cloud/acl/DomainCheckerTest.java | 45 +++ .../ConfigurationManagerImplTest.java | 3 + .../com/cloud/vm/UserVmManagerImplTest.java | 3 +- .../cloudstack/backup/BackupManagerTest.java | 366 +++++++++++++++++- .../CreateNetworkOfferingTest.java | 4 + tools/marvin/setup.py | 2 +- ui/src/config/section/offering.js | 6 +- .../views/offering/ImportBackupOffering.vue | 69 +++- 39 files changed, 1610 insertions(+), 316 deletions(-) create mode 100644 api/src/main/java/org/apache/cloudstack/api/command/offering/DomainAndZoneIdResolver.java create mode 100644 api/src/test/java/org/apache/cloudstack/api/command/offering/DomainAndZoneIdResolverTest.java create mode 100644 engine/schema/src/main/java/org/apache/cloudstack/backup/BackupOfferingDetailsVO.java create mode 100644 engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupOfferingDetailsDao.java create mode 100644 engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupOfferingDetailsDaoImpl.java create mode 100644 engine/schema/src/test/java/org/apache/cloudstack/backup/dao/BackupOfferingDetailsDaoImplTest.java create mode 100644 server/src/main/java/com/cloud/utils/DomainHelper.java diff --git a/api/src/main/java/com/cloud/user/AccountService.java b/api/src/main/java/com/cloud/user/AccountService.java index 09fe5ffc0590..8f29a2fbc428 100644 --- a/api/src/main/java/com/cloud/user/AccountService.java +++ b/api/src/main/java/com/cloud/user/AccountService.java @@ -36,6 +36,7 @@ import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; import org.apache.cloudstack.auth.UserTwoFactorAuthenticator; +import org.apache.cloudstack.backup.BackupOffering; public interface AccountService { @@ -115,6 +116,8 @@ User createUser(String userName, String password, String firstName, String lastN void checkAccess(Account account, VpcOffering vof, DataCenter zone) throws PermissionDeniedException; + void checkAccess(Account account, BackupOffering bof) throws PermissionDeniedException; + void checkAccess(User user, ControlledEntity entity); void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) throws PermissionDeniedException; diff --git a/api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java b/api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java index 82a8ec5fe932..fa17df7c6ed4 100644 --- a/api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java +++ b/api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java @@ -27,6 +27,8 @@ import com.cloud.user.User; import com.cloud.utils.component.Adapter; +import org.apache.cloudstack.backup.BackupOffering; + /** * SecurityChecker checks the ownership and access control to objects within */ @@ -145,4 +147,6 @@ boolean checkAccess(Account caller, AccessType accessType, String action, Contro boolean checkAccess(Account account, NetworkOffering nof, DataCenter zone) throws PermissionDeniedException; boolean checkAccess(Account account, VpcOffering vof, DataCenter zone) throws PermissionDeniedException; + + boolean checkAccess(Account account, BackupOffering bof) throws PermissionDeniedException; } diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseBackupListCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseBackupListCmd.java index 0aa8366bcd5c..2a64a1fb6fd8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/BaseBackupListCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/BaseBackupListCmd.java @@ -25,7 +25,7 @@ import org.apache.cloudstack.backup.BackupOffering; import org.apache.cloudstack.context.CallContext; -public abstract class BaseBackupListCmd extends BaseListCmd { +public abstract class BaseBackupListCmd extends BaseListAccountResourcesCmd { protected void setupResponseBackupOfferingsList(final List offerings, final Integer count) { final ListResponse response = new ListResponse<>(); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java index 2e73698e7aa1..5e702585a2c3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java @@ -27,6 +27,7 @@ import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.BackupOfferingResponse; +import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.backup.BackupManager; import org.apache.cloudstack.backup.BackupOffering; @@ -40,6 +41,11 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.commons.collections.CollectionUtils; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; @APICommand(name = "importBackupOffering", description = "Imports a backup offering using a backup provider", @@ -76,6 +82,13 @@ public class ImportBackupOfferingCmd extends BaseAsyncCmd { description = "Whether users are allowed to create adhoc backups and backup schedules", required = true) private Boolean userDrivenBackups; + @Parameter(name = ApiConstants.DOMAIN_ID, + type = CommandType.LIST, + collectionType = CommandType.UUID, + entityType = DomainResponse.class, + description = "the ID of the containing domain(s), null for public offerings") + private List domainIds; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -100,6 +113,15 @@ public Boolean getUserDrivenBackups() { return userDrivenBackups == null ? false : userDrivenBackups; } + public List getDomainIds() { + if (CollectionUtils.isNotEmpty(domainIds)) { + Set set = new LinkedHashSet<>(domainIds); + domainIds.clear(); + domainIds.addAll(set); + } + return domainIds; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/UpdateBackupOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/UpdateBackupOfferingCmd.java index a645b1e0c8db..2f0dd6acd0e1 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/UpdateBackupOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/UpdateBackupOfferingCmd.java @@ -25,19 +25,24 @@ import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.command.offering.DomainAndZoneIdResolver; import org.apache.cloudstack.api.response.BackupOfferingResponse; import org.apache.cloudstack.backup.BackupManager; import org.apache.cloudstack.backup.BackupOffering; import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import com.cloud.exception.InvalidParameterValueException; import com.cloud.user.Account; import com.cloud.utils.exception.CloudRuntimeException; +import java.util.List; +import java.util.function.LongFunction; + @APICommand(name = "updateBackupOffering", description = "Updates a backup offering.", responseObject = BackupOfferingResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.16.0") -public class UpdateBackupOfferingCmd extends BaseCmd { +public class UpdateBackupOfferingCmd extends BaseCmd implements DomainAndZoneIdResolver { @Inject private BackupManager backupManager; @@ -57,6 +62,13 @@ public class UpdateBackupOfferingCmd extends BaseCmd { @Parameter(name = ApiConstants.ALLOW_USER_DRIVEN_BACKUPS, type = CommandType.BOOLEAN, description = "Whether to allow user driven backups or not") private Boolean allowUserDrivenBackups; + @Parameter(name = ApiConstants.DOMAIN_ID, + type = CommandType.STRING, + description = "the ID of the containing domain(s) as comma separated string, public for public offerings", + since = "4.23.0", + length = 4096) + private String domainIds; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -82,7 +94,7 @@ public Boolean getAllowUserDrivenBackups() { @Override public void execute() { try { - if (StringUtils.isAllEmpty(getName(), getDescription()) && getAllowUserDrivenBackups() == null) { + if (StringUtils.isAllEmpty(getName(), getDescription()) && getAllowUserDrivenBackups() == null && CollectionUtils.isEmpty(getDomainIds())) { throw new InvalidParameterValueException(String.format("Can't update Backup Offering [id: %s] because there are no parameters to be updated, at least one of the", "following should be informed: name, description or allowUserDrivenBackups.", id)); } @@ -103,6 +115,18 @@ public void execute() { } } + public List getDomainIds() { + // backupManager may be null in unit tests where the command is spied without injection. + // Avoid creating a method reference to a null receiver which causes NPE. When backupManager + // is null, pass null as the defaultDomainsProvider so resolveDomainIds will simply return + // an empty list or parse the explicit domainIds string. + LongFunction> defaultDomainsProvider = null; + if (backupManager != null) { + defaultDomainsProvider = backupManager::getBackupOfferingDomains; + } + return resolveDomainIds(domainIds, id, defaultDomainsProvider, "backup offering"); + } + @Override public long getEntityOwnerId() { return Account.ACCOUNT_ID_SYSTEM; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java index 9af10262b2d5..e3fac81a7932 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java @@ -16,7 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.admin.network; -import java.util.ArrayList; import java.util.List; import org.apache.cloudstack.api.APICommand; @@ -26,18 +25,16 @@ import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.command.offering.DomainAndZoneIdResolver; import org.apache.cloudstack.api.response.NetworkOfferingResponse; -import org.apache.commons.lang3.StringUtils; -import com.cloud.dc.DataCenter; -import com.cloud.domain.Domain; -import com.cloud.exception.InvalidParameterValueException; + import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; @APICommand(name = "updateNetworkOffering", description = "Updates a network offering.", responseObject = NetworkOfferingResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class UpdateNetworkOfferingCmd extends BaseCmd { +public class UpdateNetworkOfferingCmd extends BaseCmd implements DomainAndZoneIdResolver { ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -129,63 +126,11 @@ public String getTags() { } public List getDomainIds() { - List validDomainIds = new ArrayList<>(); - if (StringUtils.isNotEmpty(domainIds)) { - if (domainIds.contains(",")) { - String[] domains = domainIds.split(","); - for (String domain : domains) { - Domain validDomain = _entityMgr.findByUuid(Domain.class, domain.trim()); - if (validDomain != null) { - validDomainIds.add(validDomain.getId()); - } else { - throw new InvalidParameterValueException("Failed to create network offering because invalid domain has been specified."); - } - } - } else { - domainIds = domainIds.trim(); - if (!domainIds.matches("public")) { - Domain validDomain = _entityMgr.findByUuid(Domain.class, domainIds.trim()); - if (validDomain != null) { - validDomainIds.add(validDomain.getId()); - } else { - throw new InvalidParameterValueException("Failed to create network offering because invalid domain has been specified."); - } - } - } - } else { - validDomainIds.addAll(_configService.getNetworkOfferingDomains(id)); - } - return validDomainIds; + return resolveDomainIds(domainIds, id, _configService::getNetworkOfferingDomains, "network offering"); } public List getZoneIds() { - List validZoneIds = new ArrayList<>(); - if (StringUtils.isNotEmpty(zoneIds)) { - if (zoneIds.contains(",")) { - String[] zones = zoneIds.split(","); - for (String zone : zones) { - DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zone.trim()); - if (validZone != null) { - validZoneIds.add(validZone.getId()); - } else { - throw new InvalidParameterValueException("Failed to create network offering because invalid zone has been specified."); - } - } - } else { - zoneIds = zoneIds.trim(); - if (!zoneIds.matches("all")) { - DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zoneIds.trim()); - if (validZone != null) { - validZoneIds.add(validZone.getId()); - } else { - throw new InvalidParameterValueException("Failed to create network offering because invalid zone has been specified."); - } - } - } - } else { - validZoneIds.addAll(_configService.getNetworkOfferingZones(id)); - } - return validZoneIds; + return resolveZoneIds(zoneIds, id, _configService::getNetworkOfferingZones, "network offering"); } ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java index 2f07f85f9836..917d7ff42d82 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java @@ -16,7 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.admin.offering; -import java.util.ArrayList; import java.util.List; import com.cloud.offering.DiskOffering.State; @@ -27,19 +26,18 @@ import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.command.offering.DomainAndZoneIdResolver; import org.apache.cloudstack.api.response.DiskOfferingResponse; import org.apache.commons.lang3.EnumUtils; import org.apache.commons.lang3.StringUtils; -import com.cloud.dc.DataCenter; -import com.cloud.domain.Domain; import com.cloud.exception.InvalidParameterValueException; import com.cloud.offering.DiskOffering; import com.cloud.user.Account; @APICommand(name = "updateDiskOffering", description = "Updates a disk offering.", responseObject = DiskOfferingResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class UpdateDiskOfferingCmd extends BaseCmd { +public class UpdateDiskOfferingCmd extends BaseCmd implements DomainAndZoneIdResolver { ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -151,63 +149,11 @@ public Boolean getDisplayOffering() { } public List getDomainIds() { - List validDomainIds = new ArrayList<>(); - if (StringUtils.isNotEmpty(domainIds)) { - if (domainIds.contains(",")) { - String[] domains = domainIds.split(","); - for (String domain : domains) { - Domain validDomain = _entityMgr.findByUuid(Domain.class, domain.trim()); - if (validDomain != null) { - validDomainIds.add(validDomain.getId()); - } else { - throw new InvalidParameterValueException("Failed to create disk offering because invalid domain has been specified."); - } - } - } else { - domainIds = domainIds.trim(); - if (!domainIds.matches("public")) { - Domain validDomain = _entityMgr.findByUuid(Domain.class, domainIds.trim()); - if (validDomain != null) { - validDomainIds.add(validDomain.getId()); - } else { - throw new InvalidParameterValueException("Failed to create disk offering because invalid domain has been specified."); - } - } - } - } else { - validDomainIds.addAll(_configService.getDiskOfferingDomains(id)); - } - return validDomainIds; + return resolveDomainIds(domainIds, id, _configService::getDiskOfferingDomains, "disk offering"); } public List getZoneIds() { - List validZoneIds = new ArrayList<>(); - if (StringUtils.isNotEmpty(zoneIds)) { - if (zoneIds.contains(",")) { - String[] zones = zoneIds.split(","); - for (String zone : zones) { - DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zone.trim()); - if (validZone != null) { - validZoneIds.add(validZone.getId()); - } else { - throw new InvalidParameterValueException("Failed to create disk offering because invalid zone has been specified."); - } - } - } else { - zoneIds = zoneIds.trim(); - if (!zoneIds.matches("all")) { - DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zoneIds.trim()); - if (validZone != null) { - validZoneIds.add(validZone.getId()); - } else { - throw new InvalidParameterValueException("Failed to create disk offering because invalid zone has been specified."); - } - } - } - } else { - validZoneIds.addAll(_configService.getDiskOfferingZones(id)); - } - return validZoneIds; + return resolveZoneIds(zoneIds, id, _configService::getDiskOfferingZones, "disk offering"); } public String getTags() { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java index 4027662574ab..3a6d6639a5b4 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java @@ -16,7 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.admin.offering; -import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -28,19 +27,18 @@ import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.command.offering.DomainAndZoneIdResolver; import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.commons.lang3.EnumUtils; import org.apache.commons.lang3.StringUtils; -import com.cloud.dc.DataCenter; -import com.cloud.domain.Domain; import com.cloud.exception.InvalidParameterValueException; import com.cloud.offering.ServiceOffering; import com.cloud.user.Account; @APICommand(name = "updateServiceOffering", description = "Updates a service offering.", responseObject = ServiceOfferingResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class UpdateServiceOfferingCmd extends BaseCmd { +public class UpdateServiceOfferingCmd extends BaseCmd implements DomainAndZoneIdResolver { ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -130,63 +128,11 @@ public Integer getSortKey() { } public List getDomainIds() { - List validDomainIds = new ArrayList<>(); - if (StringUtils.isNotEmpty(domainIds)) { - if (domainIds.contains(",")) { - String[] domains = domainIds.split(","); - for (String domain : domains) { - Domain validDomain = _entityMgr.findByUuid(Domain.class, domain.trim()); - if (validDomain != null) { - validDomainIds.add(validDomain.getId()); - } else { - throw new InvalidParameterValueException("Failed to create service offering because invalid domain has been specified."); - } - } - } else { - domainIds = domainIds.trim(); - if (!domainIds.matches("public")) { - Domain validDomain = _entityMgr.findByUuid(Domain.class, domainIds.trim()); - if (validDomain != null) { - validDomainIds.add(validDomain.getId()); - } else { - throw new InvalidParameterValueException("Failed to create service offering because invalid domain has been specified."); - } - } - } - } else { - validDomainIds.addAll(_configService.getServiceOfferingDomains(id)); - } - return validDomainIds; + return resolveDomainIds(domainIds, id, _configService::getServiceOfferingDomains, "service offering"); } public List getZoneIds() { - List validZoneIds = new ArrayList<>(); - if (StringUtils.isNotEmpty(zoneIds)) { - if (zoneIds.contains(",")) { - String[] zones = zoneIds.split(","); - for (String zone : zones) { - DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zone.trim()); - if (validZone != null) { - validZoneIds.add(validZone.getId()); - } else { - throw new InvalidParameterValueException("Failed to create service offering because invalid zone has been specified."); - } - } - } else { - zoneIds = zoneIds.trim(); - if (!zoneIds.matches("all")) { - DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zoneIds.trim()); - if (validZone != null) { - validZoneIds.add(validZone.getId()); - } else { - throw new InvalidParameterValueException("Failed to create service offering because invalid zone has been specified."); - } - } - } - } else { - validZoneIds.addAll(_configService.getServiceOfferingZones(id)); - } - return validZoneIds; + return resolveZoneIds(zoneIds, id, _configService::getServiceOfferingZones, "service offering"); } public String getStorageTags() { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java index b8a8077b30b5..300584428eae 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java @@ -16,7 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.admin.vpc; -import java.util.ArrayList; import java.util.List; import org.apache.cloudstack.api.APICommand; @@ -26,19 +25,16 @@ import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.command.offering.DomainAndZoneIdResolver; import org.apache.cloudstack.api.response.VpcOfferingResponse; -import org.apache.commons.lang3.StringUtils; -import com.cloud.dc.DataCenter; -import com.cloud.domain.Domain; import com.cloud.event.EventTypes; -import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.vpc.VpcOffering; import com.cloud.user.Account; @APICommand(name = "updateVPCOffering", description = "Updates VPC offering", responseObject = VpcOfferingResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class UpdateVPCOfferingCmd extends BaseAsyncCmd { +public class UpdateVPCOfferingCmd extends BaseAsyncCmd implements DomainAndZoneIdResolver { ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -92,63 +88,11 @@ public String getState() { } public List getDomainIds() { - List validDomainIds = new ArrayList<>(); - if (StringUtils.isNotEmpty(domainIds)) { - if (domainIds.contains(",")) { - String[] domains = domainIds.split(","); - for (String domain : domains) { - Domain validDomain = _entityMgr.findByUuid(Domain.class, domain.trim()); - if (validDomain != null) { - validDomainIds.add(validDomain.getId()); - } else { - throw new InvalidParameterValueException("Failed to create VPC offering because invalid domain has been specified."); - } - } - } else { - domainIds = domainIds.trim(); - if (!domainIds.matches("public")) { - Domain validDomain = _entityMgr.findByUuid(Domain.class, domainIds.trim()); - if (validDomain != null) { - validDomainIds.add(validDomain.getId()); - } else { - throw new InvalidParameterValueException("Failed to create VPC offering because invalid domain has been specified."); - } - } - } - } else { - validDomainIds.addAll(_vpcProvSvc.getVpcOfferingDomains(id)); - } - return validDomainIds; + return resolveDomainIds(domainIds, id, _vpcProvSvc::getVpcOfferingDomains, "VPC offering"); } public List getZoneIds() { - List validZoneIds = new ArrayList<>(); - if (StringUtils.isNotEmpty(zoneIds)) { - if (zoneIds.contains(",")) { - String[] zones = zoneIds.split(","); - for (String zone : zones) { - DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zone.trim()); - if (validZone != null) { - validZoneIds.add(validZone.getId()); - } else { - throw new InvalidParameterValueException("Failed to create VPC offering because invalid zone has been specified."); - } - } - } else { - zoneIds = zoneIds.trim(); - if (!zoneIds.matches("all")) { - DataCenter validZone = _entityMgr.findByUuid(DataCenter.class, zoneIds.trim()); - if (validZone != null) { - validZoneIds.add(validZone.getId()); - } else { - throw new InvalidParameterValueException("Failed to create VPC offering because invalid zone has been specified."); - } - } - } - } else { - validZoneIds.addAll(_vpcProvSvc.getVpcOfferingZones(id)); - } - return validZoneIds; + return resolveZoneIds(zoneIds, id, _vpcProvSvc::getVpcOfferingZones, "VPC offering"); } public Integer getSortKey() { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/offering/DomainAndZoneIdResolver.java b/api/src/main/java/org/apache/cloudstack/api/command/offering/DomainAndZoneIdResolver.java new file mode 100644 index 000000000000..b302c4a9beec --- /dev/null +++ b/api/src/main/java/org/apache/cloudstack/api/command/offering/DomainAndZoneIdResolver.java @@ -0,0 +1,114 @@ +// 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.offering; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.LongFunction; + +import com.cloud.dc.DataCenter; +import com.cloud.domain.Domain; +import com.cloud.exception.InvalidParameterValueException; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * Helper for commands that accept a domainIds or zoneIds string and need to + * resolve them to lists of IDs, falling back to an offering-specific + * default provider. + */ +public interface DomainAndZoneIdResolver { + /** + * Parse the provided domainIds string and return a list of domain IDs. + * If domainIds is empty, the defaultDomainsProvider will be invoked with the + * provided resource id to obtain the current domains. + */ + default List resolveDomainIds(final String domainIds, final Long id, final LongFunction> defaultDomainsProvider, final String resourceTypeName) { + final List validDomainIds = new ArrayList<>(); + final BaseCmd base = (BaseCmd) this; + final Logger logger = LogManager.getLogger(base.getClass()); + + if (StringUtils.isEmpty(domainIds)) { + if (defaultDomainsProvider != null) { + final List defaults = defaultDomainsProvider.apply(id); + if (defaults != null) { + validDomainIds.addAll(defaults); + } + } + return validDomainIds; + } + + final String[] domains = domainIds.split(","); + final String type = (resourceTypeName == null || resourceTypeName.isEmpty()) ? "offering" : resourceTypeName; + for (String domain : domains) { + final String trimmed = domain == null ? "" : domain.trim(); + if (trimmed.isEmpty() || "public".equalsIgnoreCase(trimmed)) { + continue; + } + + final Domain validDomain = base._entityMgr.findByUuid(Domain.class, trimmed); + if (validDomain == null) { + logger.warn("Invalid domain specified for {}", type); + throw new InvalidParameterValueException("Failed to create " + type + " because invalid domain has been specified."); + } + validDomainIds.add(validDomain.getId()); + } + + return validDomainIds; + } + + /** + * Parse the provided zoneIds string and return a list of zone IDs. + * If zoneIds is empty, the defaultZonesProvider will be invoked with the + * provided resource id to obtain the current zones. + */ + default List resolveZoneIds(final String zoneIds, final Long id, final LongFunction> defaultZonesProvider, final String resourceTypeName) { + final List validZoneIds = new ArrayList<>(); + final BaseCmd base = (BaseCmd) this; + final Logger logger = LogManager.getLogger(base.getClass()); + + if (StringUtils.isEmpty(zoneIds)) { + if (defaultZonesProvider != null) { + final List defaults = defaultZonesProvider.apply(id); + if (defaults != null) { + validZoneIds.addAll(defaults); + } + } + return validZoneIds; + } + + final String[] zones = zoneIds.split(","); + final String type = (resourceTypeName == null || resourceTypeName.isEmpty()) ? "offering" : resourceTypeName; + for (String zone : zones) { + final String trimmed = zone == null ? "" : zone.trim(); + if (trimmed.isEmpty() || "all".equalsIgnoreCase(trimmed)) { + continue; + } + + final DataCenter validZone = base._entityMgr.findByUuid(DataCenter.class, trimmed); + if (validZone == null) { + logger.warn("Invalid zone specified for {}: {}", type, trimmed); + throw new InvalidParameterValueException("Failed to create " + type + " because invalid zone has been specified."); + } + validZoneIds.add(validZone.getId()); + } + + return validZoneIds; + } +} diff --git a/api/src/main/java/org/apache/cloudstack/api/response/BackupOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/BackupOfferingResponse.java index b3a7d0362198..c4f3ee31dadc 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/BackupOfferingResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/BackupOfferingResponse.java @@ -61,6 +61,16 @@ public class BackupOfferingResponse extends BaseResponse { @Param(description = "Zone name") private String zoneName; + @SerializedName(ApiConstants.DOMAIN_ID) + @Param(description = "the domain ID(s) this backup offering belongs to.", + since = "4.23.0") + private String domainId; + + @SerializedName(ApiConstants.DOMAIN) + @Param(description = "the domain name(s) this backup offering belongs to.", + since = "4.23.0") + private String domain; + @SerializedName(ApiConstants.CROSS_ZONE_INSTANCE_CREATION) @Param(description = "the backups with this offering can be used to create Instances on all Zones", since = "4.22.0") private Boolean crossZoneInstanceCreation; @@ -108,4 +118,13 @@ public void setCrossZoneInstanceCreation(Boolean crossZoneInstanceCreation) { public void setCreated(Date created) { this.created = created; } + + public void setDomainId(String domainId) { + this.domainId = domainId; + } + + public void setDomain(String domain) { + this.domain = domain; + } + } diff --git a/api/src/main/java/org/apache/cloudstack/backup/BackupManager.java b/api/src/main/java/org/apache/cloudstack/backup/BackupManager.java index db051313d962..cbaf61405970 100644 --- a/api/src/main/java/org/apache/cloudstack/backup/BackupManager.java +++ b/api/src/main/java/org/apache/cloudstack/backup/BackupManager.java @@ -136,6 +136,8 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer */ BackupOffering importBackupOffering(final ImportBackupOfferingCmd cmd); + List getBackupOfferingDomains(final Long offeringId); + /** * List backup offerings * @param ListBackupOfferingsCmd API cmd diff --git a/api/src/test/java/org/apache/cloudstack/api/command/offering/DomainAndZoneIdResolverTest.java b/api/src/test/java/org/apache/cloudstack/api/command/offering/DomainAndZoneIdResolverTest.java new file mode 100644 index 000000000000..e679bbf2d1f1 --- /dev/null +++ b/api/src/test/java/org/apache/cloudstack/api/command/offering/DomainAndZoneIdResolverTest.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.offering; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.function.LongFunction; + +import com.cloud.dc.DataCenter; +import com.cloud.domain.Domain; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.utils.db.EntityManager; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.ServerApiException; +import org.junit.Assert; +import org.junit.Test; + +public class DomainAndZoneIdResolverTest { + static class TestCmd extends BaseCmd implements DomainAndZoneIdResolver { + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { + // No implementation needed for tests + } + + @Override + public String getCommandName() { + return "test"; + } + + @Override + public long getEntityOwnerId() { + return 1L; + } + } + + private void setEntityMgr(final BaseCmd cmd, final EntityManager entityMgr) throws Exception { + Field f = BaseCmd.class.getDeclaredField("_entityMgr"); + f.setAccessible(true); + f.set(cmd, entityMgr); + } + + @Test + public void resolveDomainIds_usesDefaultProviderWhenEmpty() { + TestCmd cmd = new TestCmd(); + + final LongFunction> defaultsProvider = id -> Arrays.asList(100L, 200L); + + List result = cmd.resolveDomainIds("", 42L, defaultsProvider, "offering"); + Assert.assertEquals(Arrays.asList(100L, 200L), result); + } + + @Test + public void resolveDomainIds_resolvesValidUuids() throws Exception { + TestCmd cmd = new TestCmd(); + + EntityManager em = mock(EntityManager.class); + setEntityMgr(cmd, em); + + Domain d1 = mock(Domain.class); + when(d1.getId()).thenReturn(10L); + Domain d2 = mock(Domain.class); + when(d2.getId()).thenReturn(20L); + + when(em.findByUuid(Domain.class, "uuid1")).thenReturn(d1); + when(em.findByUuid(Domain.class, "uuid2")).thenReturn(d2); + + List ids = cmd.resolveDomainIds("uuid1, public, uuid2", null, null, "template"); + Assert.assertEquals(Arrays.asList(10L, 20L), ids); + } + + @Test + public void resolveDomainIds_invalidUuid_throws() throws Exception { + TestCmd cmd = new TestCmd(); + + EntityManager em = mock(EntityManager.class); + setEntityMgr(cmd, em); + + when(em.findByUuid(Domain.class, "bad-uuid")).thenReturn(null); + + Assert.assertThrows(InvalidParameterValueException.class, + () -> cmd.resolveDomainIds("bad-uuid", null, null, "offering")); + } + + @Test + public void resolveZoneIds_usesDefaultProviderWhenEmpty() { + TestCmd cmd = new TestCmd(); + + final LongFunction> defaultsProvider = id -> Collections.singletonList(300L); + + List result = cmd.resolveZoneIds("", 99L, defaultsProvider, "offering"); + Assert.assertEquals(Collections.singletonList(300L), result); + } + + @Test + public void resolveZoneIds_resolvesValidUuids() throws Exception { + TestCmd cmd = new TestCmd(); + + EntityManager em = mock(EntityManager.class); + setEntityMgr(cmd, em); + + DataCenter z1 = mock(DataCenter.class); + when(z1.getId()).thenReturn(30L); + DataCenter z2 = mock(DataCenter.class); + when(z2.getId()).thenReturn(40L); + + when(em.findByUuid(DataCenter.class, "zone-1")).thenReturn(z1); + when(em.findByUuid(DataCenter.class, "zone-2")).thenReturn(z2); + + List ids = cmd.resolveZoneIds("zone-1, all, zone-2", null, null, "service"); + Assert.assertEquals(Arrays.asList(30L, 40L), ids); + } + + @Test + public void resolveZoneIds_invalidUuid_throws() throws Exception { + TestCmd cmd = new TestCmd(); + + EntityManager em = mock(EntityManager.class); + setEntityMgr(cmd, em); + + when(em.findByUuid(DataCenter.class, "bad-zone")).thenReturn(null); + + Assert.assertThrows(InvalidParameterValueException.class, + () -> cmd.resolveZoneIds("bad-zone", null, null, "offering")); + } +} diff --git a/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupOfferingDetailsVO.java b/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupOfferingDetailsVO.java new file mode 100644 index 000000000000..6bdf7602a9d4 --- /dev/null +++ b/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupOfferingDetailsVO.java @@ -0,0 +1,86 @@ +// 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.backup; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "backup_offering_details") +public class BackupOfferingDetailsVO implements ResourceDetail { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "backup_offering_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Column(name = "value") + private String value; + + @Column(name = "display") + private boolean display = true; + + protected BackupOfferingDetailsVO() { + } + + public BackupOfferingDetailsVO(long backupOfferingId, String name, String value, boolean display) { + this.resourceId = backupOfferingId; + this.name = name; + this.value = value; + this.display = display; + } + + @Override + public long getResourceId() { + return resourceId; + } + + public void setResourceId(long backupOfferingId) { + this.resourceId = backupOfferingId; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getId() { + return id; + } + + @Override + public boolean isDisplay() { + return display; + } +} diff --git a/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupOfferingVO.java b/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupOfferingVO.java index d30385af575d..ebeb7d4a2d59 100644 --- a/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupOfferingVO.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupOfferingVO.java @@ -17,6 +17,8 @@ package org.apache.cloudstack.backup; +import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils; + import java.util.Date; import java.util.UUID; @@ -131,4 +133,9 @@ public void setDescription(String description) { public Date getCreated() { return created; } + + @Override + public String toString() { + return String.format("Backup offering %s.", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "name", "uuid")); + } } diff --git a/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupOfferingDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupOfferingDaoImpl.java index a41e4e70d339..708faeef4643 100644 --- a/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupOfferingDaoImpl.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupOfferingDaoImpl.java @@ -20,6 +20,8 @@ import javax.annotation.PostConstruct; import javax.inject.Inject; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; import org.apache.cloudstack.api.response.BackupOfferingResponse; import org.apache.cloudstack.backup.BackupOffering; import org.apache.cloudstack.backup.BackupOfferingVO; @@ -30,10 +32,16 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import java.util.List; + public class BackupOfferingDaoImpl extends GenericDaoBase implements BackupOfferingDao { @Inject DataCenterDao dataCenterDao; + @Inject + BackupOfferingDetailsDao backupOfferingDetailsDao; + @Inject + DomainDao domainDao; private SearchBuilder backupPoliciesSearch; @@ -51,8 +59,9 @@ protected void init() { @Override public BackupOfferingResponse newBackupOfferingResponse(BackupOffering offering, Boolean crossZoneInstanceCreation) { - DataCenterVO zone = dataCenterDao.findById(offering.getZoneId()); + DataCenterVO zone = dataCenterDao.findById(offering.getZoneId()); + List domainIds = backupOfferingDetailsDao.findDomainIds(offering.getId()); BackupOfferingResponse response = new BackupOfferingResponse(); response.setId(offering.getUuid()); response.setName(offering.getName()); @@ -64,6 +73,18 @@ public BackupOfferingResponse newBackupOfferingResponse(BackupOffering offering, response.setZoneId(zone.getUuid()); response.setZoneName(zone.getName()); } + if (domainIds != null && !domainIds.isEmpty()) { + String domainUUIDs = domainIds.stream().map(Long::valueOf).map(domainId -> { + DomainVO domain = domainDao.findById(domainId); + return domain != null ? domain.getUuid() : ""; + }).filter(name -> !name.isEmpty()).reduce((a, b) -> a + "," + b).orElse(""); + String domainNames = domainIds.stream().map(Long::valueOf).map(domainId -> { + DomainVO domain = domainDao.findById(domainId); + return domain != null ? domain.getName() : ""; + }).filter(name -> !name.isEmpty()).reduce((a, b) -> a + "," + b).orElse(""); + response.setDomain(domainNames); + response.setDomainId(domainUUIDs); + } if (crossZoneInstanceCreation) { response.setCrossZoneInstanceCreation(true); } diff --git a/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupOfferingDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupOfferingDetailsDao.java new file mode 100644 index 000000000000..390fcba1e0e7 --- /dev/null +++ b/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupOfferingDetailsDao.java @@ -0,0 +1,32 @@ +// 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.backup.dao; + +import java.util.List; + +import org.apache.cloudstack.backup.BackupOfferingDetailsVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; + +import com.cloud.utils.db.GenericDao; + +public interface BackupOfferingDetailsDao extends GenericDao, ResourceDetailsDao { + List findDomainIds(final long resourceId); + List findZoneIds(final long resourceId); + String getDetail(Long backupOfferingId, String key); + List findOfferingIdsByDomainIds(List domainIds); + void updateBackupOfferingDomainIdsDetail(long backupOfferingId, List filteredDomainIds); +} diff --git a/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupOfferingDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupOfferingDetailsDaoImpl.java new file mode 100644 index 000000000000..f052c93f9817 --- /dev/null +++ b/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupOfferingDetailsDaoImpl.java @@ -0,0 +1,101 @@ +// 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.backup.dao; + + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import com.cloud.utils.db.DB; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.backup.BackupOfferingDetailsVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.springframework.stereotype.Component; + +@Component +public class BackupOfferingDetailsDaoImpl extends ResourceDetailsDaoBase implements BackupOfferingDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value, boolean display) { + super.addDetail(new BackupOfferingDetailsVO(resourceId, key, value, display)); + } + + @Override + public List findDomainIds(long resourceId) { + final List domainIds = new ArrayList<>(); + for (final BackupOfferingDetailsVO detail: findDetails(resourceId, ApiConstants.DOMAIN_ID)) { + final Long domainId = Long.valueOf(detail.getValue()); + if (domainId > 0) { + domainIds.add(domainId); + } + } + return domainIds; + } + + @Override + public List findZoneIds(long resourceId) { + final List zoneIds = new ArrayList<>(); + for (final BackupOfferingDetailsVO detail: findDetails(resourceId, ApiConstants.ZONE_ID)) { + final Long zoneId = Long.valueOf(detail.getValue()); + if (zoneId > 0) { + zoneIds.add(zoneId); + } + } + return zoneIds; + } + + @Override + public String getDetail(Long backupOfferingId, String key) { + String detailValue = null; + BackupOfferingDetailsVO backupOfferingDetail = findDetail(backupOfferingId, key); + if (backupOfferingDetail != null) { + detailValue = backupOfferingDetail.getValue(); + } + return detailValue; + } + + @Override + public List findOfferingIdsByDomainIds(List domainIds) { + Object[] dIds = domainIds.stream().map(s -> String.valueOf(s)).collect(Collectors.toList()).toArray(); + return findResourceIdsByNameAndValueIn("domainid", dIds); + } + + @DB + @Override + public void updateBackupOfferingDomainIdsDetail(long backupOfferingId, List filteredDomainIds) { + SearchBuilder sb = createSearchBuilder(); + List detailsVO = new ArrayList<>(); + sb.and("offeringId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); + sb.and("detailName", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.done(); + SearchCriteria sc = sb.create(); + sc.setParameters("offeringId", String.valueOf(backupOfferingId)); + sc.setParameters("detailName", ApiConstants.DOMAIN_ID); + remove(sc); + for (Long domainId : filteredDomainIds) { + detailsVO.add(new BackupOfferingDetailsVO(backupOfferingId, ApiConstants.DOMAIN_ID, String.valueOf(domainId), false)); + } + if (!detailsVO.isEmpty()) { + for (BackupOfferingDetailsVO detailVO : detailsVO) { + persist(detailVO); + } + } + } +} diff --git a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-common-daos-between-management-and-usage-context.xml b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-common-daos-between-management-and-usage-context.xml index d308a9e5aaf9..1846c3c62a0e 100644 --- a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-common-daos-between-management-and-usage-context.xml +++ b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-common-daos-between-management-and-usage-context.xml @@ -71,6 +71,7 @@ - + + diff --git a/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql b/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql index 07f394b19c90..d330ecd0c0d5 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql @@ -19,6 +19,16 @@ -- Schema upgrade from 4.22.1.0 to 4.23.0.0 --; +CREATE TABLE `cloud`.`backup_offering_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `backup_offering_id` bigint unsigned NOT NULL COMMENT 'Backup offering id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + `display` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Should detail be displayed to the end user', + PRIMARY KEY (`id`), + CONSTRAINT `fk_offering_details__backup_offering_id` FOREIGN KEY `fk_offering_details__backup_offering_id`(`backup_offering_id`) REFERENCES `backup_offering`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + -- Update value to random for the config 'vm.allocation.algorithm' or 'volume.allocation.algorithm' if configured as userconcentratedpod_random -- Update value to firstfit for the config 'vm.allocation.algorithm' or 'volume.allocation.algorithm' if configured as userconcentratedpod_firstfit UPDATE `cloud`.`configuration` SET value='random' WHERE name IN ('vm.allocation.algorithm', 'volume.allocation.algorithm') AND value='userconcentratedpod_random'; diff --git a/engine/schema/src/test/java/org/apache/cloudstack/backup/dao/BackupOfferingDetailsDaoImplTest.java b/engine/schema/src/test/java/org/apache/cloudstack/backup/dao/BackupOfferingDetailsDaoImplTest.java new file mode 100644 index 000000000000..fc8f2d0fcf71 --- /dev/null +++ b/engine/schema/src/test/java/org/apache/cloudstack/backup/dao/BackupOfferingDetailsDaoImplTest.java @@ -0,0 +1,251 @@ +// 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.backup.dao; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.backup.BackupOfferingDetailsVO; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.mockito.InjectMocks; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; + +import com.cloud.utils.db.SearchCriteria; + +@RunWith(MockitoJUnitRunner.class) +public class BackupOfferingDetailsDaoImplTest { + + @Spy + @InjectMocks + private BackupOfferingDetailsDaoImpl backupOfferingDetailsDao; + + private static final long RESOURCE_ID = 1L; + private static final long OFFERING_ID = 100L; + private static final String TEST_KEY = "testKey"; + private static final String TEST_VALUE = "testValue"; + + @Test + public void testAddDetail() { + BackupOfferingDetailsVO detailVO = new BackupOfferingDetailsVO(RESOURCE_ID, TEST_KEY, TEST_VALUE, true); + + Assert.assertEquals("Resource ID should match", RESOURCE_ID, detailVO.getResourceId()); + Assert.assertEquals("Detail name/key should match", TEST_KEY, detailVO.getName()); + Assert.assertEquals("Detail value should match", TEST_VALUE, detailVO.getValue()); + Assert.assertTrue("Display flag should be true", detailVO.isDisplay()); + + BackupOfferingDetailsVO detailVOHidden = new BackupOfferingDetailsVO(RESOURCE_ID, "hiddenKey", "hiddenValue", false); + Assert.assertFalse("Display flag should be false", detailVOHidden.isDisplay()); + } + + @Test + public void testFindDomainIdsWithMultipleDomains() { + List mockDetails = Arrays.asList( + createDetailVO(RESOURCE_ID, ApiConstants.DOMAIN_ID, "1", false), + createDetailVO(RESOURCE_ID, ApiConstants.DOMAIN_ID, "2", false), + createDetailVO(RESOURCE_ID, ApiConstants.DOMAIN_ID, "3", false) + ); + + Mockito.doReturn(mockDetails).when(backupOfferingDetailsDao) + .findDetails(RESOURCE_ID, ApiConstants.DOMAIN_ID); + + List domainIds = backupOfferingDetailsDao.findDomainIds(RESOURCE_ID); + + Assert.assertNotNull(domainIds); + Assert.assertEquals(3, domainIds.size()); + Assert.assertEquals(Arrays.asList(1L, 2L, 3L), domainIds); + } + + @Test + public void testFindDomainIdsWithEmptyList() { + Mockito.doReturn(Collections.emptyList()).when(backupOfferingDetailsDao) + .findDetails(RESOURCE_ID, ApiConstants.DOMAIN_ID); + + List domainIds = backupOfferingDetailsDao.findDomainIds(RESOURCE_ID); + + Assert.assertNotNull(domainIds); + Assert.assertTrue(domainIds.isEmpty()); + } + + @Test + public void testFindDomainIdsExcludesZeroOrNegativeValues() { + List mockDetails = Arrays.asList( + createDetailVO(RESOURCE_ID, ApiConstants.DOMAIN_ID, "1", false), + createDetailVO(RESOURCE_ID, ApiConstants.DOMAIN_ID, "0", false), + createDetailVO(RESOURCE_ID, ApiConstants.DOMAIN_ID, "-1", false), + createDetailVO(RESOURCE_ID, ApiConstants.DOMAIN_ID, "2", false) + ); + + Mockito.doReturn(mockDetails).when(backupOfferingDetailsDao) + .findDetails(RESOURCE_ID, ApiConstants.DOMAIN_ID); + + List domainIds = backupOfferingDetailsDao.findDomainIds(RESOURCE_ID); + + Assert.assertNotNull(domainIds); + Assert.assertEquals(2, domainIds.size()); + Assert.assertEquals(Arrays.asList(1L, 2L), domainIds); + } + + @Test + public void testFindZoneIdsWithMultipleZones() { + List mockDetails = Arrays.asList( + createDetailVO(RESOURCE_ID, ApiConstants.ZONE_ID, "10", false), + createDetailVO(RESOURCE_ID, ApiConstants.ZONE_ID, "20", false), + createDetailVO(RESOURCE_ID, ApiConstants.ZONE_ID, "30", false) + ); + + Mockito.doReturn(mockDetails).when(backupOfferingDetailsDao) + .findDetails(RESOURCE_ID, ApiConstants.ZONE_ID); + + List zoneIds = backupOfferingDetailsDao.findZoneIds(RESOURCE_ID); + + Assert.assertNotNull(zoneIds); + Assert.assertEquals(3, zoneIds.size()); + Assert.assertEquals(Arrays.asList(10L, 20L, 30L), zoneIds); + } + + @Test + public void testFindZoneIdsWithEmptyList() { + Mockito.doReturn(Collections.emptyList()).when(backupOfferingDetailsDao) + .findDetails(RESOURCE_ID, ApiConstants.ZONE_ID); + + List zoneIds = backupOfferingDetailsDao.findZoneIds(RESOURCE_ID); + + Assert.assertNotNull(zoneIds); + Assert.assertTrue(zoneIds.isEmpty()); + } + + @Test + public void testFindZoneIdsExcludesZeroOrNegativeValues() { + List mockDetails = Arrays.asList( + createDetailVO(RESOURCE_ID, ApiConstants.ZONE_ID, "10", false), + createDetailVO(RESOURCE_ID, ApiConstants.ZONE_ID, "0", false), + createDetailVO(RESOURCE_ID, ApiConstants.ZONE_ID, "-5", false), + createDetailVO(RESOURCE_ID, ApiConstants.ZONE_ID, "20", false) + ); + + Mockito.doReturn(mockDetails).when(backupOfferingDetailsDao) + .findDetails(RESOURCE_ID, ApiConstants.ZONE_ID); + + List zoneIds = backupOfferingDetailsDao.findZoneIds(RESOURCE_ID); + + Assert.assertNotNull(zoneIds); + Assert.assertEquals(2, zoneIds.size()); + Assert.assertEquals(Arrays.asList(10L, 20L), zoneIds); + } + + @Test + public void testGetDetailWhenDetailExists() { + BackupOfferingDetailsVO mockDetail = createDetailVO(OFFERING_ID, TEST_KEY, TEST_VALUE, true); + + Mockito.doReturn(mockDetail).when(backupOfferingDetailsDao) + .findDetail(OFFERING_ID, TEST_KEY); + + String detailValue = backupOfferingDetailsDao.getDetail(OFFERING_ID, TEST_KEY); + + Assert.assertNotNull(detailValue); + Assert.assertEquals(TEST_VALUE, detailValue); + } + + @Test + public void testGetDetailWhenDetailDoesNotExist() { + Mockito.doReturn(null).when(backupOfferingDetailsDao) + .findDetail(OFFERING_ID, TEST_KEY); + + String detailValue = backupOfferingDetailsDao.getDetail(OFFERING_ID, TEST_KEY); + + Assert.assertNull(detailValue); + } + + @Test + public void testFindOfferingIdsByDomainIds() { + List domainIds = Arrays.asList(1L, 2L, 3L); + List expectedOfferingIds = Arrays.asList(100L, 101L, 102L); + + Mockito.doReturn(expectedOfferingIds).when(backupOfferingDetailsDao) + .findResourceIdsByNameAndValueIn(Mockito.eq("domainid"), Mockito.any(Object[].class)); + + List offeringIds = backupOfferingDetailsDao.findOfferingIdsByDomainIds(domainIds); + + Assert.assertNotNull(offeringIds); + Assert.assertEquals(expectedOfferingIds, offeringIds); + Mockito.verify(backupOfferingDetailsDao).findResourceIdsByNameAndValueIn( + Mockito.eq("domainid"), Mockito.any(Object[].class)); + } + + @Test + public void testFindOfferingIdsByDomainIdsWithEmptyList() { + List domainIds = Collections.emptyList(); + List expectedOfferingIds = Collections.emptyList(); + + Mockito.doReturn(expectedOfferingIds).when(backupOfferingDetailsDao) + .findResourceIdsByNameAndValueIn(Mockito.eq("domainid"), Mockito.any(Object[].class)); + + List offeringIds = backupOfferingDetailsDao.findOfferingIdsByDomainIds(domainIds); + + Assert.assertNotNull(offeringIds); + Assert.assertTrue(offeringIds.isEmpty()); + } + + @Test + @SuppressWarnings("unchecked") + public void testUpdateBackupOfferingDomainIdsDetail() { + List newDomainIds = Arrays.asList(1L, 2L, 3L); + + Mockito.doReturn(0).when(backupOfferingDetailsDao).remove(Mockito.any(SearchCriteria.class)); + Mockito.doReturn(null).when(backupOfferingDetailsDao).persist(Mockito.any(BackupOfferingDetailsVO.class)); + + backupOfferingDetailsDao.updateBackupOfferingDomainIdsDetail(OFFERING_ID, newDomainIds); + + Mockito.verify(backupOfferingDetailsDao, Mockito.times(3)).persist(Mockito.any(BackupOfferingDetailsVO.class)); + } + + @Test + @SuppressWarnings("unchecked") + public void testUpdateBackupOfferingDomainIdsDetailWithEmptyList() { + List emptyDomainIds = Collections.emptyList(); + + Mockito.doReturn(0).when(backupOfferingDetailsDao).remove(Mockito.any(SearchCriteria.class)); + + backupOfferingDetailsDao.updateBackupOfferingDomainIdsDetail(OFFERING_ID, emptyDomainIds); + + Mockito.verify(backupOfferingDetailsDao, Mockito.never()).persist(Mockito.any(BackupOfferingDetailsVO.class)); + } + + @Test + @SuppressWarnings("unchecked") + public void testUpdateBackupOfferingDomainIdsDetailWithSingleDomain() { + List singleDomainId = Collections.singletonList(5L); + + Mockito.doReturn(0).when(backupOfferingDetailsDao).remove(Mockito.any(SearchCriteria.class)); + Mockito.doReturn(null).when(backupOfferingDetailsDao).persist(Mockito.any(BackupOfferingDetailsVO.class)); + + backupOfferingDetailsDao.updateBackupOfferingDomainIdsDetail(OFFERING_ID, singleDomainId); + + Mockito.verify(backupOfferingDetailsDao, Mockito.times(1)).persist(Mockito.any(BackupOfferingDetailsVO.class)); + } + + private BackupOfferingDetailsVO createDetailVO(long resourceId, String name, String value, boolean display) { + return new BackupOfferingDetailsVO(resourceId, name, value, display); + } +} diff --git a/plugins/hypervisors/ovm3/sonar-project.properties b/plugins/hypervisors/ovm3/sonar-project.properties index 7355f1df4f78..7cc3a41f2a5f 100644 --- a/plugins/hypervisors/ovm3/sonar-project.properties +++ b/plugins/hypervisors/ovm3/sonar-project.properties @@ -24,7 +24,7 @@ sonar.projectVersion=1.0 sonar.sources=src sonar.binaries=target/classes -# Exclussions +# Exclusions sonar.exclusions=**/*Test.java # Language diff --git a/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java index 2ff68b4836f4..54e76463bcaa 100644 --- a/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java +++ b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java @@ -30,6 +30,7 @@ import org.apache.cloudstack.api.command.admin.user.MoveUserCmd; import org.apache.cloudstack.api.response.UserTwoFactorAuthenticationSetupResponse; import org.apache.cloudstack.auth.UserTwoFactorAuthenticator; +import org.apache.cloudstack.backup.BackupOffering; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.acl.ControlledEntity; @@ -491,6 +492,11 @@ public void checkAccess(Account account, VpcOffering vof, DataCenter zone) throw // TODO Auto-generated method stub } + @Override + public void checkAccess(Account account, BackupOffering bof) throws PermissionDeniedException { + // TODO Auto-generated method stub + } + @Override public Pair> getKeys(GetUserKeysCmd cmd){ return null; diff --git a/pom.xml b/pom.xml index 33b232045cad..fa57b98ce7b4 100644 --- a/pom.xml +++ b/pom.xml @@ -53,6 +53,8 @@ 4.22.0.0 apache https://sonarcloud.io + engine/schema/src/main/java/org/apache/cloudstack/backup/BackupOfferingDetailsVO.java + api/src/main/java/org/apache/cloudstack/api/response/BackupOfferingResponse.java 11 diff --git a/server/src/main/java/com/cloud/acl/DomainChecker.java b/server/src/main/java/com/cloud/acl/DomainChecker.java index 24b6346d0afb..0500960abb13 100644 --- a/server/src/main/java/com/cloud/acl/DomainChecker.java +++ b/server/src/main/java/com/cloud/acl/DomainChecker.java @@ -32,6 +32,8 @@ import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao; import org.springframework.stereotype.Component; +import org.apache.cloudstack.backup.dao.BackupOfferingDetailsDao; +import org.apache.cloudstack.backup.BackupOffering; import com.cloud.dc.DataCenter; import com.cloud.dc.DedicatedResourceVO; import com.cloud.dc.dao.DedicatedResourceDao; @@ -70,6 +72,8 @@ public class DomainChecker extends AdapterBase implements SecurityChecker { @Inject DomainDao _domainDao; @Inject + BackupOfferingDetailsDao backupOfferingDetailsDao; + @Inject AccountDao _accountDao; @Inject LaunchPermissionDao _launchPermissionDao; @@ -474,6 +478,35 @@ else if (_accountService.isNormalUser(account.getId()) return hasAccess; } + @Override + public boolean checkAccess(Account account, BackupOffering backupOffering) throws PermissionDeniedException { + boolean hasAccess = false; + if (account == null || backupOffering == null) { + hasAccess = true; + } else { + if (_accountService.isRootAdmin(account.getId())) { + hasAccess = true; + } + else if (_accountService.isNormalUser(account.getId()) + || account.getType() == Account.Type.RESOURCE_DOMAIN_ADMIN + || _accountService.isDomainAdmin(account.getId()) + || account.getType() == Account.Type.PROJECT) { + final List boDomainIds = backupOfferingDetailsDao.findDomainIds(backupOffering.getId()); + if (boDomainIds.isEmpty()) { + hasAccess = true; + } else { + for (Long domainId : boDomainIds) { + if (_domainDao.isChildDomain(domainId, account.getDomainId())) { + hasAccess = true; + break; + } + } + } + } + } + return hasAccess; + } + @Override public boolean checkAccess(Account account, DataCenter zone) throws PermissionDeniedException { if (account == null || zone.getDomainId() == null) {//public zone diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java index e8dd45ce7191..5331cb10ed6d 100644 --- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java @@ -49,6 +49,11 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.consoleproxy.ConsoleProxyManager; +import com.cloud.network.router.VirtualNetworkApplianceManager; +import com.cloud.storage.secondary.SecondaryStorageVmManager; +import com.cloud.utils.DomainHelper; +import com.cloud.vm.VirtualMachineManager; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.affinity.AffinityGroup; @@ -150,7 +155,6 @@ import com.cloud.capacity.CapacityManager; import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Resource.ResourceType; -import com.cloud.consoleproxy.ConsoleProxyManager; import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.ClusterDetailsDao; import com.cloud.dc.ClusterDetailsVO; @@ -245,7 +249,6 @@ import com.cloud.network.element.NetrisProviderVO; import com.cloud.network.element.NsxProviderVO; import com.cloud.network.netris.NetrisService; -import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.vpc.VpcManager; import com.cloud.offering.DiskOffering; @@ -280,7 +283,6 @@ import com.cloud.storage.dao.StoragePoolTagsDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.test.IPRangeConfig; import com.cloud.user.Account; import com.cloud.user.AccountDetailVO; @@ -314,7 +316,6 @@ import com.cloud.utils.net.NetUtils; import com.cloud.vm.NicIpAlias; import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.VmDetailConstants; import com.cloud.vm.dao.NicIpAliasDao; import com.cloud.vm.dao.NicIpAliasVO; @@ -399,6 +400,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati ClusterDao _clusterDao; @Inject AlertManager _alertMgr; + @Inject + DomainHelper domainHelper; List _secChecker; List externalProvisioners; @@ -3519,7 +3522,7 @@ protected ServiceOfferingVO createServiceOffering(final long userId, final boole final boolean isCustomized, final boolean encryptRoot, Long vgpuProfileId, Integer gpuCount, Boolean gpuDisplay, final boolean purgeResources, Integer leaseDuration, VMLeaseManager.ExpiryAction leaseExpiryAction) { // Filter child domains when both parent and child domains are present - List filteredDomainIds = filterChildSubDomains(domainIds); + List filteredDomainIds = domainHelper.filterChildSubDomains(domainIds); // Check if user exists in the system final User user = _userDao.findById(userId); @@ -3908,7 +3911,7 @@ public ServiceOffering updateServiceOffering(final UpdateServiceOfferingCmd cmd) final Account account = _accountDao.findById(user.getAccountId()); // Filter child domains when both parent and child domains are present - List filteredDomainIds = filterChildSubDomains(domainIds); + List filteredDomainIds = domainHelper.filterChildSubDomains(domainIds); Collections.sort(filteredDomainIds); // avoid domain update of service offering if any instance is associated to it @@ -4118,7 +4121,7 @@ protected DiskOfferingVO createDiskOffering(final Long userId, final List } // Filter child domains when both parent and child domains are present - List filteredDomainIds = filterChildSubDomains(domainIds); + List filteredDomainIds = domainHelper.filterChildSubDomains(domainIds); // Check if user exists in the system final User user = _userDao.findById(userId); @@ -4394,7 +4397,7 @@ public DiskOffering updateDiskOffering(final UpdateDiskOfferingCmd cmd) { final Account account = _accountDao.findById(user.getAccountId()); // Filter child domains when both parent and child domains are present - List filteredDomainIds = filterChildSubDomains(domainIds); + List filteredDomainIds = domainHelper.filterChildSubDomains(domainIds); Collections.sort(filteredDomainIds); List filteredZoneIds = new ArrayList<>(); @@ -7401,7 +7404,7 @@ public NetworkOfferingVO doInTransaction(final TransactionStatus status) { } if (offering != null) { // Filter child domains when both parent and child domains are present - List filteredDomainIds = filterChildSubDomains(domainIds); + List filteredDomainIds = domainHelper.filterChildSubDomains(domainIds); List detailsVO = new ArrayList<>(); for (Long domainId : filteredDomainIds) { detailsVO.add(new NetworkOfferingDetailsVO(offering.getId(), Detail.domainid, String.valueOf(domainId), false)); @@ -7867,7 +7870,7 @@ public NetworkOffering updateNetworkOffering(final UpdateNetworkOfferingCmd cmd) } // Filter child domains when both parent and child domains are present - List filteredDomainIds = filterChildSubDomains(domainIds); + List filteredDomainIds = domainHelper.filterChildSubDomains(domainIds); Collections.sort(filteredDomainIds); List filteredZoneIds = new ArrayList<>(); @@ -8434,30 +8437,6 @@ private boolean checkOverlapPortableIpRange(final int regionId, final String new return false; } - private List filterChildSubDomains(final List domainIds) { - List filteredDomainIds = new ArrayList<>(); - if (domainIds != null) { - filteredDomainIds.addAll(domainIds); - } - if (filteredDomainIds.size() > 1) { - for (int i = filteredDomainIds.size() - 1; i >= 1; i--) { - long first = filteredDomainIds.get(i); - for (int j = i - 1; j >= 0; j--) { - long second = filteredDomainIds.get(j); - if (_domainDao.isChildDomain(filteredDomainIds.get(i), filteredDomainIds.get(j))) { - filteredDomainIds.remove(j); - i--; - } - if (_domainDao.isChildDomain(filteredDomainIds.get(j), filteredDomainIds.get(i))) { - filteredDomainIds.remove(i); - break; - } - } - } - } - return filteredDomainIds; - } - protected void validateCacheMode(String cacheMode){ if(cacheMode != null && !Enums.getIfPresent(DiskOffering.DiskCacheMode.class, diff --git a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java index e4219c858da6..60b93d409aab 100644 --- a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java @@ -63,6 +63,7 @@ import com.cloud.network.element.NsxProviderVO; import com.cloud.network.rules.RulesManager; import com.cloud.network.vpn.RemoteAccessVpnService; +import com.cloud.utils.DomainHelper; import com.cloud.vm.dao.VMInstanceDao; import com.google.common.collect.Sets; import org.apache.cloudstack.acl.ControlledEntity.ACLType; @@ -285,6 +286,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis @Inject DomainDao domainDao; @Inject + DomainHelper domainHelper; + @Inject private AnnotationDao annotationDao; @Inject NetworkOfferingDao _networkOfferingDao; @@ -636,7 +639,7 @@ public VpcOffering createVpcOffering(final String name, final String displayText } // Filter child domains when both parent and child domains are present - List filteredDomainIds = filterChildSubDomains(domainIds); + List filteredDomainIds = domainHelper.filterChildSubDomains(domainIds); final Map> svcProviderMap = new HashMap>(); final Set defaultProviders = new HashSet(); @@ -1118,7 +1121,7 @@ private VpcOffering updateVpcOfferingInternal(long vpcOffId, String vpcOfferingN // Filter child domains when both parent and child domains are present - List filteredDomainIds = filterChildSubDomains(domainIds); + List filteredDomainIds = domainHelper.filterChildSubDomains(domainIds); Collections.sort(filteredDomainIds); List filteredZoneIds = new ArrayList<>(); @@ -3658,30 +3661,6 @@ private boolean rollingRestartVpc(final Vpc vpc, final ReservationContext contex return _ntwkMgr.areRoutersRunning(routerDao.listByVpcId(vpc.getId())); } - private List filterChildSubDomains(final List domainIds) { - List filteredDomainIds = new ArrayList<>(); - if (domainIds != null) { - filteredDomainIds.addAll(domainIds); - } - if (filteredDomainIds.size() > 1) { - for (int i = filteredDomainIds.size() - 1; i >= 1; i--) { - long first = filteredDomainIds.get(i); - for (int j = i - 1; j >= 0; j--) { - long second = filteredDomainIds.get(j); - if (domainDao.isChildDomain(filteredDomainIds.get(i), filteredDomainIds.get(j))) { - filteredDomainIds.remove(j); - i--; - } - if (domainDao.isChildDomain(filteredDomainIds.get(j), filteredDomainIds.get(i))) { - filteredDomainIds.remove(i); - break; - } - } - } - } - return filteredDomainIds; - } - protected boolean isGlobalAcl(Long aclVpcId) { return aclVpcId != null && aclVpcId == 0; } diff --git a/server/src/main/java/com/cloud/user/AccountManagerImpl.java b/server/src/main/java/com/cloud/user/AccountManagerImpl.java index dd60fbfb9cca..6f68a1048676 100644 --- a/server/src/main/java/com/cloud/user/AccountManagerImpl.java +++ b/server/src/main/java/com/cloud/user/AccountManagerImpl.java @@ -67,6 +67,7 @@ import org.apache.cloudstack.auth.UserAuthenticator; import org.apache.cloudstack.auth.UserAuthenticator.ActionOnFailedAuthentication; import org.apache.cloudstack.auth.UserTwoFactorAuthenticator; +import org.apache.cloudstack.backup.BackupOffering; import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -3574,6 +3575,21 @@ public void checkAccess(Account account, VpcOffering vof, DataCenter zone) throw throw new PermissionDeniedException("There's no way to confirm " + account + " has access to " + vof); } + @Override + public void checkAccess(Account account, BackupOffering bof) throws PermissionDeniedException { + for (SecurityChecker checker : _securityCheckers) { + if (checker.checkAccess(account, bof)) { + if (logger.isDebugEnabled()) { + logger.debug("Access granted to " + account + " to " + bof + " by " + checker.getName()); + } + return; + } + } + + assert false : "How can all of the security checkers pass on checking this caller?"; + throw new PermissionDeniedException("There's no way to confirm " + account + " has access to " + bof); + } + @Override public void checkAccess(User user, ControlledEntity entity) throws PermissionDeniedException { for (SecurityChecker checker : _securityCheckers) { diff --git a/server/src/main/java/com/cloud/utils/DomainHelper.java b/server/src/main/java/com/cloud/utils/DomainHelper.java new file mode 100644 index 000000000000..480726d256b8 --- /dev/null +++ b/server/src/main/java/com/cloud/utils/DomainHelper.java @@ -0,0 +1,63 @@ +// 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.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import javax.inject.Inject; + +import org.springframework.stereotype.Component; + +import com.cloud.domain.dao.DomainDao; + +@Component +public class DomainHelper { + + @Inject + private DomainDao domainDao; + + /** + * + * @param domainIds List of domain IDs to filter + * @return Filtered list containing only domains that are not descendants of other domains in the list + */ + public List filterChildSubDomains(final List domainIds) { + if (domainIds == null || domainIds.size() <= 1) { + return domainIds == null ? new ArrayList<>() : new ArrayList<>(domainIds); + } + + final List result = new ArrayList<>(); + for (final Long candidate : domainIds) { + boolean isDescendant = false; + for (final Long other : domainIds) { + if (Objects.equals(candidate, other)) { + continue; + } + if (domainDao.isChildDomain(other, candidate)) { + isDescendant = true; + break; + } + } + if (!isDescendant) { + result.add(candidate); + } + } + return result; + } +} diff --git a/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java b/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java index ef3ba917de74..5743c7299231 100644 --- a/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java @@ -38,6 +38,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.utils.DomainHelper; import org.apache.cloudstack.api.ApiCommandResourceType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.InternalIdentity; @@ -68,6 +69,7 @@ import org.apache.cloudstack.backup.dao.BackupDao; import org.apache.cloudstack.backup.dao.BackupDetailsDao; import org.apache.cloudstack.backup.dao.BackupOfferingDao; +import org.apache.cloudstack.backup.dao.BackupOfferingDetailsDao; import org.apache.cloudstack.backup.dao.BackupScheduleDao; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.ConfigKey; @@ -81,12 +83,12 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.math.NumberUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; -import com.amazonaws.util.CollectionUtils; import com.cloud.alert.AlertManager; import com.cloud.api.ApiDispatcher; import com.cloud.api.ApiGsonHelper; @@ -184,6 +186,8 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager { @Inject private BackupOfferingDao backupOfferingDao; @Inject + private BackupOfferingDetailsDao backupOfferingDetailsDao; + @Inject private VMInstanceDao vmInstanceDao; @Inject private AccountService accountService; @@ -237,6 +241,8 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager { private AlertManager alertManager; @Inject private GuestOSDao _guestOSDao; + @Inject + private DomainHelper domainHelper; private AsyncJobDispatcher asyncJobDispatcher; private Timer backupTimer; @@ -280,6 +286,20 @@ public BackupOffering importBackupOffering(final ImportBackupOfferingCmd cmd) { throw new CloudRuntimeException("A backup offering with the same name already exists in this zone"); } + if (CollectionUtils.isNotEmpty(cmd.getDomainIds())) { + for (final Long domainId: cmd.getDomainIds()) { + if (domainDao.findById(domainId) == null) { + throw new InvalidParameterValueException("Please specify a valid domain id"); + } + } + } + + final Account caller = CallContext.current().getCallingAccount(); + List filteredDomainIds = cmd.getDomainIds() == null ? new ArrayList<>() : new ArrayList<>(cmd.getDomainIds()); + if (filteredDomainIds.size() > 1) { + filteredDomainIds = domainHelper.filterChildSubDomains(filteredDomainIds); + } + final BackupProvider provider = getBackupProvider(cmd.getZoneId()); if (!provider.isValidProviderOffering(cmd.getZoneId(), cmd.getExternalId())) { throw new CloudRuntimeException("Backup offering '" + cmd.getExternalId() + "' does not exist on provider " + provider.getName() + " on zone " + cmd.getZoneId()); @@ -292,15 +312,34 @@ public BackupOffering importBackupOffering(final ImportBackupOfferingCmd cmd) { if (savedOffering == null) { throw new CloudRuntimeException("Unable to create backup offering: " + cmd.getExternalId() + ", name: " + cmd.getName()); } + if (CollectionUtils.isNotEmpty(filteredDomainIds)) { + List detailsVOList = new ArrayList<>(); + for (Long domainId : filteredDomainIds) { + detailsVOList.add(new BackupOfferingDetailsVO(savedOffering.getId(), ApiConstants.DOMAIN_ID, String.valueOf(domainId), false)); + } + if (!detailsVOList.isEmpty()) { + backupOfferingDetailsDao.saveDetails(detailsVOList); + } + } logger.debug("Successfully created backup offering " + cmd.getName() + " mapped to backup provider offering " + cmd.getExternalId()); return savedOffering; } + @Override + public List getBackupOfferingDomains(Long offeringId) { + final BackupOffering backupOffering = backupOfferingDao.findById(offeringId); + if (backupOffering == null) { + throw new InvalidParameterValueException("Unable to find backup offering for id: " + offeringId); + } + return backupOfferingDetailsDao.findDomainIds(offeringId); + } + @Override public Pair, Integer> listBackupOfferings(final ListBackupOfferingsCmd cmd) { final Long offeringId = cmd.getOfferingId(); final Long zoneId = cmd.getZoneId(); final String keyword = cmd.getKeyword(); + Long domainId = cmd.getDomainId(); if (offeringId != null) { BackupOfferingVO offering = backupOfferingDao.findById(offeringId); @@ -314,8 +353,13 @@ public Pair, Integer> listBackupOfferings(final ListBackupO SearchBuilder sb = backupOfferingDao.createSearchBuilder(); sb.and("zone_id", sb.entity().getZoneId(), SearchCriteria.Op.EQ); sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); + CallContext ctx = CallContext.current(); final Account caller = ctx.getCallingAccount(); + if (Account.Type.ADMIN != caller.getType() && domainId == null) { + domainId = caller.getDomainId(); + } + if (Account.Type.NORMAL == caller.getType()) { sb.and("user_backups_allowed", sb.entity().isUserDrivenBackupAllowed(), SearchCriteria.Op.EQ); } @@ -328,13 +372,36 @@ public Pair, Integer> listBackupOfferings(final ListBackupO if (keyword != null) { sc.setParameters("name", "%" + keyword + "%"); } + if (Account.Type.NORMAL == caller.getType()) { sc.setParameters("user_backups_allowed", true); } + Pair, Integer> result = backupOfferingDao.searchAndCount(sc, searchFilter); + + if (domainId != null) { + List filteredOfferings = new ArrayList<>(); + for (BackupOfferingVO offering : result.first()) { + List offeringDomains = backupOfferingDetailsDao.findDomainIds(offering.getId()); + if (offeringDomains.isEmpty() || offeringDomains.contains(domainId) || containsParentDomain(offeringDomains, domainId)) { + filteredOfferings.add(offering); + } + } + return new Pair<>(new ArrayList<>(filteredOfferings), filteredOfferings.size()); + } + return new Pair<>(new ArrayList<>(result.first()), result.second()); } + private boolean containsParentDomain(List offeringDomains, Long domainId) { + for (Long offeringDomainId : offeringDomains) { + if (domainDao.isChildDomain(offeringDomainId, domainId)) { + return true; + } + } + return false; + } + @Override public boolean deleteBackupOffering(final Long offeringId) { final BackupOfferingVO offering = backupOfferingDao.findById(offeringId); @@ -342,6 +409,8 @@ public boolean deleteBackupOffering(final Long offeringId) { throw new CloudRuntimeException("Could not find a backup offering with id: " + offeringId); } + accountManager.checkAccess(CallContext.current().getCallingAccount(), offering); + if (backupDao.listByOfferingId(offering.getId()).size() > 0) { throw new CloudRuntimeException("Backup Offering cannot be removed as it has backups associated with it."); } @@ -452,6 +521,12 @@ public boolean assignVMToBackupOffering(Long vmId, Long offeringId) { throw new CloudRuntimeException("Provided backup offering does not exist"); } + Account owner = accountManager.getAccount(vm.getAccountId()); + if (owner == null) { + throw new CloudRuntimeException("Unable to find the owner of the VM"); + } + accountManager.checkAccess(owner, offering); + final BackupProvider backupProvider = getBackupProvider(offering.getProvider()); if (backupProvider == null) { throw new CloudRuntimeException("Failed to get the backup provider for the zone, please contact the administrator"); @@ -762,10 +837,11 @@ protected boolean deleteAllVmBackupSchedules(long vmId) { @ActionEvent(eventType = EventTypes.EVENT_VM_BACKUP_CREATE, eventDescription = "creating VM backup", async = true) public boolean createBackup(CreateBackupCmd cmd, Object job) throws ResourceAllocationException { Long vmId = cmd.getVmId(); + Account caller = CallContext.current().getCallingAccount(); final VMInstanceVO vm = findVmById(vmId); validateBackupForZone(vm.getDataCenterId()); - accountManager.checkAccess(CallContext.current().getCallingAccount(), null, true, vm); + accountManager.checkAccess(caller, null, true, vm); if (vm.getBackupOfferingId() == null) { throw new CloudRuntimeException("VM has not backup offering configured, cannot create backup before assigning it to a backup offering"); @@ -1065,7 +1141,7 @@ public boolean restoreBackup(final Long backupId) { } // This is done to handle historic backups if any with Veeam / Networker plugins - List backupVolumes = CollectionUtils.isNullOrEmpty(backup.getBackedUpVolumes()) ? + List backupVolumes = CollectionUtils.isEmpty(backup.getBackedUpVolumes()) ? vm.getBackupVolumeList() : backup.getBackedUpVolumes(); List vmVolumes = volumeDao.findByInstance(vm.getId()); if (vmVolumes.size() != backupVolumes.size()) { @@ -2112,11 +2188,15 @@ public BackupOffering updateBackupOffering(UpdateBackupOfferingCmd updateBackupO String name = updateBackupOfferingCmd.getName(); String description = updateBackupOfferingCmd.getDescription(); Boolean allowUserDrivenBackups = updateBackupOfferingCmd.getAllowUserDrivenBackups(); + List domainIds = updateBackupOfferingCmd.getDomainIds(); BackupOfferingVO backupOfferingVO = backupOfferingDao.findById(id); if (backupOfferingVO == null) { throw new InvalidParameterValueException(String.format("Unable to find Backup Offering with id: [%s].", id)); } + + accountManager.checkAccess(CallContext.current().getCallingAccount(), backupOfferingVO); + logger.debug("Trying to update Backup Offering {} to {}.", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(backupOfferingVO, "uuid", "name", "description", "userDrivenBackupAllowed"), ReflectionToStringBuilderUtils.reflectOnlySelectedFields(updateBackupOfferingCmd, "name", "description", "allowUserDrivenBackups")); @@ -2139,16 +2219,43 @@ public BackupOffering updateBackupOffering(UpdateBackupOfferingCmd updateBackupO fields.add("allowUserDrivenBackups: " + allowUserDrivenBackups); } - if (!backupOfferingDao.update(id, offering)) { + if (CollectionUtils.isNotEmpty(domainIds)) { + for (final Long domainId: domainIds) { + if (domainDao.findById(domainId) == null) { + throw new InvalidParameterValueException("Please specify a valid domain id"); + } + } + } + List filteredDomainIds = domainHelper.filterChildSubDomains(domainIds); + Collections.sort(filteredDomainIds); + + boolean success = backupOfferingDao.update(id, offering); + if (!success) { logger.warn(String.format("Couldn't update Backup offering (%s) with [%s].", backupOfferingVO, String.join(", ", fields))); } + if (success || fields.isEmpty()) { + List existingDomainIds = backupOfferingDetailsDao.findDomainIds(id); + Collections.sort(existingDomainIds); + updateBackupOfferingDomainDetails(id, filteredDomainIds, existingDomainIds); + } + BackupOfferingVO response = backupOfferingDao.findById(id); CallContext.current().setEventDetails(String.format("Backup Offering updated [%s].", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(response, "id", "name", "description", "userDrivenBackupAllowed", "externalId"))); return response; } + private void updateBackupOfferingDomainDetails(Long id, List filteredDomainIds, List existingDomainIds) { + if (existingDomainIds == null) { + existingDomainIds = new ArrayList<>(); + } + + if(!filteredDomainIds.equals(existingDomainIds)) { + backupOfferingDetailsDao.updateBackupOfferingDomainIdsDetail(id, filteredDomainIds); + } + } + Map getDetailsFromBackupDetails(Long backupId) { Map details = backupDetailsDao.listDetailsKeyPairs(backupId, true); if (details == null) { @@ -2270,7 +2377,7 @@ public void checkAndRemoveBackupOfferingBeforeExpunge(VirtualMachine vm) { return; } List backupsForVm = backupDao.listByVmIdAndOffering(vm.getDataCenterId(), vm.getId(), vm.getBackupOfferingId()); - if (org.apache.commons.collections.CollectionUtils.isEmpty(backupsForVm)) { + if (CollectionUtils.isEmpty(backupsForVm)) { removeVMFromBackupOffering(vm.getId(), true); } else { throw new CloudRuntimeException(String.format("This Instance [uuid: %s, name: %s] has a " diff --git a/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml b/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml index c633a3b0abd2..f4fd57d59fc4 100644 --- a/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml +++ b/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml @@ -81,4 +81,6 @@ + + diff --git a/server/src/test/java/com/cloud/acl/DomainCheckerTest.java b/server/src/test/java/com/cloud/acl/DomainCheckerTest.java index a5ec41306d85..8c7817c2b842 100644 --- a/server/src/test/java/com/cloud/acl/DomainCheckerTest.java +++ b/server/src/test/java/com/cloud/acl/DomainCheckerTest.java @@ -18,6 +18,9 @@ import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker; +import org.apache.cloudstack.backup.BackupOfferingVO; +import org.apache.cloudstack.backup.dao.BackupOfferingDetailsDao; +import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; @@ -35,6 +38,8 @@ import com.cloud.user.dao.AccountDao; import com.cloud.utils.Ternary; +import java.util.Collections; + @RunWith(MockitoJUnitRunner.class) public class DomainCheckerTest { @@ -46,6 +51,8 @@ public class DomainCheckerTest { DomainDao _domainDao; @Mock ProjectManager _projectMgr; + @Mock + BackupOfferingDetailsDao backupOfferingDetailsDao; @Spy @InjectMocks @@ -163,4 +170,42 @@ public void testProjectOwnerCannotAccess() { domainChecker.validateCallerHasAccessToEntityOwner(caller, entity, SecurityChecker.AccessType.ListEntry); } + @Test + public void testBackupOfferingAccessRootAdmin() { + Account rootAdmin = Mockito.mock(Account.class); + Mockito.when(rootAdmin.getId()).thenReturn(1L); + BackupOfferingVO backupOfferingVO = Mockito.mock(BackupOfferingVO.class); + Mockito.when(_accountService.isRootAdmin(rootAdmin.getId())).thenReturn(true); + + boolean hasAccess = domainChecker.checkAccess(rootAdmin, backupOfferingVO); + Assert.assertTrue(hasAccess); + } + + @Test + public void testBackupOfferingAccessDomainAdmin() { + Account domainAdmin = Mockito.mock(Account.class); + Mockito.when(domainAdmin.getId()).thenReturn(2L); + BackupOfferingVO backupOfferingVO = Mockito.mock(BackupOfferingVO.class); + AccountVO owner = Mockito.mock(AccountVO.class); + Mockito.when(_accountService.isDomainAdmin(domainAdmin.getId())).thenReturn(true); + Mockito.when(domainAdmin.getDomainId()).thenReturn(10L); + Mockito.when(_domainDao.isChildDomain(100L, 10L)).thenReturn(true); + Mockito.when(backupOfferingDetailsDao.findDomainIds(backupOfferingVO.getId())).thenReturn(Collections.singletonList(100L)); + + boolean hasAccess = domainChecker.checkAccess(domainAdmin, backupOfferingVO); + Assert.assertTrue(hasAccess); + } + + @Test + public void testBackupOfferingAccessNoAccess() { + Account normalUser = Mockito.mock(Account.class); + Mockito.when(normalUser.getId()).thenReturn(3L); + BackupOfferingVO backupOfferingVO = Mockito.mock(BackupOfferingVO.class); + Mockito.when(_accountService.isRootAdmin(normalUser.getId())).thenReturn(false); + Mockito.when(_accountService.isDomainAdmin(normalUser.getId())).thenReturn(false); + + boolean hasAccess = domainChecker.checkAccess(normalUser, backupOfferingVO); + Assert.assertFalse(hasAccess); + } + } diff --git a/server/src/test/java/com/cloud/configuration/ConfigurationManagerImplTest.java b/server/src/test/java/com/cloud/configuration/ConfigurationManagerImplTest.java index 60263cea9b88..8295202fcc53 100644 --- a/server/src/test/java/com/cloud/configuration/ConfigurationManagerImplTest.java +++ b/server/src/test/java/com/cloud/configuration/ConfigurationManagerImplTest.java @@ -49,6 +49,7 @@ import com.cloud.user.Account; import com.cloud.user.AccountManagerImpl; import com.cloud.user.User; +import com.cloud.utils.DomainHelper; import com.cloud.utils.Pair; import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.SearchCriteria; @@ -178,6 +179,8 @@ public class ConfigurationManagerImplTest { PrimaryDataStoreDao storagePoolDao; @Mock StoragePoolDetailsDao storagePoolDetailsDao; + @Mock + DomainHelper domainHelper; DeleteZoneCmd deleteZoneCmd; CreateNetworkOfferingCmd createNetworkOfferingCmd; diff --git a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java index fe4ea0838f16..1ec141a8be13 100644 --- a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java +++ b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java @@ -59,6 +59,7 @@ import java.util.TimeZone; import java.util.UUID; +import com.cloud.domain.Domain; import com.cloud.storage.dao.SnapshotPolicyDao; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker; @@ -3107,7 +3108,7 @@ public void moveVmToUserTestAccountManagerCheckAccessThrowsPermissionDeniedExcep configureDoNothingForMethodsThatWeDoNotWantToTest(); - doThrow(PermissionDeniedException.class).when(accountManager).checkAccess(Mockito.any(Account.class), Mockito.any()); + doThrow(PermissionDeniedException.class).when(accountManager).checkAccess(Mockito.any(Account.class), Mockito.any(Domain.class)); Assert.assertThrows(PermissionDeniedException.class, () -> userVmManagerImpl.moveVmToUser(assignVmCmdMock)); } diff --git a/server/src/test/java/org/apache/cloudstack/backup/BackupManagerTest.java b/server/src/test/java/org/apache/cloudstack/backup/BackupManagerTest.java index 8b13fd474947..a9c083228e2b 100644 --- a/server/src/test/java/org/apache/cloudstack/backup/BackupManagerTest.java +++ b/server/src/test/java/org/apache/cloudstack/backup/BackupManagerTest.java @@ -60,6 +60,7 @@ import com.cloud.user.User; import com.cloud.user.dao.AccountDao; import com.cloud.utils.DateUtil; +import com.cloud.utils.DomainHelper; import com.cloud.utils.Pair; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -80,11 +81,13 @@ import org.apache.cloudstack.api.command.user.backup.CreateBackupCmd; import org.apache.cloudstack.api.command.user.backup.CreateBackupScheduleCmd; import org.apache.cloudstack.api.command.user.backup.DeleteBackupScheduleCmd; +import org.apache.cloudstack.api.command.user.backup.ListBackupOfferingsCmd; import org.apache.cloudstack.api.command.user.backup.ListBackupScheduleCmd; import org.apache.cloudstack.api.response.BackupResponse; import org.apache.cloudstack.backup.dao.BackupDao; import org.apache.cloudstack.backup.dao.BackupDetailsDao; import org.apache.cloudstack.backup.dao.BackupOfferingDao; +import org.apache.cloudstack.backup.dao.BackupOfferingDetailsDao; import org.apache.cloudstack.backup.dao.BackupScheduleDao; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.ConfigKey; @@ -241,6 +244,12 @@ public class BackupManagerTest { @Mock private GuestOSDao _guestOSDao; + @Mock + private BackupOfferingDetailsDao backupOfferingDetailsDao; + + @Mock + DomainHelper domainHelper; + private Gson gson; private String[] hostPossibleValues = {"127.0.0.1", "hostname"}; @@ -352,6 +361,7 @@ public void testUpdateBackupOfferingSuccess() { when(cmd.getName()).thenReturn("New name"); when(cmd.getDescription()).thenReturn("New description"); when(cmd.getAllowUserDrivenBackups()).thenReturn(true); + when(backupOfferingDetailsDao.findDomainIds(id)).thenReturn(Collections.emptyList()); BackupOffering updated = backupManager.updateBackupOffering(cmd); assertEquals("New name", updated.getName()); @@ -1081,7 +1091,7 @@ public void testGetRootDiskInfoFromBackup() { assertEquals("root-disk-offering-uuid", VmDiskInfo.getDiskOffering().getUuid()); assertEquals(Long.valueOf(5), VmDiskInfo.getSize()); - assertEquals(null, VmDiskInfo.getDeviceId()); + assertNull(VmDiskInfo.getDeviceId()); } @Test @@ -1106,7 +1116,7 @@ public void testImportBackupOffering() { assertEquals("Test Offering", result.getName()); assertEquals("Test Description", result.getDescription()); - assertEquals(true, result.isUserDrivenBackupAllowed()); + assertTrue(result.isUserDrivenBackupAllowed()); assertEquals("external-id", result.getExternalId()); assertEquals("testbackupprovider", result.getProvider()); } @@ -1149,6 +1159,8 @@ public void testAssignVMToBackupOffering() { VMInstanceVO vm = mock(VMInstanceVO.class); when(vm.getId()).thenReturn(vmId); BackupOfferingVO offering = mock(BackupOfferingVO.class); + Account owner = mock(Account.class); + overrideBackupFrameworkConfigValue(); @@ -1159,6 +1171,8 @@ public void testAssignVMToBackupOffering() { when(vm.getBackupOfferingId()).thenReturn(null); when(offering.getProvider()).thenReturn("testbackupprovider"); when(backupProvider.assignVMToBackupOffering(vm, offering)).thenReturn(true); + when(vm.getAccountId()).thenReturn(3L); + when(accountManager.getAccount(vm.getAccountId())).thenReturn(owner); when(vmInstanceDao.update(1L, vm)).thenReturn(true); try (MockedStatic ignored2 = Mockito.mockStatic(UsageEventUtils.class)) { @@ -2156,4 +2170,352 @@ public void testRestoreBackupVolumeMismatch() { verify(vmInstanceDao, times(1)).findByIdIncludingRemoved(vmId); verify(volumeDao, times(1)).findByInstance(vmId); } + + @Test + public void getBackupOfferingDomainsTestOfferingNotFound() { + Long offeringId = 1L; + when(backupOfferingDao.findById(offeringId)).thenReturn(null); + + InvalidParameterValueException exception = Assert.assertThrows(InvalidParameterValueException.class, + () -> backupManager.getBackupOfferingDomains(offeringId)); + assertEquals("Unable to find backup offering for id: " + offeringId, exception.getMessage()); + } + + @Test + public void getBackupOfferingDomainsTestReturnsDomains() { + Long offeringId = 1L; + BackupOfferingVO offering = Mockito.mock(BackupOfferingVO.class); + when(backupOfferingDao.findById(offeringId)).thenReturn(offering); + when(backupOfferingDetailsDao.findDomainIds(offeringId)).thenReturn(List.of(10L, 20L)); + + List result = backupManager.getBackupOfferingDomains(offeringId); + + assertEquals(2, result.size()); + assertTrue(result.contains(10L)); + assertTrue(result.contains(20L)); + } + + @Test + public void testUpdateBackupOfferingThrowsWhenDomainIdInvalid() { + Long id = 1234L; + UpdateBackupOfferingCmd cmd = Mockito.spy(UpdateBackupOfferingCmd.class); + when(cmd.getId()).thenReturn(id); + when(cmd.getDomainIds()).thenReturn(List.of(99L)); + + when(domainDao.findById(99L)).thenReturn(null); + + InvalidParameterValueException exception = Assert.assertThrows(InvalidParameterValueException.class, + () -> backupManager.updateBackupOffering(cmd)); + assertEquals("Please specify a valid domain id", exception.getMessage()); + } + + @Test + public void testUpdateBackupOfferingPersistsDomainDetailsWhenProvided() { + Long id = 1234L; + Long domainId = 11L; + UpdateBackupOfferingCmd cmd = Mockito.spy(UpdateBackupOfferingCmd.class); + when(cmd.getId()).thenReturn(id); + when(cmd.getDomainIds()).thenReturn(List.of(domainId)); + + DomainVO domain = Mockito.mock(DomainVO.class); + when(domainDao.findById(domainId)).thenReturn(domain); + + when(domainHelper.filterChildSubDomains(List.of(domainId))).thenReturn(new ArrayList<>(List.of(domainId))); + when(backupOfferingDetailsDao.findDomainIds(id)).thenReturn(new ArrayList<>()); + + BackupOfferingVO offering = Mockito.mock(BackupOfferingVO.class); + BackupOfferingVO offeringUpdate = Mockito.mock(BackupOfferingVO.class); + when(backupOfferingDao.findById(id)).thenReturn(offering); + when(backupOfferingDao.createForUpdate(id)).thenReturn(offeringUpdate); + when(backupOfferingDao.update(id, offeringUpdate)).thenReturn(true); + + BackupOffering updated = backupManager.updateBackupOffering(cmd); + + verify(backupOfferingDetailsDao, times(1)).updateBackupOfferingDomainIdsDetail(id, List.of(domainId)); + } + + @Test + public void testListBackupOfferingsWithDomainFilteringIncludesGlobalOfferings() { + Long requestedDomainId = 3L; + + ListBackupOfferingsCmd cmd = + Mockito.mock(ListBackupOfferingsCmd.class); + when(cmd.getOfferingId()).thenReturn(null); + when(cmd.getDomainId()).thenReturn(requestedDomainId); + when(cmd.getStartIndex()).thenReturn(0L); + when(cmd.getPageSizeVal()).thenReturn(20L); + + BackupOfferingVO globalOffering = createMockOffering(1L, "Global Offering"); + BackupOfferingVO domainOffering = createMockOffering(2L, "Domain Offering"); + + List allOfferings = List.of(globalOffering, domainOffering); + + SearchBuilder sb = Mockito.mock(SearchBuilder.class); + SearchCriteria sc = Mockito.mock(SearchCriteria.class); + BackupOfferingVO entityMock = Mockito.mock(BackupOfferingVO.class); + when(backupOfferingDao.createSearchBuilder()).thenReturn(sb); + when(sb.entity()).thenReturn(entityMock); + when(sb.and(Mockito.anyString(), Mockito.any(), Mockito.any(SearchCriteria.Op.class))).thenReturn(sb); + when(sb.create()).thenReturn(sc); + when(backupOfferingDao.searchAndCount(Mockito.any(), Mockito.any())) + .thenReturn(new Pair<>(allOfferings, allOfferings.size())); + + when(backupOfferingDetailsDao.findDomainIds(1L)).thenReturn(Collections.emptyList()); + when(backupOfferingDetailsDao.findDomainIds(2L)).thenReturn(List.of(2L)); + + Account account = Mockito.mock(Account.class); + when(account.getType()).thenReturn(Account.Type.NORMAL); + + try (MockedStatic mockedCallContext = Mockito.mockStatic(CallContext.class)) { + CallContext contextMock = Mockito.mock(CallContext.class); + mockedCallContext.when(CallContext::current).thenReturn(contextMock); + when(contextMock.getCallingAccount()).thenReturn(account); + + Pair, Integer> result = backupManager.listBackupOfferings(cmd); + + assertEquals(1, result.first().size()); + assertEquals("Global Offering", result.first().get(0).getName()); + } + } + + @Test + public void testListBackupOfferingsWithDomainFilteringIncludesDirectDomainMapping() { + Long requestedDomainId = 3L; + + ListBackupOfferingsCmd cmd = + Mockito.mock(ListBackupOfferingsCmd.class); + when(cmd.getOfferingId()).thenReturn(null); + when(cmd.getDomainId()).thenReturn(requestedDomainId); + when(cmd.getStartIndex()).thenReturn(0L); + when(cmd.getPageSizeVal()).thenReturn(20L); + + BackupOfferingVO directDomainOffering = createMockOffering(1L, "Direct Domain Offering"); + BackupOfferingVO otherDomainOffering = createMockOffering(2L, "Other Domain Offering"); + + List allOfferings = List.of(directDomainOffering, otherDomainOffering); + + SearchBuilder sb = Mockito.mock(SearchBuilder.class); + SearchCriteria sc = Mockito.mock(SearchCriteria.class); + BackupOfferingVO entityMock = Mockito.mock(BackupOfferingVO.class); + when(backupOfferingDao.createSearchBuilder()).thenReturn(sb); + when(sb.entity()).thenReturn(entityMock); + when(sb.and(Mockito.anyString(), Mockito.any(), Mockito.any(SearchCriteria.Op.class))).thenReturn(sb); + when(sb.create()).thenReturn(sc); + when(backupOfferingDao.searchAndCount(Mockito.any(), Mockito.any())) + .thenReturn(new Pair<>(allOfferings, allOfferings.size())); + + when(backupOfferingDetailsDao.findDomainIds(1L)).thenReturn(List.of(requestedDomainId)); + when(backupOfferingDetailsDao.findDomainIds(2L)).thenReturn(List.of(5L)); + + Account account = Mockito.mock(Account.class); + when(account.getType()).thenReturn(Account.Type.NORMAL); + + try (MockedStatic mockedCallContext = Mockito.mockStatic(CallContext.class)) { + CallContext contextMock = Mockito.mock(CallContext.class); + mockedCallContext.when(CallContext::current).thenReturn(contextMock); + when(contextMock.getCallingAccount()).thenReturn(account); + + Pair, Integer> result = backupManager.listBackupOfferings(cmd); + + assertEquals(1, result.first().size()); + assertEquals("Direct Domain Offering", result.first().get(0).getName()); + } + } + + @Test + public void testListBackupOfferingsWithDomainFilteringIncludesParentDomainOfferings() { + Long parentDomainId = 1L; + Long childDomainId = 3L; + + ListBackupOfferingsCmd cmd = + Mockito.mock(ListBackupOfferingsCmd.class); + when(cmd.getOfferingId()).thenReturn(null); + when(cmd.getDomainId()).thenReturn(childDomainId); + when(cmd.getStartIndex()).thenReturn(0L); + when(cmd.getPageSizeVal()).thenReturn(20L); + + BackupOfferingVO parentDomainOffering = createMockOffering(1L, "Parent Domain Offering"); + BackupOfferingVO siblingDomainOffering = createMockOffering(2L, "Sibling Domain Offering"); + + List allOfferings = List.of(parentDomainOffering, siblingDomainOffering); + + SearchBuilder sb = Mockito.mock(SearchBuilder.class); + SearchCriteria sc = Mockito.mock(SearchCriteria.class); + BackupOfferingVO entityMock = Mockito.mock(BackupOfferingVO.class); + when(backupOfferingDao.createSearchBuilder()).thenReturn(sb); + when(sb.entity()).thenReturn(entityMock); + when(sb.and(Mockito.anyString(), Mockito.any(), Mockito.any(SearchCriteria.Op.class))).thenReturn(sb); + when(sb.create()).thenReturn(sc); + when(backupOfferingDao.searchAndCount(Mockito.any(), Mockito.any())) + .thenReturn(new Pair<>(allOfferings, allOfferings.size())); + + when(backupOfferingDetailsDao.findDomainIds(1L)).thenReturn(List.of(parentDomainId)); + when(backupOfferingDetailsDao.findDomainIds(2L)).thenReturn(List.of(4L)); + + when(domainDao.isChildDomain(parentDomainId, childDomainId)).thenReturn(true); + when(domainDao.isChildDomain(4L, childDomainId)).thenReturn(false); + + Account account = Mockito.mock(Account.class); + when(account.getType()).thenReturn(Account.Type.NORMAL); + + try (MockedStatic mockedCallContext = Mockito.mockStatic(CallContext.class)) { + CallContext contextMock = Mockito.mock(CallContext.class); + mockedCallContext.when(CallContext::current).thenReturn(contextMock); + when(contextMock.getCallingAccount()).thenReturn(account); + + Pair, Integer> result = backupManager.listBackupOfferings(cmd); + + assertEquals(1, result.first().size()); + assertEquals("Parent Domain Offering", result.first().get(0).getName()); + } + } + + @Test + public void testListBackupOfferingsWithDomainFilteringExcludesSiblingDomainOfferings() { + Long requestedDomainId = 3L; + Long siblingDomainId = 4L; + + ListBackupOfferingsCmd cmd = + Mockito.mock(ListBackupOfferingsCmd.class); + when(cmd.getOfferingId()).thenReturn(null); + when(cmd.getDomainId()).thenReturn(requestedDomainId); + when(cmd.getStartIndex()).thenReturn(0L); + when(cmd.getPageSizeVal()).thenReturn(20L); + + BackupOfferingVO siblingOffering = createMockOffering(1L, "Sibling Domain Offering"); + List allOfferings = List.of(siblingOffering); + + SearchBuilder sb = Mockito.mock(SearchBuilder.class); + SearchCriteria sc = Mockito.mock(SearchCriteria.class); + BackupOfferingVO entityMock = Mockito.mock(BackupOfferingVO.class); + when(backupOfferingDao.createSearchBuilder()).thenReturn(sb); + when(sb.entity()).thenReturn(entityMock); + when(sb.and(Mockito.anyString(), Mockito.any(), Mockito.any(SearchCriteria.Op.class))).thenReturn(sb); + when(sb.create()).thenReturn(sc); + when(backupOfferingDao.searchAndCount(Mockito.any(), Mockito.any())) + .thenReturn(new Pair<>(allOfferings, allOfferings.size())); + + when(backupOfferingDetailsDao.findDomainIds(1L)).thenReturn(List.of(siblingDomainId)); + when(domainDao.isChildDomain(siblingDomainId, requestedDomainId)).thenReturn(false); + + Account account = Mockito.mock(Account.class); + when(account.getType()).thenReturn(Account.Type.NORMAL); + + try (MockedStatic mockedCallContext = Mockito.mockStatic(CallContext.class)) { + CallContext contextMock = Mockito.mock(CallContext.class); + mockedCallContext.when(CallContext::current).thenReturn(contextMock); + when(contextMock.getCallingAccount()).thenReturn(account); + + Pair, Integer> result = backupManager.listBackupOfferings(cmd); + + assertEquals(0, result.first().size()); + } + } + + @Test + public void testListBackupOfferingsWithDomainFilteringMultipleDomainMappings() { + Long requestedDomainId = 5L; + Long parentDomainId1 = 1L; + Long parentDomainId2 = 2L; + Long unrelatedDomainId = 8L; + + ListBackupOfferingsCmd cmd = + Mockito.mock(ListBackupOfferingsCmd.class); + when(cmd.getOfferingId()).thenReturn(null); + when(cmd.getDomainId()).thenReturn(requestedDomainId); + when(cmd.getStartIndex()).thenReturn(0L); + when(cmd.getPageSizeVal()).thenReturn(20L); + + BackupOfferingVO multiDomainOffering = createMockOffering(1L, "Multi-Domain Offering"); + List allOfferings = List.of(multiDomainOffering); + + SearchBuilder sb = Mockito.mock(SearchBuilder.class); + SearchCriteria sc = Mockito.mock(SearchCriteria.class); + BackupOfferingVO entityMock = Mockito.mock(BackupOfferingVO.class); + when(backupOfferingDao.createSearchBuilder()).thenReturn(sb); + when(sb.entity()).thenReturn(entityMock); + when(sb.and(Mockito.anyString(), Mockito.any(), Mockito.any(SearchCriteria.Op.class))).thenReturn(sb); + when(sb.create()).thenReturn(sc); + when(backupOfferingDao.searchAndCount(Mockito.any(), Mockito.any())) + .thenReturn(new Pair<>(allOfferings, allOfferings.size())); + + when(backupOfferingDetailsDao.findDomainIds(1L)) + .thenReturn(List.of(parentDomainId1, unrelatedDomainId, parentDomainId2)); + + when(domainDao.isChildDomain(parentDomainId1, requestedDomainId)).thenReturn(false); + when(domainDao.isChildDomain(unrelatedDomainId, requestedDomainId)).thenReturn(false); + when(domainDao.isChildDomain(parentDomainId2, requestedDomainId)).thenReturn(true); + + Account account = Mockito.mock(Account.class); + when(account.getType()).thenReturn(Account.Type.NORMAL); + + try (MockedStatic mockedCallContext = Mockito.mockStatic(CallContext.class)) { + CallContext contextMock = Mockito.mock(CallContext.class); + mockedCallContext.when(CallContext::current).thenReturn(contextMock); + when(contextMock.getCallingAccount()).thenReturn(account); + + Pair, Integer> result = backupManager.listBackupOfferings(cmd); + + assertEquals(1, result.first().size()); + assertEquals("Multi-Domain Offering", result.first().get(0).getName()); + } + } + + @Test + public void testListBackupOfferingsNormalUserDefaultsToDomainFiltering() { + Long userDomainId = 7L; + + ListBackupOfferingsCmd cmd = + Mockito.mock(ListBackupOfferingsCmd.class); + when(cmd.getOfferingId()).thenReturn(null); + when(cmd.getDomainId()).thenReturn(null); // User didn't pass domain filter + when(cmd.getStartIndex()).thenReturn(0L); + when(cmd.getPageSizeVal()).thenReturn(20L); + + BackupOfferingVO globalOffering = createMockOffering(1L, "Global Offering"); + BackupOfferingVO userDomainOffering = createMockOffering(2L, "User Domain Offering"); + BackupOfferingVO otherDomainOffering = createMockOffering(3L, "Other Domain Offering"); + + List allOfferings = List.of(globalOffering, userDomainOffering, otherDomainOffering); + + SearchBuilder sb = Mockito.mock(SearchBuilder.class); + SearchCriteria sc = Mockito.mock(SearchCriteria.class); + BackupOfferingVO entityMock = Mockito.mock(BackupOfferingVO.class); + when(backupOfferingDao.createSearchBuilder()).thenReturn(sb); + when(sb.entity()).thenReturn(entityMock); + when(sb.and(Mockito.anyString(), Mockito.any(), Mockito.any(SearchCriteria.Op.class))).thenReturn(sb); + when(sb.create()).thenReturn(sc); + when(backupOfferingDao.searchAndCount(Mockito.any(), Mockito.any())) + .thenReturn(new Pair<>(allOfferings, allOfferings.size())); + + when(backupOfferingDetailsDao.findDomainIds(1L)).thenReturn(Collections.emptyList()); // Global + when(backupOfferingDetailsDao.findDomainIds(2L)).thenReturn(List.of(userDomainId)); // User's domain + when(backupOfferingDetailsDao.findDomainIds(3L)).thenReturn(List.of(99L)); // Other domain + + when(domainDao.isChildDomain(99L, userDomainId)).thenReturn(false); + + Account account = Mockito.mock(Account.class); + when(account.getType()).thenReturn(Account.Type.NORMAL); + when(account.getDomainId()).thenReturn(userDomainId); + + try (MockedStatic mockedCallContext = Mockito.mockStatic(CallContext.class)) { + CallContext contextMock = Mockito.mock(CallContext.class); + mockedCallContext.when(CallContext::current).thenReturn(contextMock); + when(contextMock.getCallingAccount()).thenReturn(account); + + Pair, Integer> result = backupManager.listBackupOfferings(cmd); + + assertEquals(2, result.first().size()); + assertTrue(result.first().stream().anyMatch(o -> o.getName().equals("Global Offering"))); + assertTrue(result.first().stream().anyMatch(o -> o.getName().equals("User Domain Offering"))); + } + } + + private BackupOfferingVO createMockOffering(Long id, String name) { + BackupOfferingVO offering = Mockito.mock(BackupOfferingVO.class); + when(offering.getId()).thenReturn(id); + when(offering.getName()).thenReturn(name); + return offering; + } + } diff --git a/server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java b/server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java index 2fa9a2d7a44b..f175c5674224 100644 --- a/server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java +++ b/server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java @@ -27,6 +27,7 @@ import javax.inject.Inject; +import com.cloud.utils.DomainHelper; import org.apache.cloudstack.annotation.dao.AnnotationDao; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; @@ -98,6 +99,9 @@ public class CreateNetworkOfferingTest extends TestCase { @Mock LoadBalancerVMMapDao _loadBalancerVMMapDao; + @Mock + DomainHelper domainHelper; + @Mock AnnotationDao annotationDao; @Inject diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py index 05ce9d41023c..6c9aa087bc7d 100644 --- a/tools/marvin/setup.py +++ b/tools/marvin/setup.py @@ -27,7 +27,7 @@ raise RuntimeError("python setuptools is required to build Marvin") -VERSION = "4.23.0.0-SNAPSHOT" +VERSION = "4.23.0.0" setup(name="Marvin", version=VERSION, diff --git a/ui/src/config/section/offering.js b/ui/src/config/section/offering.js index 4a32619b8c2f..bc95772d6f7a 100644 --- a/ui/src/config/section/offering.js +++ b/ui/src/config/section/offering.js @@ -340,9 +340,9 @@ export default { icon: 'cloud-upload-outlined', docHelp: 'adminguide/virtual_machines.html#backup-offerings', permission: ['listBackupOfferings'], - searchFilters: ['zoneid'], - columns: ['name', 'description', 'zonename'], - details: ['name', 'id', 'description', 'externalid', 'zone', 'allowuserdrivenbackups', 'created'], + searchFilters: ['zoneid', 'domainid'], + columns: ['name', 'description', 'domain', 'zonename'], + details: ['name', 'id', 'description', 'externalid', 'domain', 'zone', 'allowuserdrivenbackups', 'created'], related: [{ name: 'vm', title: 'label.instances', diff --git a/ui/src/views/offering/ImportBackupOffering.vue b/ui/src/views/offering/ImportBackupOffering.vue index b8ac7d8e8e65..f680eacd4a7d 100644 --- a/ui/src/views/offering/ImportBackupOffering.vue +++ b/ui/src/views/offering/ImportBackupOffering.vue @@ -85,6 +85,33 @@
+ + + + + + + + + + + {{ opt.path || opt.name || opt.description }} + + + +
{{ this.$t('label.cancel') }} {{ this.$t('label.ok') }} @@ -96,6 +123,7 @@ diff --git a/ui/src/config/router.js b/ui/src/config/router.js index 08df799dd898..3e5d8677b347 100644 --- a/ui/src/config/router.js +++ b/ui/src/config/router.js @@ -81,6 +81,7 @@ function generateRouterMap (section) { filters: child.filters, params: child.params ? child.params : {}, columns: child.columns, + advisories: !vueProps.$config.advisoriesDisabled ? child.advisories : undefined, details: child.details, searchFilters: child.searchFilters, related: child.related, @@ -180,6 +181,10 @@ function generateRouterMap (section) { map.meta.columns = section.columns } + if (!vueProps.$config.advisoriesDisabled && section.advisories) { + map.meta.advisories = section.advisories + } + if (section.actions) { map.meta.actions = section.actions } diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index a03693e351d8..32e888bb53dc 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -18,6 +18,8 @@ import { shallowRef, defineAsyncComponent } from 'vue' import store from '@/store' import { isZoneCreated } from '@/utils/zone' +import { getAPI, postAPI, getBaseUrl } from '@/api' +import { getLatestKubernetesIsoParams } from '@/utils/acsrepo' import kubernetesIcon from '@/assets/icons/kubernetes.svg?inline' export default { @@ -582,6 +584,182 @@ export default { } ], resourceType: 'KubernetesCluster', + advisories: [ + { + id: 'cks-min-offering', + severity: 'warning', + message: 'message.advisory.cks.min.offering', + docsHelp: 'plugins/cloudstack-kubernetes-service.html', + dismissOnConditionFail: true, + condition: async (store) => { + if (!('listServiceOfferings' in store.getters.apis)) { + return false + } + const params = { + cpunumber: 2, + memory: 2048, + issystem: false + } + try { + const json = await getAPI('listServiceOfferings', params) + const offerings = json?.listserviceofferingsresponse?.serviceoffering || [] + return !offerings.some(o => !o.iscustomized) + } catch (error) {} + return false + }, + actions: [ + { + primary: true, + label: 'label.add.minimum.required.compute.offering', + loadingLabel: 'message.adding.minimum.required.compute.offering.kubernetes.cluster', + show: (store) => { return ('createServiceOffering' in store.getters.apis) }, + run: async () => { + const params = { + name: 'CKS Instance', + cpunumber: 2, + cpuspeed: 1000, + memory: 2048, + iscustomized: false, + issystem: false + } + try { + const json = await postAPI('createServiceOffering', params) + if (json?.createserviceofferingresponse?.serviceoffering) { + return true + } + } catch (error) {} + return false + }, + successMessage: 'message.added.minimum.required.compute.offering.kubernetes.cluster', + errorMessage: 'message.add.minimum.required.compute.offering.kubernetes.cluster.failed' + }, + { + label: 'label.go.to.compute.offerings', + show: (store) => { return ('listServiceOfferings' in store.getters.apis) }, + run: (store, router) => { + router.push({ name: 'computeoffering' }) + return false + } + } + ] + }, + { + id: 'cks-version-check', + severity: 'warning', + message: 'message.advisory.cks.version.check', + docsHelp: 'plugins/cloudstack-kubernetes-service.html', + dismissOnConditionFail: true, + condition: async (store) => { + const api = 'listKubernetesSupportedVersions' + if (!(api in store.getters.apis)) { + return false + } + try { + const json = await getAPI(api, {}) + const versions = json?.listkubernetessupportedversionsresponse?.kubernetessupportedversion || [] + return versions.length === 0 + } catch (error) {} + return false + }, + actions: [ + { + primary: true, + label: 'label.add.latest.kubernetes.iso', + loadingLabel: 'message.adding.latest.kubernetes.iso', + show: (store) => { return ('addKubernetesSupportedVersion' in store.getters.apis) }, + run: async () => { + let arch = 'x86_64' + if ('listClusters' in store.getters.apis) { + try { + const json = await getAPI('listClusters', { allocationstate: 'Enabled', page: 1, pagesize: 1 }) + const cluster = json?.listclustersresponse?.cluster?.[0] || {} + arch = cluster.architecture || 'x86_64' + } catch (error) {} + } + const params = await getLatestKubernetesIsoParams(arch) + try { + const json = await postAPI('addKubernetesSupportedVersion', params) + if (json?.addkubernetessupportedversionresponse?.kubernetessupportedversion) { + return true + } + } catch (error) {} + return false + }, + successMessage: 'message.added.latest.kubernetes.iso', + errorMessage: 'message.add.latest.kubernetes.iso.failed' + }, + { + label: 'label.go.to.kubernetes.isos', + show: true, + run: (store, router) => { + router.push({ name: 'kubernetesiso' }) + return false + } + } + ] + }, + { + id: 'cks-endpoint-url', + severity: 'warning', + message: 'message.advisory.cks.endpoint.url.not.configured', + docsHelp: 'plugins/cloudstack-kubernetes-service.html', + dismissOnConditionFail: true, + condition: async (store) => { + if (!['Admin'].includes(store.getters.userInfo.roletype)) { + return false + } + let url = '' + const baseUrl = getBaseUrl() + if (baseUrl.startsWith('/')) { + url = window.location.origin + baseUrl + } + if (!url || url.startsWith('http://localhost')) { + return false + } + const params = { + name: 'endpoint.url' + } + const json = await getAPI('listConfigurations', params) + const configuration = json?.listconfigurationsresponse?.configuration?.[0] || {} + return !configuration.value || configuration.value.startsWith('http://localhost') + }, + actions: [ + { + primary: true, + label: 'label.fix.global.setting', + show: (store) => { return ('updateConfiguration' in store.getters.apis) }, + run: async () => { + let url = '' + const baseUrl = getBaseUrl() + if (baseUrl.startsWith('/')) { + url = window.location.origin + baseUrl + } + const params = { + name: 'endpoint.url', + value: url + } + try { + const json = await postAPI('updateConfiguration', params) + if (json?.updateconfigurationresponse?.configuration) { + return true + } + } catch (error) {} + return false + }, + successMessage: 'message.global.setting.updated', + errorMessage: 'message.global.setting.update.failed' + }, + { + label: 'label.go.to.global.settings', + show: (store) => { return ('listConfigurations' in store.getters.apis) }, + run: (store, router) => { + router.push({ name: 'globalsetting' }) + return false + } + } + ] + } + ], actions: [ { api: 'createKubernetesCluster', diff --git a/ui/src/utils/acsrepo/index.js b/ui/src/utils/acsrepo/index.js new file mode 100644 index 000000000000..809bd7f17483 --- /dev/null +++ b/ui/src/utils/acsrepo/index.js @@ -0,0 +1,81 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +const BASE_KUBERNETES_ISO_URL = 'https://download.cloudstack.org/cks/' + +function getDefaultLatestKubernetesIsoParams (arch) { + return { + name: 'v1.33.1-calico-' + arch, + semanticversion: '1.33.1', + url: BASE_KUBERNETES_ISO_URL + 'setup-v1.33.1-calico-' + arch + '.iso', + arch: arch, + mincpunumber: 2, + minmemory: 2048 + } +} + +/** + * Returns the latest Kubernetes ISO info for the given architecture. + * Falls back to a hardcoded default if fetching fails. + * @param {string} arch + * @returns {Promise<{name: string, semanticversion: string, url: string, arch: string}>} + */ +export async function getLatestKubernetesIsoParams (arch) { + arch = arch || 'x86_64' + try { + const html = await fetch(BASE_KUBERNETES_ISO_URL, { cache: 'no-store' }).then(r => r.text()) + + const hrefs = [...html.matchAll(/href="([^"]+\.iso)"/gi)].map(m => m[1]) + + // Prefer files that explicitly include the arch (e.g. ...-x86_64.iso) + let isoHrefs = hrefs.filter(h => new RegExp(`${arch}\\.iso$`, 'i').test(h)) + + // Fallback: older files without arch suffix (e.g. setup-1.28.4.iso) + if (isoHrefs.length === 0) { + isoHrefs = hrefs.filter(h => /setup-\d+\.\d+\.\d+\.iso$/i.test(h)) + } + + const entries = isoHrefs.map(h => { + const m = h.match(/setup-(?:v)?(\d+\.\d+\.\d+)(?:-calico)?(?:-(x86_64|arm64))?/i) + return m + ? { + name: h.replace('.iso', ''), + semanticversion: m[1], + url: new URL(h, BASE_KUBERNETES_ISO_URL).toString(), + arch: m[2] || arch, + mincpunumber: 2, + minmemory: 2048 + } + : null + }).filter(Boolean) + + if (entries.length === 0) throw new Error('No matching ISOs found') + + entries.sort((a, b) => { + const pa = a.semanticversion.split('.').map(Number) + const pb = b.semanticversion.split('.').map(Number) + for (let i = 0; i < 3; i++) { + if ((pb[i] ?? 0) !== (pa[i] ?? 0)) return (pb[i] ?? 0) - (pa[i] ?? 0) + } + return 0 + }) + + return entries[0] + } catch { + return { ...getDefaultLatestKubernetesIsoParams(arch) } + } +} diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue index e0583cd97a4e..cfbaf580507d 100644 --- a/ui/src/views/AutogenView.vue +++ b/ui/src/views/AutogenView.vue @@ -540,6 +540,9 @@ class="row-element" v-else > + Date: Thu, 29 Jan 2026 13:52:07 +0530 Subject: [PATCH 085/101] api,server: apis return their http request type (#11382) * api,server: apis return their http request type Signed-off-by: Abhishek Kumar * fix and unit test Signed-off-by: Abhishek Kumar * more test Signed-off-by: Abhishek Kumar * address copilot Signed-off-by: Abhishek Kumar * Update plugins/api/discovery/src/main/java/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java --------- Signed-off-by: Abhishek Kumar Co-authored-by: dahn Co-authored-by: Harikrishna --- .../org/apache/cloudstack/api/APICommand.java | 2 + .../apache/cloudstack/api/ApiConstants.java | 1 + ...ntAllowedToCreateOfferingsWithTagsCmd.java | 3 +- .../api/response/ApiDiscoveryResponse.java | 13 ++ .../discovery/ApiDiscoveryServiceImpl.java | 9 +- .../ApiDiscoveryServiceImplTest.java | 123 +++++++++++++++ .../api/command/QuotaBalanceCmd.java | 3 +- .../api/command/QuotaEnabledCmd.java | 3 +- .../api/command/QuotaStatementCmd.java | 3 +- .../api/command/QuotaSummaryCmd.java | 3 +- .../api/command/QuotaTariffListCmd.java | 3 +- .../cloudian/api/CloudianIsEnabledCmd.java | 3 +- .../api/command/ReadyForShutdownCmd.java | 3 +- .../command/VerifyOAuthCodeAndGetUserCmd.java | 14 +- .../main/java/com/cloud/api/ApiServlet.java | 46 ++++-- .../java/com/cloud/api/ApiServletTest.java | 143 ++++++++++++++---- 16 files changed, 319 insertions(+), 56 deletions(-) create mode 100644 plugins/api/discovery/src/test/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImplTest.java diff --git a/api/src/main/java/org/apache/cloudstack/api/APICommand.java b/api/src/main/java/org/apache/cloudstack/api/APICommand.java index c559be081165..b77649046ca9 100644 --- a/api/src/main/java/org/apache/cloudstack/api/APICommand.java +++ b/api/src/main/java/org/apache/cloudstack/api/APICommand.java @@ -50,4 +50,6 @@ RoleType[] authorized() default {}; Class[] entityType() default {}; + + String httpMethod() default ""; } diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index 2e0e843b5354..d00e339de2fd 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -282,6 +282,7 @@ public class ApiConstants { public static final String HOST = "host"; public static final String HOST_CONTROL_STATE = "hostcontrolstate"; public static final String HOSTS_MAP = "hostsmap"; + public static final String HTTP_REQUEST_TYPE = "httprequesttype"; public static final String HYPERVISOR = "hypervisor"; public static final String INLINE = "inline"; public static final String INSTANCE = "instance"; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/IsAccountAllowedToCreateOfferingsWithTagsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/IsAccountAllowedToCreateOfferingsWithTagsCmd.java index fcd6b03d3e59..4b1cd2ff7255 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/IsAccountAllowedToCreateOfferingsWithTagsCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/IsAccountAllowedToCreateOfferingsWithTagsCmd.java @@ -26,7 +26,8 @@ import org.apache.cloudstack.api.response.IsAccountAllowedToCreateOfferingsWithTagsResponse; @APICommand(name = "isAccountAllowedToCreateOfferingsWithTags", description = "Return true if the specified account is allowed to create offerings with tags.", - responseObject = IsAccountAllowedToCreateOfferingsWithTagsResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) + responseObject = IsAccountAllowedToCreateOfferingsWithTagsResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, + httpMethod = "GET") public class IsAccountAllowedToCreateOfferingsWithTagsCmd extends BaseCmd { @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "Account UUID", required = true) diff --git a/plugins/api/discovery/src/main/java/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java b/plugins/api/discovery/src/main/java/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java index 4b243f2e8a1a..90b3b89d3fb5 100644 --- a/plugins/api/discovery/src/main/java/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java +++ b/plugins/api/discovery/src/main/java/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java @@ -59,6 +59,10 @@ public class ApiDiscoveryResponse extends BaseResponse { @Param(description = "Response field type") private String type; + @SerializedName(ApiConstants.HTTP_REQUEST_TYPE) + @Param(description = "Preferred HTTP request type for the API", since = "4.23.0") + private String httpRequestType; + public ApiDiscoveryResponse() { params = new HashSet(); apiResponse = new HashSet(); @@ -74,6 +78,7 @@ public ApiDiscoveryResponse(ApiDiscoveryResponse another) { this.params = new HashSet<>(another.getParams()); this.apiResponse = new HashSet<>(another.getApiResponse()); this.type = another.getType(); + this.httpRequestType = another.getHttpRequestType(); this.setObjectName(another.getObjectName()); } @@ -140,4 +145,12 @@ public Set getApiResponse() { public String getType() { return type; } + + public String getHttpRequestType() { + return httpRequestType; + } + + public void setHttpRequestType(String httpRequestType) { + this.httpRequestType = httpRequestType; + } } diff --git a/plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java b/plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java index 452b95cf2c05..d6d235162efb 100644 --- a/plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java +++ b/plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java @@ -50,6 +50,7 @@ import org.reflections.ReflectionUtils; import org.springframework.stereotype.Component; +import com.cloud.api.ApiServlet; import com.cloud.exception.PermissionDeniedException; import com.cloud.serializer.Param; import com.cloud.user.Account; @@ -189,7 +190,7 @@ private ApiResponseResponse getFieldResponseMap(Field responseField) { return responseResponse; } - private ApiDiscoveryResponse getCmdRequestMap(Class cmdClass, APICommand apiCmdAnnotation) { + protected ApiDiscoveryResponse getCmdRequestMap(Class cmdClass, APICommand apiCmdAnnotation) { String apiName = apiCmdAnnotation.name(); ApiDiscoveryResponse response = new ApiDiscoveryResponse(); response.setName(apiName); @@ -197,6 +198,12 @@ private ApiDiscoveryResponse getCmdRequestMap(Class cmdClass, APICommand apiC if (!apiCmdAnnotation.since().isEmpty()) { response.setSince(apiCmdAnnotation.since()); } + String httpRequestType = apiCmdAnnotation.httpMethod(); + if (StringUtils.isBlank(httpRequestType)) { + httpRequestType = ApiServlet.GET_REQUEST_COMMANDS.matcher(apiName.toLowerCase()).matches() ? + "GET" : "POST"; + } + response.setHttpRequestType(httpRequestType); Set fields = ReflectUtil.getAllFieldsForClass(cmdClass, new Class[] {BaseCmd.class, BaseAsyncCmd.class, BaseAsyncCreateCmd.class}); diff --git a/plugins/api/discovery/src/test/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImplTest.java b/plugins/api/discovery/src/test/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImplTest.java new file mode 100644 index 000000000000..e69b9523d449 --- /dev/null +++ b/plugins/api/discovery/src/test/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImplTest.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.discovery; + +import static org.mockito.ArgumentMatchers.any; + +import java.lang.reflect.Field; +import java.util.Set; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.command.admin.account.CreateAccountCmd; +import org.apache.cloudstack.api.command.admin.user.GetUserCmd; +import org.apache.cloudstack.api.command.user.discovery.ListApisCmd; +import org.apache.cloudstack.api.response.ApiDiscoveryResponse; +import org.apache.cloudstack.api.response.ApiParameterResponse; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import com.cloud.utils.ReflectUtil; + +@RunWith(MockitoJUnitRunner.class) +public class ApiDiscoveryServiceImplTest { + + @Mock + APICommand apiCommandMock; + + @Spy + @InjectMocks + ApiDiscoveryServiceImpl discoveryServiceSpy; + + @Before + public void setUp() { + Mockito.when(apiCommandMock.name()).thenReturn("listApis"); + Mockito.when(apiCommandMock.since()).thenReturn(""); + } + + @Test + public void getCmdRequestMapReturnsResponseWithCorrectApiNameAndDescription() { + Mockito.when(apiCommandMock.description()).thenReturn("Lists all APIs"); + ApiDiscoveryResponse response = discoveryServiceSpy.getCmdRequestMap(ListApisCmd.class, apiCommandMock); + Assert.assertEquals("listApis", response.getName()); + Assert.assertEquals("Lists all APIs", response.getDescription()); + } + + @Test + public void getCmdRequestMapSetsHttpRequestTypeToGetWhenApiNameMatchesGetPattern() { + Mockito.when(apiCommandMock.name()).thenReturn("getUser"); + Mockito.when(apiCommandMock.httpMethod()).thenReturn(""); + ApiDiscoveryResponse response = discoveryServiceSpy.getCmdRequestMap(GetUserCmd.class, apiCommandMock); + Assert.assertEquals("GET", response.getHttpRequestType()); + } + + @Test + public void getCmdRequestMapSetsHttpRequestTypeToPostWhenApiNameDoesNotMatchGetPattern() { + Mockito.when(apiCommandMock.name()).thenReturn("createAccount"); + Mockito.when(apiCommandMock.httpMethod()).thenReturn(""); + ApiDiscoveryResponse response = discoveryServiceSpy.getCmdRequestMap(CreateAccountCmd.class, apiCommandMock); + Assert.assertEquals("POST", response.getHttpRequestType()); + } + + @Test + public void getCmdRequestMapSetsAsyncToTrueForAsyncCommand() { + Mockito.when(apiCommandMock.name()).thenReturn("asyncApi"); + ApiDiscoveryResponse response = discoveryServiceSpy.getCmdRequestMap(BaseAsyncCmd.class, apiCommandMock); + Assert.assertTrue(response.getAsync()); + } + + @Test + public void getCmdRequestMapDoesNotAddParamsWithoutParameterAnnotation() { + ApiDiscoveryResponse response = discoveryServiceSpy.getCmdRequestMap(BaseCmd.class, apiCommandMock); + Assert.assertFalse(response.getParams().isEmpty()); + Assert.assertEquals(1, response.getParams().size()); + } + + @Test + public void getCmdRequestMapAddsParamsWithExposedAndIncludedInApiDocAnnotations() { + Field fieldMock = Mockito.mock(Field.class); + Parameter parameterMock = Mockito.mock(Parameter.class); + Mockito.when(parameterMock.expose()).thenReturn(true); + Mockito.when(parameterMock.includeInApiDoc()).thenReturn(true); + Mockito.when(parameterMock.name()).thenReturn("paramName"); + Mockito.when(parameterMock.since()).thenReturn(""); + Mockito.when(parameterMock.entityType()).thenReturn(new Class[]{Object.class}); + Mockito.when(parameterMock.description()).thenReturn("paramDescription"); + Mockito.when(parameterMock.type()).thenReturn(BaseCmd.CommandType.STRING); + Mockito.when(fieldMock.getAnnotation(Parameter.class)).thenReturn(parameterMock); + try (MockedStatic reflectUtilMockedStatic = Mockito.mockStatic(ReflectUtil.class)) { + reflectUtilMockedStatic.when(() -> ReflectUtil.getAllFieldsForClass(any(Class.class), any(Class[].class))) + .thenReturn(Set.of(fieldMock)); + ApiDiscoveryResponse response = discoveryServiceSpy.getCmdRequestMap(ListApisCmd.class, apiCommandMock); + Set params = response.getParams(); + Assert.assertEquals(1, params.size()); + ApiParameterResponse paramResponse = params.iterator().next(); + Assert.assertEquals("paramName", ReflectionTestUtils.getField(paramResponse, "name")); + } + } +} diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaBalanceCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaBalanceCmd.java index cf39f802d34f..0cec0df66182 100644 --- a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaBalanceCmd.java +++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaBalanceCmd.java @@ -35,7 +35,8 @@ import org.apache.cloudstack.quota.vo.QuotaBalanceVO; import org.apache.cloudstack.api.response.QuotaStatementItemResponse; -@APICommand(name = "quotaBalance", responseObject = QuotaStatementItemResponse.class, description = "Create a quota balance statement", since = "4.7.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +@APICommand(name = "quotaBalance", responseObject = QuotaStatementItemResponse.class, description = "Create a quota balance statement", since = "4.7.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, + httpMethod = "GET") public class QuotaBalanceCmd extends BaseCmd { diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaEnabledCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaEnabledCmd.java index 4035a5205e6c..af1d146ea9dc 100644 --- a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaEnabledCmd.java +++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaEnabledCmd.java @@ -26,7 +26,8 @@ import javax.inject.Inject; -@APICommand(name = "quotaIsEnabled", responseObject = QuotaEnabledResponse.class, description = "Return true if the plugin is enabled", since = "4.7.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +@APICommand(name = "quotaIsEnabled", responseObject = QuotaEnabledResponse.class, description = "Return true if the plugin is enabled", since = "4.7.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, + httpMethod = "GET") public class QuotaEnabledCmd extends BaseCmd { diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaStatementCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaStatementCmd.java index 18f9bc48a6e2..d3bd3868ed16 100644 --- a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaStatementCmd.java +++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaStatementCmd.java @@ -35,7 +35,8 @@ import com.cloud.user.Account; -@APICommand(name = "quotaStatement", responseObject = QuotaStatementItemResponse.class, description = "Create a quota statement", since = "4.7.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +@APICommand(name = "quotaStatement", responseObject = QuotaStatementItemResponse.class, description = "Create a quota statement", since = "4.7.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, + httpMethod = "GET") public class QuotaStatementCmd extends BaseCmd { diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaSummaryCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaSummaryCmd.java index 42a598042b39..87322b01f4d4 100644 --- a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaSummaryCmd.java +++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaSummaryCmd.java @@ -33,7 +33,8 @@ import javax.inject.Inject; -@APICommand(name = "quotaSummary", responseObject = QuotaSummaryResponse.class, description = "Lists balance and quota usage for all Accounts", since = "4.7.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +@APICommand(name = "quotaSummary", responseObject = QuotaSummaryResponse.class, description = "Lists balance and quota usage for all Accounts", since = "4.7.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, + httpMethod = "GET") public class QuotaSummaryCmd extends BaseListCmd { @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required = false, description = "Optional, Account Id for which statement needs to be generated") diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffListCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffListCmd.java index d054d5459313..e0bab07501b6 100644 --- a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffListCmd.java +++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffListCmd.java @@ -38,7 +38,8 @@ import java.util.Date; import java.util.List; -@APICommand(name = "quotaTariffList", responseObject = QuotaTariffResponse.class, description = "Lists all quota tariff plans", since = "4.7.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +@APICommand(name = "quotaTariffList", responseObject = QuotaTariffResponse.class, description = "Lists all quota tariff plans", since = "4.7.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, + httpMethod = "GET") public class QuotaTariffListCmd extends BaseListCmd { @Inject diff --git a/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/api/CloudianIsEnabledCmd.java b/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/api/CloudianIsEnabledCmd.java index 56cb74e3cab7..3c334ba55c2e 100644 --- a/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/api/CloudianIsEnabledCmd.java +++ b/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/api/CloudianIsEnabledCmd.java @@ -31,7 +31,8 @@ responseObject = CloudianEnabledResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.11.0", - authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User}) + authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User}, + httpMethod = "GET") public class CloudianIsEnabledCmd extends BaseCmd { @Inject diff --git a/plugins/maintenance/src/main/java/org/apache/cloudstack/api/command/ReadyForShutdownCmd.java b/plugins/maintenance/src/main/java/org/apache/cloudstack/api/command/ReadyForShutdownCmd.java index 782b23a04222..36ec4fff9c95 100644 --- a/plugins/maintenance/src/main/java/org/apache/cloudstack/api/command/ReadyForShutdownCmd.java +++ b/plugins/maintenance/src/main/java/org/apache/cloudstack/api/command/ReadyForShutdownCmd.java @@ -26,7 +26,8 @@ description = "Returns the status of CloudStack, whether a shutdown has been triggered and if ready to shutdown", since = "4.19.0", responseObject = ManagementServerMaintenanceResponse.class, - requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, + httpMethod = "GET") public class ReadyForShutdownCmd extends BaseMSMaintenanceActionCmd { public static final String APINAME = "readyForShutdown"; diff --git a/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/VerifyOAuthCodeAndGetUserCmd.java b/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/VerifyOAuthCodeAndGetUserCmd.java index bd49f87d6273..b3d2d335ba25 100644 --- a/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/VerifyOAuthCodeAndGetUserCmd.java +++ b/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/VerifyOAuthCodeAndGetUserCmd.java @@ -20,8 +20,10 @@ import java.util.List; import java.util.Map; -import com.cloud.api.response.ApiResponseSerializer; -import com.cloud.user.Account; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -37,13 +39,13 @@ import org.apache.cloudstack.oauth2.api.response.OauthProviderResponse; import org.apache.commons.lang.ArrayUtils; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import com.cloud.api.response.ApiResponseSerializer; +import com.cloud.user.Account; @APICommand(name = "verifyOAuthCodeAndGetUser", description = "Verify the OAuth Code and fetch the corresponding user from provider", responseObject = OauthProviderResponse.class, entityType = {}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, - authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User}, since = "4.19.0") + authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User}, since = "4.19.0", + httpMethod = "GET") public class VerifyOAuthCodeAndGetUserCmd extends BaseListCmd implements APIAuthenticator { ///////////////////////////////////////////////////// diff --git a/server/src/main/java/com/cloud/api/ApiServlet.java b/server/src/main/java/com/cloud/api/ApiServlet.java index db17daaf146b..158df2240717 100644 --- a/server/src/main/java/com/cloud/api/ApiServlet.java +++ b/server/src/main/java/com/cloud/api/ApiServlet.java @@ -25,8 +25,8 @@ import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.regex.Pattern; import java.util.Set; +import java.util.regex.Pattern; import javax.inject.Inject; import javax.servlet.ServletConfig; @@ -52,10 +52,9 @@ import org.apache.cloudstack.managed.context.ManagedContext; import org.apache.cloudstack.utils.consoleproxy.ConsoleAccessUtils; import org.apache.commons.collections.MapUtils; - -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; import org.apache.commons.lang3.EnumUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.Nullable; import org.springframework.stereotype.Component; import org.springframework.web.context.support.SpringBeanAutowiringSupport; @@ -70,12 +69,12 @@ import com.cloud.user.AccountService; import com.cloud.user.User; import com.cloud.user.UserAccount; - import com.cloud.utils.HttpUtils; -import com.cloud.utils.HttpUtils.ApiSessionKeySameSite; import com.cloud.utils.HttpUtils.ApiSessionKeyCheckOption; +import com.cloud.utils.HttpUtils.ApiSessionKeySameSite; import com.cloud.utils.StringUtils; import com.cloud.utils.db.EntityManager; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; @Component("apiServlet") @@ -84,9 +83,7 @@ public class ApiServlet extends HttpServlet { private static final Logger ACCESSLOGGER = LogManager.getLogger("apiserver." + ApiServlet.class.getName()); private static final String REPLACEMENT = "_"; private static final String LOGGER_REPLACEMENTS = "[\n\r\t]"; - private static final Pattern GET_REQUEST_COMMANDS = Pattern.compile("^(get|list|query|find)(\\w+)+$"); - private static final HashSet GET_REQUEST_COMMANDS_LIST = new HashSet<>(Set.of("isaccountallowedtocreateofferingswithtags", - "readyforshutdown", "cloudianisenabled", "quotabalance", "quotasummary", "quotatarifflist", "quotaisenabled", "quotastatement", "verifyoauthcodeandgetuser")); + public static final Pattern GET_REQUEST_COMMANDS = Pattern.compile("^(get|list|query|find)(\\w+)+$"); private static final HashSet POST_REQUESTS_TO_DISABLE_LOGGING = new HashSet<>(Set.of( "login", "oauthlogin", @@ -367,7 +364,7 @@ void processRequestInContext(final HttpServletRequest req, final HttpServletResp } } - if (apiServer.isPostRequestsAndTimestampsEnforced() && !isStateChangingCommandUsingPOST(command, req.getMethod(), params)) { + if (apiServer.isPostRequestsAndTimestampsEnforced() && isStateChangingCommandNotUsingPOST(command, req.getMethod(), params)) { String errorText = String.format("State changing command %s needs to be sent using POST request", command); if (command.equalsIgnoreCase("updateConfiguration") && params.containsKey("name")) { errorText = String.format("Changes for configuration %s needs to be sent using POST request", params.get("name")[0]); @@ -485,13 +482,32 @@ private boolean checkIfAuthenticatorIsOf2FA(String command) { return verify2FA; } - private boolean isStateChangingCommandUsingPOST(String command, String method, Map params) { - if (command == null || (!GET_REQUEST_COMMANDS.matcher(command.toLowerCase()).matches() && !GET_REQUEST_COMMANDS_LIST.contains(command.toLowerCase()) - && !command.equalsIgnoreCase("updateConfiguration") && !method.equals("POST"))) { + protected boolean isStateChangingCommandNotUsingPOST(String command, String method, Map params) { + if (BaseCmd.HTTPMethod.POST.toString().equalsIgnoreCase(method)) { + return false; + } + if (command == null || method == null) { + return true; + } + String commandHttpMethod = null; + try { + Class cmdClass = apiServer.getCmdClass(command); + if (cmdClass != null) { + APICommand at = cmdClass.getAnnotation(APICommand.class); + if (at != null && org.apache.commons.lang3.StringUtils.isNotBlank(at.httpMethod())) { + commandHttpMethod = at.httpMethod(); + } + } + } catch (CloudRuntimeException e) { + LOGGER.trace("Command class not found for {}; falling back to pattern match", command, e); + } + if (BaseCmd.HTTPMethod.GET.toString().equalsIgnoreCase(commandHttpMethod) || + GET_REQUEST_COMMANDS.matcher(command.toLowerCase()).matches()) { return false; } - return !command.equalsIgnoreCase("updateConfiguration") || method.equals("POST") || (params.containsKey("name") - && params.get("name")[0].toString().equalsIgnoreCase(ApiServer.EnforcePostRequestsAndTimestamps.key())); + return !command.equalsIgnoreCase("updateConfiguration") || + !params.containsKey("name") || + !ApiServer.EnforcePostRequestsAndTimestamps.key().equalsIgnoreCase(params.get("name")[0].toString()); } protected boolean skip2FAcheckForAPIs(String command) { diff --git a/server/src/test/java/com/cloud/api/ApiServletTest.java b/server/src/test/java/com/cloud/api/ApiServletTest.java index 79fe4b86f859..c5ee9f58154d 100644 --- a/server/src/test/java/com/cloud/api/ApiServletTest.java +++ b/server/src/test/java/com/cloud/api/ApiServletTest.java @@ -16,22 +16,30 @@ // under the License. package com.cloud.api; -import com.cloud.api.auth.ListUserTwoFactorAuthenticatorProvidersCmd; -import com.cloud.api.auth.SetupUserTwoFactorAuthenticationCmd; -import com.cloud.api.auth.ValidateUserTwoFactorAuthenticationCodeCmd; -import com.cloud.server.ManagementServer; -import com.cloud.user.Account; -import com.cloud.user.AccountManagerImpl; -import com.cloud.user.AccountService; -import com.cloud.user.User; -import com.cloud.user.UserAccount; -import com.cloud.utils.HttpUtils; -import com.cloud.vm.UserVmManager; +import static org.mockito.ArgumentMatchers.nullable; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.net.InetAddress; +import java.net.URLEncoder; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.auth.APIAuthenticationManager; import org.apache.cloudstack.api.auth.APIAuthenticationType; import org.apache.cloudstack.api.auth.APIAuthenticator; import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd; +import org.apache.cloudstack.api.command.admin.offering.IsAccountAllowedToCreateOfferingsWithTagsCmd; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.impl.ConfigDepotImpl; import org.junit.After; @@ -43,25 +51,24 @@ import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Field; -import java.net.InetAddress; -import java.net.URLEncoder; -import java.net.UnknownHostException; -import java.util.HashMap; -import java.util.Map; - -import static org.mockito.ArgumentMatchers.nullable; +import com.cloud.api.auth.ListUserTwoFactorAuthenticatorProvidersCmd; +import com.cloud.api.auth.SetupUserTwoFactorAuthenticationCmd; +import com.cloud.api.auth.ValidateUserTwoFactorAuthenticationCodeCmd; +import com.cloud.server.ManagementServer; +import com.cloud.user.Account; +import com.cloud.user.AccountManagerImpl; +import com.cloud.user.AccountService; +import com.cloud.user.User; +import com.cloud.user.UserAccount; +import com.cloud.utils.HttpUtils; +import com.cloud.vm.UserVmManager; @RunWith(MockitoJUnitRunner.class) public class ApiServletTest { + private static final String[] STATE_CHANGING_COMMAND_CHECK_NAME_PARAM = + {ApiServer.EnforcePostRequestsAndTimestamps.key()}; + @Mock ApiServer apiServer; @@ -461,4 +468,88 @@ public void testVerify2FAWhenExpectedCommandIsNotCalled() throws UnknownHostExce Assert.assertEquals(false, result); } + + @Test + public void isStateChangingCommandNotUsingPOSTReturnsFalseForPostMethod() { + String command = "updateConfiguration"; + String method = "POST"; + Map params = new HashMap<>(); + + boolean result = servlet.isStateChangingCommandNotUsingPOST(command, method, params); + + Assert.assertFalse(result); + } + + @Test + public void isStateChangingCommandNotUsingPOSTReturnsTrueForNullCommandAndMethod() { + String command = null; + String method = null; + Map params = new HashMap<>(); + + boolean result = servlet.isStateChangingCommandNotUsingPOST(command, method, params); + + Assert.assertTrue(result); + } + + @Test + public void isStateChangingCommandNotUsingPOSTReturnsFalseForGetHttpMethodAnnotation() { + String command = "isAccountAllowedToCreateOfferingsWithTags"; + String method = "GET"; + Map params = new HashMap<>(); + Class cmdClass = IsAccountAllowedToCreateOfferingsWithTagsCmd.class; + APICommand apiCommand = cmdClass.getAnnotation(APICommand.class); + Mockito.doReturn(cmdClass).when(apiServer).getCmdClass(command); + Assert.assertNotNull(apiCommand); + Assert.assertEquals("GET", apiCommand.httpMethod()); + boolean result = servlet.isStateChangingCommandNotUsingPOST(command, method, params); + Assert.assertFalse(result); + } + + @Test + public void isStateChangingCommandNotUsingPOSTReturnsFalseForMatchingGetRequestPattern() { + String command = "listZones"; + String method = "GET"; + Map params = new HashMap<>(); + boolean result = servlet.isStateChangingCommandNotUsingPOST(command, method, params); + Assert.assertFalse(result); + } + + @Test + public void isStateChangingCommandNotUsingPOSTReturnsTrueForMissingNameParameter() { + String command = "updateConfiguration"; + String method = "GET"; + Map params = new HashMap<>(); + boolean result = servlet.isStateChangingCommandNotUsingPOST(command, method, params); + Assert.assertTrue(result); + } + + @Test + public void isStateChangingCommandNotUsingPOSTReturnsFalseForUpdateConfigurationEnforcePostRequestsKey() { + String command = "updateConfiguration"; + String method = "GET"; + Map params = new HashMap<>(); + params.put("name", STATE_CHANGING_COMMAND_CHECK_NAME_PARAM); + boolean result = servlet.isStateChangingCommandNotUsingPOST(command, method, params); + Assert.assertFalse(result); + } + + @Test + public void isStateChangingCommandNotUsingPOSTReturnsFalseForWrongApiEnforcePostRequestsKey() { + String command = "updateSomeApi"; + String method = "GET"; + Map params = new HashMap<>(); + params.put("name", STATE_CHANGING_COMMAND_CHECK_NAME_PARAM); + boolean result = servlet.isStateChangingCommandNotUsingPOST(command, method, params); + Assert.assertTrue(result); + } + + @Test + public void isStateChangingCommandNotUsingPOSTReturnsFalseForUpdateConfigurationNonEnforcePostRequestsKey() { + String command = "updateConfiguration"; + String method = "GET"; + Map params = new HashMap<>(); + params.put("name", new String[] { "key" }); + boolean result = servlet.isStateChangingCommandNotUsingPOST(command, method, params); + Assert.assertTrue(result); + } } From c681d0d0a2f53a7ef52de5cc2a4bb0d7d2aa864a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernardo=20De=20Marco=20Gon=C3=A7alves?= Date: Thu, 29 Jan 2026 06:01:54 -0300 Subject: [PATCH 086/101] Change `vmsnapshot.max` setting scope to the account level (#11616) --- .../com/cloud/vm/snapshot/VMSnapshotManager.java | 2 +- .../cloud/vm/snapshot/VMSnapshotManagerImpl.java | 7 ++++--- .../cloud/vm/snapshot/VMSnapshotManagerTest.java | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/engine/components-api/src/main/java/com/cloud/vm/snapshot/VMSnapshotManager.java b/engine/components-api/src/main/java/com/cloud/vm/snapshot/VMSnapshotManager.java index 6478469f190c..6831552b83db 100644 --- a/engine/components-api/src/main/java/com/cloud/vm/snapshot/VMSnapshotManager.java +++ b/engine/components-api/src/main/java/com/cloud/vm/snapshot/VMSnapshotManager.java @@ -31,7 +31,7 @@ public interface VMSnapshotManager extends VMSnapshotService, Manager { static final ConfigKey VMSnapshotExpireInterval = new ConfigKey("Advanced", Integer.class, "vmsnapshot.expire.interval", "-1", "VM Snapshot expire interval in hours", true, ConfigKey.Scope.Account); - ConfigKey VMSnapshotMax = new ConfigKey("Advanced", Integer.class, "vmsnapshot.max", "10", "Maximum vm snapshots for a single vm", true, ConfigKey.Scope.Global); + ConfigKey VMSnapshotMax = new ConfigKey("Advanced", Integer.class, "vmsnapshot.max", "10", "Maximum VM snapshots for a single VM", true, ConfigKey.Scope.Account); /** * Delete all VM snapshots belonging to one VM diff --git a/server/src/main/java/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/main/java/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java index 617a4e54a6e4..d5e25adcd5fa 100644 --- a/server/src/main/java/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -400,10 +400,11 @@ public VMSnapshot allocVMSnapshot(Long vmId, String vsDisplayName, String vsDesc _accountMgr.checkAccess(caller, null, true, userVmVo); // check max snapshot limit for per VM - int vmSnapshotMax = VMSnapshotManager.VMSnapshotMax.value(); - + boolean vmBelongsToProject = _accountMgr.getAccount(userVmVo.getAccountId()).getType() == Account.Type.PROJECT; + long accountIdToRetrieveConfigurationValueFrom = vmBelongsToProject ? caller.getId() : userVmVo.getAccountId(); + int vmSnapshotMax = VMSnapshotManager.VMSnapshotMax.valueIn(accountIdToRetrieveConfigurationValueFrom); if (_vmSnapshotDao.findByVm(vmId).size() >= vmSnapshotMax) { - throw new CloudRuntimeException("Creating Instance Snapshot failed due to a Instance can just have : " + vmSnapshotMax + " Instance Snapshots. Please delete old ones"); + throw new CloudRuntimeException(String.format("Each VM can have at most [%s] VM snapshots.", vmSnapshotMax)); } // check if there are active volume snapshots tasks diff --git a/server/src/test/java/com/cloud/vm/snapshot/VMSnapshotManagerTest.java b/server/src/test/java/com/cloud/vm/snapshot/VMSnapshotManagerTest.java index a0f09981a401..b696d743ac64 100644 --- a/server/src/test/java/com/cloud/vm/snapshot/VMSnapshotManagerTest.java +++ b/server/src/test/java/com/cloud/vm/snapshot/VMSnapshotManagerTest.java @@ -41,6 +41,7 @@ import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; import com.cloud.uservm.UserVm; @@ -136,6 +137,8 @@ public class VMSnapshotManagerTest { VMSnapshotDetailsDao _vmSnapshotDetailsDao; @Mock UserVmManager _userVmManager; + @Mock + private AccountVO accountVOMock; private static final long TEST_VM_ID = 3L; private static final long SERVICE_OFFERING_ID = 1L; @@ -285,8 +288,12 @@ public void testCreateVMSnapshotF3() throws AgentUnavailableException, Operation @SuppressWarnings("unchecked") @Test(expected = CloudRuntimeException.class) public void testAllocVMSnapshotF4() throws ResourceAllocationException { + long accountId = 1L; List mockList = mock(List.class); when(mockList.size()).thenReturn(10); + when(_userVMDao.findById(TEST_VM_ID)).thenReturn(vmMock); + when(userVm.getAccountId()).thenReturn(accountId); + when(_accountMgr.getAccount(accountId)).thenReturn(accountVOMock); when(_vmSnapshotDao.findByVm(TEST_VM_ID)).thenReturn(mockList); _vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID, "", "", true); } @@ -295,8 +302,12 @@ public void testAllocVMSnapshotF4() throws ResourceAllocationException { @SuppressWarnings("unchecked") @Test(expected = CloudRuntimeException.class) public void testAllocVMSnapshotF5() throws ResourceAllocationException { + long accountId = 1L; List mockList = mock(List.class); when(mockList.size()).thenReturn(1); + when(_userVMDao.findById(TEST_VM_ID)).thenReturn(vmMock); + when(userVm.getAccountId()).thenReturn(accountId); + when(_accountMgr.getAccount(accountId)).thenReturn(accountVOMock); when(_snapshotDao.listByInstanceId(TEST_VM_ID, Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp)).thenReturn(mockList); _vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID, "", "", true); } @@ -304,6 +315,10 @@ public void testAllocVMSnapshotF5() throws ResourceAllocationException { // successful creation case @Test public void testCreateVMSnapshot() throws AgentUnavailableException, OperationTimedoutException, ResourceAllocationException, NoTransitionException { + long accountId = 1L; + when(_userVMDao.findById(TEST_VM_ID)).thenReturn(vmMock); + when(userVm.getAccountId()).thenReturn(accountId); + when(_accountMgr.getAccount(accountId)).thenReturn(accountVOMock); when(vmMock.getState()).thenReturn(State.Running); _vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID, "", "", true); } From 0b62fb5e20c27116f11bd8af72255b45d5703c02 Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Thu, 29 Jan 2026 16:06:19 +0530 Subject: [PATCH 087/101] Add cloud image downloader script (#11918) --- tools/utils/cloud-image-downloader.sh | 259 ++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100755 tools/utils/cloud-image-downloader.sh diff --git a/tools/utils/cloud-image-downloader.sh b/tools/utils/cloud-image-downloader.sh new file mode 100755 index 000000000000..90f234906e1a --- /dev/null +++ b/tools/utils/cloud-image-downloader.sh @@ -0,0 +1,259 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#------------------------------------------------------------------------------- +# Configuration +#------------------------------------------------------------------------------- +# This section contains the variables you might want to change. + +# The temporary directory where files will be downloaded. +# It's a good practice to create a unique temporary directory for each script run. +TEMP_DIR=$(mktemp -d) + +# The BASE destination directory for the downloaded image files. +# Subdirectories for each distro will be created inside this one. +# Make sure this directory exists before running the script. +# Must be executed by the cloudstack user on machine hosting the public download site. +# It will be publicly available at https://download.cloudstack.org/templates/cloud-images/ +DEST_DIR="${HOME}/repository/templates/cloud-images" + +# The directory where log files will be stored. +# Make sure this directory exists. +LOG_DIR="${HOME}/log/cloud-image-downloader" +LOG_FILE="${LOG_DIR}/cloud-image-downloader_$(date +%Y%m%d_%H%M%S).log" +LOG_RETENTION_DAYS=30 + +LOGGER_TAG="cloud-image-downloader" +LOGGER_FACILITY="user" +LOGGER_AVAILABLE=false + +log_message() { + local priority=$1 + shift + local message="$*" + local timestamp=$(date +'%Y-%m-%d %H:%M:%S') + + # Log to file + echo "${timestamp} [${priority}] ${message}" | tee -a "${LOG_FILE}" + + # Log to syslog using logger utility + if [ "${LOGGER_AVAILABLE}" = true ]; then + logger -t "${LOGGER_TAG}" -p "${LOGGER_FACILITY}.${priority}" -- "${message}" + fi +} + +log_info() { + log_message "info" "$@" +} + +log_warn() { + log_message "warning" "$@" +} + +log_error() { + log_message "err" "$@" +} + +cleanup_old_logs() { + log_info "Cleaning up log files older than ${LOG_RETENTION_DAYS} days..." + + if [ ! -d "$LOG_DIR" ]; then + log_warn "Log directory does not exist: $LOG_DIR" + return + fi + + local deleted_count=0 + + # Find and delete log files older than retention period + while IFS= read -r -d '' log_file; do + rm -f "$log_file" + deleted_count=$((deleted_count + 1)) + done < <(find "$LOG_DIR" -name "*.log" -type f -mtime +${LOG_RETENTION_DAYS} -print0 2>/dev/null) + + if [ $deleted_count -gt 0 ]; then + log_info "Deleted $deleted_count old log file(s)" + else + log_info "No old log files to delete" + fi +} + +#------------------------------------------------------------------------------- +# Image Definitions +#------------------------------------------------------------------------------- +# To add a new image, you must add an entry to BOTH arrays below. + +# 1. Add the destination filename and the download URL. +declare -A IMAGE_URLS=( + ["Rocky-9-GenericCloud.latest.x86_64.qcow2"]="https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2" + ["Rocky-9-GenericCloud.latest.aarch64.qcow2"]="https://dl.rockylinux.org/pub/rocky/9/images/aarch64/Rocky-9-GenericCloud.latest.aarch64.qcow2" + ["Rocky-8-GenericCloud.latest.x86_64.qcow2"]="https://dl.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud.latest.x86_64.qcow2" + ["Rocky-8-GenericCloud.latest.aarch64.qcow2"]="https://dl.rockylinux.org/pub/rocky/8/images/aarch64/Rocky-8-GenericCloud.latest.aarch64.qcow2" + ["openSUSE-Leap-15.5-Minimal-VM.x86_64-Cloud.qcow2"]="https://download.opensuse.org/distribution/leap/15.5/appliances/openSUSE-Leap-15.5-Minimal-VM.x86_64-Cloud.qcow2" + ["openSUSE-Leap-15.5-Minimal-VM.aarch64-Cloud.qcow2"]="https://download.opensuse.org/distribution/leap/15.5/appliances/openSUSE-Leap-15.5-Minimal-VM.aarch64-Cloud.qcow2" + ["debian-12-genericcloud-amd64.qcow2"]="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2" + ["debian-12-genericcloud-arm64.qcow2"]="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-arm64.qcow2" + ["ubuntu-24.04-server-cloudimg-amd64.img"]="https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img" + ["ubuntu-24.04-server-cloudimg-arm64.img"]="https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-arm64.img" + ["ubuntu-22.04-server-cloudimg-amd64.img"]="https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img" + ["ubuntu-22.04-server-cloudimg-arm64.img"]="https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-arm64.img" + ["ubuntu-20.04-server-cloudimg-amd64.img"]="https://cloud-images.ubuntu.com/releases/20.04/release/ubuntu-20.04-server-cloudimg-amd64.img" + ["ubuntu-20.04-server-cloudimg-arm64.img"]="https://cloud-images.ubuntu.com/releases/20.04/release/ubuntu-20.04-server-cloudimg-arm64.img" + ["OL9U5_x86_64-kvm-b259.qcow2"]="https://yum.oracle.com/templates/OracleLinux/OL9/u5/x86_64/OL9U5_x86_64-kvm-b259.qcow2" + ["OL9U5_aarch64-kvm-b126.qcow2"]="https://yum.oracle.com/templates/OracleLinux/OL9/u5/aarch64/OL9U5_aarch64-kvm-b126.qcow2" + ["OL8U10_x86_64-kvm-b258.qcow2"]="https://yum.oracle.com/templates/OracleLinux/OL8/u10/x86_64/OL8U10_x86_64-kvm-b258.qcow2" + ["OL8U10_aarch64-kvm-b122.qcow2"]="https://yum.oracle.com/templates/OracleLinux/OL8/u10/aarch64/OL8U10_aarch64-kvm-b122.qcow2" +) + +# 2. Add the destination filename and its corresponding distribution subdirectory name. +declare -A IMAGE_DISTROS=( + ["Rocky-9-GenericCloud.latest.x86_64.qcow2"]="rockylinux" + ["Rocky-9-GenericCloud.latest.aarch64.qcow2"]="rockylinux" + ["Rocky-8-GenericCloud.latest.x86_64.qcow2"]="rockylinux" + ["Rocky-8-GenericCloud.latest.aarch64.qcow2"]="rockylinux" + ["openSUSE-Leap-15.5-Minimal-VM.x86_64-Cloud.qcow2"]="opensuse" + ["openSUSE-Leap-15.5-Minimal-VM.aarch64-Cloud.qcow2"]="opensuse" + ["debian-12-genericcloud-amd64.qcow2"]="debian" + ["debian-12-genericcloud-arm64.qcow2"]="debian" + ["ubuntu-24.04-server-cloudimg-amd64.img"]="ubuntu" + ["ubuntu-24.04-server-cloudimg-arm64.img"]="ubuntu" + ["ubuntu-22.04-server-cloudimg-amd64.img"]="ubuntu" + ["ubuntu-22.04-server-cloudimg-arm64.img"]="ubuntu" + ["ubuntu-20.04-server-cloudimg-amd64.img"]="ubuntu" + ["ubuntu-20.04-server-cloudimg-arm64.img"]="ubuntu" + ["OL9U5_x86_64-kvm-b259.qcow2"]="oraclelinux" + ["OL9U5_aarch64-kvm-b126.qcow2"]="oraclelinux" + ["OL8U10_x86_64-kvm-b258.qcow2"]="oraclelinux" + ["OL8U10_aarch64-kvm-b122.qcow2"]="oraclelinux" +) + +#------------------------------------------------------------------------------- +# Cleanup Handler +#------------------------------------------------------------------------------- + +cleanup_on_exit() { + local exit_code=$? + if [ -d "$TEMP_DIR" ]; then + rm -rf "$TEMP_DIR" + log_info "Temporary directory $TEMP_DIR removed." + fi + + if [ $exit_code -ne 0 ]; then + log_error "Script exited with error code: $exit_code" + fi +} + +trap cleanup_on_exit EXIT INT TERM + +#------------------------------------------------------------------------------- +# Main Script Logic +#------------------------------------------------------------------------------- + +if command -v logger &> /dev/null; then + LOGGER_AVAILABLE=true +fi + +# Ensure base destination and log directories exist +mkdir -p "$DEST_DIR" +mkdir -p "$LOG_DIR" + +# Clean up old logs first +cleanup_old_logs + +log_info "Starting image download process." +log_info "Temporary directory: $TEMP_DIR" +log_info "Base destination directory: $DEST_DIR" +log_info "Log file: $LOG_FILE" + +# Inform about logger status +if [ "${LOGGER_AVAILABLE}" = true ]; then + log_info "Syslog logging enabled (tag: ${LOGGER_TAG})" +else + log_warn "Syslog logging disabled - logger utility not found" +fi + +# Loop through the image URLs +for filename in "${!IMAGE_URLS[@]}"; do + url="${IMAGE_URLS[$filename]}" + distro="${IMAGE_DISTROS[$filename]}" + + # Check if a distro is defined for the file + if [ -z "$distro" ]; then + log_error "No distribution directory defined for $filename. Skipping." + continue + fi + + distro_dest_dir="${DEST_DIR}/${distro}" + temp_filepath="${TEMP_DIR}/${filename}" + dest_filepath="${distro_dest_dir}/${filename}" + + log_info "--------------------------------------------------" + log_info "Starting download for: $filename" + log_info "URL: $url" + + # Download the file to the temporary directory + wget --progress=bar:force:noscroll -O "$temp_filepath" "$url" + download_status=$? + + if [ $download_status -ne 0 ]; then + # Handle download failure + log_error "Failed to download $filename from $url. wget exit code: $download_status" + else + # Handle download success + log_info "Successfully downloaded $filename to temporary location." + + # Ensure the specific distro directory exists + log_info "Ensuring destination directory exists: $distro_dest_dir" + mkdir -p "$distro_dest_dir" + + # Move the file to the destination directory, replacing any existing file + log_info "Moving $filename to $dest_filepath" + mv -f "$temp_filepath" "$dest_filepath" + move_status=$? + + if [ $move_status -ne 0 ]; then + log_error "Failed to move $filename to $dest_filepath. mv exit code: $move_status" + else + log_info "Successfully moved $filename." + fi + fi +done + +log_info "Generate checksum" +# Create md5 checksum +checksum_file="md5sum.txt" +sha512_checksum_file="sha512sum.txt" + +cd "$DEST_DIR" +find . -type f ! -iname '*.txt' -exec md5sum {} \; > "$checksum_file" +checksum_status=$? +if [ $checksum_status -ne 0 ]; then + log_error "Failed to create md5 checksum. md5sum exit code: $checksum_status" +else + log_info "Successfully created checksum file: $checksum_file" +fi + +find . -type f ! -iname '*.txt' -exec sha512sum {} \; > "$sha512_checksum_file" +sha512_checksum_status=$? +if [ $sha512_checksum_status -ne 0 ]; then + log_error "Failed to create sha512 checksum. sha512sum exit code: $sha512_checksum_status" +else + log_info "Successfully created checksum file: $sha512_checksum_file" +fi + +log_info "--------------------------------------------------" +log_info "Image download process finished." From 8c2a0308165173812d146d835bf31c3e515daff4 Mon Sep 17 00:00:00 2001 From: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com> Date: Thu, 29 Jan 2026 09:51:22 -0300 Subject: [PATCH 088/101] Fix query filter and units tests (#12184) --- .../com/cloud/network/dao/NetworkDaoImpl.java | 2 +- .../cloud/network/dao/NetworkDaoImplTest.java | 31 +++++++------------ 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/network/dao/NetworkDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkDaoImpl.java index 8066b89b4b9a..4e8b6204f720 100644 --- a/engine/schema/src/main/java/com/cloud/network/dao/NetworkDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/network/dao/NetworkDaoImpl.java @@ -598,7 +598,7 @@ public List listByPhysicalNetwork(final long physicalNetworkId) { public List listByPhysicalNetworkTrafficType(final long physicalNetworkId, final TrafficType trafficType) { final SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("trafficType", trafficType); - sc.setParameters("physicalNetwork", physicalNetworkId); + sc.setParameters("physicalNetworkId", physicalNetworkId); return listBy(sc); } diff --git a/engine/schema/src/test/java/com/cloud/network/dao/NetworkDaoImplTest.java b/engine/schema/src/test/java/com/cloud/network/dao/NetworkDaoImplTest.java index ab5f43521052..a78eab568af0 100644 --- a/engine/schema/src/test/java/com/cloud/network/dao/NetworkDaoImplTest.java +++ b/engine/schema/src/test/java/com/cloud/network/dao/NetworkDaoImplTest.java @@ -22,7 +22,6 @@ import com.cloud.network.Networks; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.TransactionLegacy; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -30,7 +29,6 @@ import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; - import java.util.List; @RunWith(MockitoJUnitRunner.class) @@ -46,26 +44,21 @@ public class NetworkDaoImplTest { List listNetworkVoMock; @Test - public void listByPhysicalNetworkTrafficTypeTestSetParametersValidation() throws Exception { + public void listByPhysicalNetworkTrafficTypeTestSetParametersValidation() { NetworkDaoImpl networkDaoImplSpy = Mockito.spy(NetworkDaoImpl.class); - TransactionLegacy txn = TransactionLegacy.open("runNetworkDaoImplTest"); - try { - networkDaoImplSpy.AllFieldsSearch = searchBuilderNetworkVoMock; - Mockito.doReturn(searchCriteriaNetworkVoMock).when(searchBuilderNetworkVoMock).create(); - Mockito.doNothing().when(searchCriteriaNetworkVoMock).setParameters(Mockito.anyString(), Mockito.any()); - Mockito.doReturn(listNetworkVoMock).when(networkDaoImplSpy).listBy(Mockito.any(SearchCriteria.class)); - - long expectedPhysicalNetwork = 2513l; + networkDaoImplSpy.AllFieldsSearch = searchBuilderNetworkVoMock; + Mockito.doReturn(searchCriteriaNetworkVoMock).when(searchBuilderNetworkVoMock).create(); + Mockito.doNothing().when(searchCriteriaNetworkVoMock).setParameters(Mockito.anyString(), Mockito.any()); + Mockito.doReturn(listNetworkVoMock).when(networkDaoImplSpy).listBy(Mockito.any(SearchCriteria.class)); - for (Networks.TrafficType trafficType : Networks.TrafficType.values()) { - List result = networkDaoImplSpy.listByPhysicalNetworkTrafficType(expectedPhysicalNetwork, trafficType); - Assert.assertEquals(listNetworkVoMock, result); - Mockito.verify(searchCriteriaNetworkVoMock).setParameters("trafficType", trafficType); - } + long expectedPhysicalNetwork = 2513l; - Mockito.verify(searchCriteriaNetworkVoMock, Mockito.times(Networks.TrafficType.values().length)).setParameters("physicalNetwork", expectedPhysicalNetwork); - } finally { - txn.close(); + for (Networks.TrafficType trafficType : Networks.TrafficType.values()) { + List result = networkDaoImplSpy.listByPhysicalNetworkTrafficType(expectedPhysicalNetwork, trafficType); + Assert.assertEquals(listNetworkVoMock, result); + Mockito.verify(searchCriteriaNetworkVoMock).setParameters("trafficType", trafficType); } + + Mockito.verify(searchCriteriaNetworkVoMock, Mockito.times(Networks.TrafficType.values().length)).setParameters("physicalNetworkId", expectedPhysicalNetwork); } } From bb8e7d39e6efc0a68f3536b607df6b5c2a01946e Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 30 Jan 2026 12:11:25 +0530 Subject: [PATCH 089/101] api,server: allow configuring repetitive alerts (#11325) * api,server: allow configuring repetitive alerts Fixes #6613 Introduces support for configuring additional alert types that can be published repeatedly, beyond the default set. Operators can now use the dynamic configuration `alert.allowed.repetitive.types` to specify a comma-separated list of alert type names that should be allowed for repetitive publication. Signed-off-by: Abhishek Kumar * add tests Signed-off-by: Abhishek Kumar * fix Signed-off-by: Abhishek Kumar * test fix Signed-off-by: Abhishek Kumar * allow repetition for custom alerts Signed-off-by: Abhishek Kumar * remove refactoring Signed-off-by: Abhishek Kumar --------- Signed-off-by: Abhishek Kumar --- .../apache/cloudstack/alert/AlertService.java | 44 +++++---- .../apache/cloudstack/api/ApiConstants.java | 1 + .../admin/resource/ListAlertTypesCmd.java | 12 ++- .../api/response/AlertTypeResponse.java | 12 ++- .../java/com/cloud/alert/AlertManager.java | 4 + .../com/cloud/alert/AlertManagerImpl.java | 72 +++++++++----- .../com/cloud/alert/AlertManagerImplTest.java | 98 +++++++++++++++++-- 7 files changed, 187 insertions(+), 56 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/alert/AlertService.java b/api/src/main/java/org/apache/cloudstack/alert/AlertService.java index c051ebb2da20..fcc87908bd5d 100644 --- a/api/src/main/java/org/apache/cloudstack/alert/AlertService.java +++ b/api/src/main/java/org/apache/cloudstack/alert/AlertService.java @@ -24,18 +24,24 @@ public interface AlertService { public static class AlertType { - private static Set defaultAlertTypes = new HashSet(); + private static final Set defaultAlertTypes = new HashSet<>(); private final String name; private final short type; + private final boolean repetitionAllowed; - private AlertType(short type, String name, boolean isDefault) { + private AlertType(short type, String name, boolean isDefault, boolean repetitionAllowed) { this.name = name; this.type = type; + this.repetitionAllowed = repetitionAllowed; if (isDefault) { defaultAlertTypes.add(this); } } + private AlertType(short type, String name, boolean isDefault) { + this(type, name, isDefault, false); + } + public static final AlertType ALERT_TYPE_MEMORY = new AlertType(Capacity.CAPACITY_TYPE_MEMORY, "ALERT.MEMORY", true); public static final AlertType ALERT_TYPE_CPU = new AlertType(Capacity.CAPACITY_TYPE_CPU, "ALERT.CPU", true); public static final AlertType ALERT_TYPE_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_STORAGE, "ALERT.STORAGE", true); @@ -45,36 +51,36 @@ private AlertType(short type, String name, boolean isDefault) { public static final AlertType ALERT_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET = new AlertType(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET, "ALERT.NETWORK.IPV6SUBNET", true); public static final AlertType ALERT_TYPE_PRIVATE_IP = new AlertType(Capacity.CAPACITY_TYPE_PRIVATE_IP, "ALERT.NETWORK.PRIVATEIP", true); public static final AlertType ALERT_TYPE_SECONDARY_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_SECONDARY_STORAGE, "ALERT.STORAGE.SECONDARY", true); - public static final AlertType ALERT_TYPE_HOST = new AlertType((short)7, "ALERT.COMPUTE.HOST", true); - public static final AlertType ALERT_TYPE_USERVM = new AlertType((short)8, "ALERT.USERVM", true); - public static final AlertType ALERT_TYPE_DOMAIN_ROUTER = new AlertType((short)9, "ALERT.SERVICE.DOMAINROUTER", true); - public static final AlertType ALERT_TYPE_CONSOLE_PROXY = new AlertType((short)10, "ALERT.SERVICE.CONSOLEPROXY", true); + public static final AlertType ALERT_TYPE_HOST = new AlertType((short)7, "ALERT.COMPUTE.HOST", true, true); + public static final AlertType ALERT_TYPE_USERVM = new AlertType((short)8, "ALERT.USERVM", true, true); + public static final AlertType ALERT_TYPE_DOMAIN_ROUTER = new AlertType((short)9, "ALERT.SERVICE.DOMAINROUTER", true, true); + public static final AlertType ALERT_TYPE_CONSOLE_PROXY = new AlertType((short)10, "ALERT.SERVICE.CONSOLEPROXY", true, true); public static final AlertType ALERT_TYPE_ROUTING = new AlertType((short)11, "ALERT.NETWORK.ROUTING", true); - public static final AlertType ALERT_TYPE_STORAGE_MISC = new AlertType((short)12, "ALERT.STORAGE.MISC", true); + public static final AlertType ALERT_TYPE_STORAGE_MISC = new AlertType((short)12, "ALERT.STORAGE.MISC", true, true); public static final AlertType ALERT_TYPE_USAGE_SERVER = new AlertType((short)13, "ALERT.USAGE", true); - public static final AlertType ALERT_TYPE_MANAGEMENT_NODE = new AlertType((short)14, "ALERT.MANAGEMENT", true); + public static final AlertType ALERT_TYPE_MANAGEMENT_NODE = new AlertType((short)14, "ALERT.MANAGEMENT", true, true); public static final AlertType ALERT_TYPE_DOMAIN_ROUTER_MIGRATE = new AlertType((short)15, "ALERT.NETWORK.DOMAINROUTERMIGRATE", true); public static final AlertType ALERT_TYPE_CONSOLE_PROXY_MIGRATE = new AlertType((short)16, "ALERT.SERVICE.CONSOLEPROXYMIGRATE", true); public static final AlertType ALERT_TYPE_USERVM_MIGRATE = new AlertType((short)17, "ALERT.USERVM.MIGRATE", true); public static final AlertType ALERT_TYPE_VLAN = new AlertType((short)18, "ALERT.NETWORK.VLAN", true); - public static final AlertType ALERT_TYPE_SSVM = new AlertType((short)19, "ALERT.SERVICE.SSVM", true); + public static final AlertType ALERT_TYPE_SSVM = new AlertType((short)19, "ALERT.SERVICE.SSVM", true, true); public static final AlertType ALERT_TYPE_USAGE_SERVER_RESULT = new AlertType((short)20, "ALERT.USAGE.RESULT", true); public static final AlertType ALERT_TYPE_STORAGE_DELETE = new AlertType((short)21, "ALERT.STORAGE.DELETE", true); public static final AlertType ALERT_TYPE_UPDATE_RESOURCE_COUNT = new AlertType((short)22, "ALERT.RESOURCE.COUNT", true); public static final AlertType ALERT_TYPE_USAGE_SANITY_RESULT = new AlertType((short)23, "ALERT.USAGE.SANITY", true); public static final AlertType ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP = new AlertType((short)24, "ALERT.NETWORK.DIRECTPUBLICIP", true); public static final AlertType ALERT_TYPE_LOCAL_STORAGE = new AlertType((short)25, "ALERT.STORAGE.LOCAL", true); - public static final AlertType ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED = new AlertType((short)26, "ALERT.RESOURCE.EXCEED", true); + public static final AlertType ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED = new AlertType((short)26, "ALERT.RESOURCE.EXCEED", true, true); public static final AlertType ALERT_TYPE_SYNC = new AlertType((short)27, "ALERT.TYPE.SYNC", true); - public static final AlertType ALERT_TYPE_UPLOAD_FAILED = new AlertType((short)28, "ALERT.UPLOAD.FAILED", true); - public static final AlertType ALERT_TYPE_OOBM_AUTH_ERROR = new AlertType((short)29, "ALERT.OOBM.AUTHERROR", true); - public static final AlertType ALERT_TYPE_HA_ACTION = new AlertType((short)30, "ALERT.HA.ACTION", true); - public static final AlertType ALERT_TYPE_CA_CERT = new AlertType((short)31, "ALERT.CA.CERT", true); + public static final AlertType ALERT_TYPE_UPLOAD_FAILED = new AlertType((short)28, "ALERT.UPLOAD.FAILED", true, true); + public static final AlertType ALERT_TYPE_OOBM_AUTH_ERROR = new AlertType((short)29, "ALERT.OOBM.AUTHERROR", true, true); + public static final AlertType ALERT_TYPE_HA_ACTION = new AlertType((short)30, "ALERT.HA.ACTION", true, true); + public static final AlertType ALERT_TYPE_CA_CERT = new AlertType((short)31, "ALERT.CA.CERT", true, true); public static final AlertType ALERT_TYPE_VM_SNAPSHOT = new AlertType((short)32, "ALERT.VM.SNAPSHOT", true); public static final AlertType ALERT_TYPE_VR_PUBLIC_IFACE_MTU = new AlertType((short)33, "ALERT.VR.PUBLIC.IFACE.MTU", true); public static final AlertType ALERT_TYPE_VR_PRIVATE_IFACE_MTU = new AlertType((short)34, "ALERT.VR.PRIVATE.IFACE.MTU", true); - public static final AlertType ALERT_TYPE_EXTENSION_PATH_NOT_READY = new AlertType((short)33, "ALERT.TYPE.EXTENSION.PATH.NOT.READY", true); - public static final AlertType ALERT_TYPE_VPN_GATEWAY_OBSOLETE_PARAMETERS = new AlertType((short)34, "ALERT.S2S.VPN.GATEWAY.OBSOLETE.PARAMETERS", true); + public static final AlertType ALERT_TYPE_EXTENSION_PATH_NOT_READY = new AlertType((short)33, "ALERT.TYPE.EXTENSION.PATH.NOT.READY", true, true); + public static final AlertType ALERT_TYPE_VPN_GATEWAY_OBSOLETE_PARAMETERS = new AlertType((short)34, "ALERT.S2S.VPN.GATEWAY.OBSOLETE.PARAMETERS", true, true); public static final AlertType ALERT_TYPE_BACKUP_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_BACKUP_STORAGE, "ALERT.STORAGE.BACKUP", true); public static final AlertType ALERT_TYPE_OBJECT_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_OBJECT_STORAGE, "ALERT.STORAGE.OBJECT", true); @@ -86,6 +92,10 @@ public String getName() { return name; } + public boolean isRepetitionAllowed() { + return repetitionAllowed; + } + private static AlertType getAlertType(short type) { for (AlertType alertType : defaultAlertTypes) { if (alertType.getType() == type) { @@ -109,7 +119,7 @@ public static AlertType generateAlert(short type, String name) { if (defaultAlert != null && !defaultAlert.getName().equalsIgnoreCase(name)) { throw new InvalidParameterValueException("There is a default alert having type " + type + " and name " + defaultAlert.getName()); } else { - return new AlertType(type, name, false); + return new AlertType(type, name, false, false); } } } diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index d00e339de2fd..790070e5244b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -503,6 +503,7 @@ public class ApiConstants { public static final String RECONNECT = "reconnect"; public static final String RECOVER = "recover"; public static final String REPAIR = "repair"; + public static final String REPETITION_ALLOWED = "repetitionallowed"; public static final String REQUIRES_HVM = "requireshvm"; public static final String RESOURCES = "resources"; public static final String RESOURCE_COUNT = "resourcecount"; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertTypesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertTypesCmd.java index e7bfbdbc6254..dcd4f2c89ef2 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertTypesCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertTypesCmd.java @@ -16,7 +16,10 @@ // under the License. package org.apache.cloudstack.api.command.admin.resource; -import com.cloud.user.Account; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + import org.apache.cloudstack.alert.AlertService; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.BaseCmd; @@ -24,9 +27,7 @@ import org.apache.cloudstack.api.response.AlertTypeResponse; import org.apache.cloudstack.api.response.ListResponse; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; +import com.cloud.user.Account; @APICommand(name = "listAlertTypes", description = "Lists all alerts types", responseObject = AlertResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) @@ -43,7 +44,8 @@ public void execute() { ListResponse response = new ListResponse<>(); List typeResponseList = new ArrayList<>(); for (AlertService.AlertType alertType : result) { - AlertTypeResponse alertResponse = new AlertTypeResponse(alertType.getType(), alertType.getName()); + AlertTypeResponse alertResponse = new AlertTypeResponse(alertType.getType(), alertType.getName(), + alertType.isRepetitionAllowed()); alertResponse.setObjectName("alerttype"); typeResponseList.add(alertResponse); } diff --git a/api/src/main/java/org/apache/cloudstack/api/response/AlertTypeResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/AlertTypeResponse.java index 3f91cde01788..e8c3cf6c4ac7 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/AlertTypeResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/AlertTypeResponse.java @@ -16,11 +16,12 @@ // under the License. package org.apache.cloudstack.api.response; -import com.cloud.serializer.Param; -import com.google.gson.annotations.SerializedName; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + public class AlertTypeResponse extends BaseResponse { @SerializedName("alerttypeid") @@ -31,6 +32,10 @@ public class AlertTypeResponse extends BaseResponse { @Param(description = "description of alert type") private String name; + @SerializedName(ApiConstants.REPETITION_ALLOWED) + @Param(description = "Whether repetitive alerts allowed for the alert type", since = "4.22.0") + private boolean repetitionAllowed = true; + public String getName() { return name; } @@ -47,9 +52,10 @@ public void setUsageType(short alertType) { this.alertType = alertType; } - public AlertTypeResponse(short alertType, String name) { + public AlertTypeResponse(short alertType, String name, boolean repetitionAllowed) { this.alertType = alertType; this.name = name; + this.repetitionAllowed = repetitionAllowed; setObjectName("alerttype"); } } diff --git a/engine/components-api/src/main/java/com/cloud/alert/AlertManager.java b/engine/components-api/src/main/java/com/cloud/alert/AlertManager.java index 7fe19c3ba9f8..46993b066a49 100644 --- a/engine/components-api/src/main/java/com/cloud/alert/AlertManager.java +++ b/engine/components-api/src/main/java/com/cloud/alert/AlertManager.java @@ -49,6 +49,10 @@ public interface AlertManager extends Manager, AlertService { "Percentage (as a value between 0 and 1) of guest network IPv6 subnet utilization above which alerts will be sent.", true); + ConfigKey AllowedRepetitiveAlertTypes = new ConfigKey<>(ConfigKey.CATEGORY_ALERT, String.class, + "alert.allowed.repetitive.types", "", + "Comma-separated list of alert types (by name) that can be sent multiple times", true); + void clearAlert(AlertType alertType, long dataCenterId, long podId); void recalculateCapacity(); diff --git a/server/src/main/java/com/cloud/alert/AlertManagerImpl.java b/server/src/main/java/com/cloud/alert/AlertManagerImpl.java index 308c4443cb8b..27b445ba3769 100644 --- a/server/src/main/java/com/cloud/alert/AlertManagerImpl.java +++ b/server/src/main/java/com/cloud/alert/AlertManagerImpl.java @@ -19,7 +19,6 @@ import java.io.UnsupportedEncodingException; import java.text.DecimalFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -37,15 +36,12 @@ import javax.mail.MessagingException; import javax.naming.ConfigurationException; -import com.cloud.dc.DataCenter; -import com.cloud.dc.Pod; -import com.cloud.org.Cluster; - import org.apache.cloudstack.backup.BackupManager; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.messagebus.MessageBus; import org.apache.cloudstack.managed.context.ManagedContextTimerTask; import org.apache.cloudstack.storage.datastore.db.ObjectStoreDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; @@ -54,6 +50,7 @@ import org.apache.cloudstack.utils.mailing.SMTPMailProperties; import org.apache.cloudstack.utils.mailing.SMTPMailSender; import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -70,9 +67,11 @@ import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; +import com.cloud.dc.Pod; import com.cloud.dc.Vlan.VlanType; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; @@ -86,10 +85,12 @@ import com.cloud.host.dao.HostDao; import com.cloud.network.Ipv6Service; import com.cloud.network.dao.IPAddressDao; +import com.cloud.org.Cluster; import com.cloud.org.Grouping.AllocationState; import com.cloud.resource.ResourceManager; import com.cloud.storage.StorageManager; import com.cloud.utils.Pair; +import com.cloud.utils.Ternary; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.SearchCriteria; @@ -100,21 +101,6 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Configurable { protected Logger logger = LogManager.getLogger(AlertManagerImpl.class.getName()); - public static final List ALERTS = Arrays.asList(AlertType.ALERT_TYPE_HOST - , AlertType.ALERT_TYPE_USERVM - , AlertType.ALERT_TYPE_DOMAIN_ROUTER - , AlertType.ALERT_TYPE_CONSOLE_PROXY - , AlertType.ALERT_TYPE_SSVM - , AlertType.ALERT_TYPE_STORAGE_MISC - , AlertType.ALERT_TYPE_MANAGEMENT_NODE - , AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED - , AlertType.ALERT_TYPE_UPLOAD_FAILED - , AlertType.ALERT_TYPE_OOBM_AUTH_ERROR - , AlertType.ALERT_TYPE_HA_ACTION - , AlertType.ALERT_TYPE_CA_CERT - , AlertType.ALERT_TYPE_EXTENSION_PATH_NOT_READY - , AlertType.ALERT_TYPE_VPN_GATEWAY_OBSOLETE_PARAMETERS); - private static final long INITIAL_CAPACITY_CHECK_DELAY = 30L * 1000L; // Thirty seconds expressed in milliseconds. private static final DecimalFormat DfPct = new DecimalFormat("###.##"); @@ -156,6 +142,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi Ipv6Service ipv6Service; @Inject HostDao hostDao; + @Inject + MessageBus messageBus; private Timer _timer = null; private long _capacityCheckPeriod = 60L * 60L * 1000L; // One hour by default. @@ -175,6 +163,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi protected String[] recipients = null; protected String senderAddress = null; + private final List allowedRepetitiveAlertTypeNames = new ArrayList<>(); + public AlertManagerImpl() { _executor = Executors.newCachedThreadPool(new NamedThreadFactory("Email-Alerts-Sender")); } @@ -254,12 +244,32 @@ public boolean configure(String name, Map params) throws Configu _capacityCheckPeriod = Long.parseLong(Config.CapacityCheckPeriod.getDefaultValue()); } } + initMessageBusListener(); + setupRepetitiveAlertTypes(); _timer = new Timer("CapacityChecker"); return true; } + protected void setupRepetitiveAlertTypes() { + allowedRepetitiveAlertTypeNames.clear(); + String allowedRepetitiveAlertsStr = AllowedRepetitiveAlertTypes.value(); + logger.trace("Allowed repetitive alert types specified by {}: {} ", AllowedRepetitiveAlertTypes.key(), + allowedRepetitiveAlertsStr); + if (StringUtils.isBlank(allowedRepetitiveAlertsStr)) { + return; + } + String[] allowedRepetitiveAlertTypesArray = allowedRepetitiveAlertsStr.split(","); + for (String allowedTypeName : allowedRepetitiveAlertTypesArray) { + if (StringUtils.isBlank(allowedTypeName)) { + continue; + } + allowedRepetitiveAlertTypeNames.add(allowedTypeName.toLowerCase()); + } + logger.trace("{} alert types specified for repetitive alerts", allowedRepetitiveAlertTypeNames.size()); + } + @Override public boolean start() { _timer.schedule(new CapacityChecker(), INITIAL_CAPACITY_CHECK_DELAY, _capacityCheckPeriod); @@ -850,11 +860,11 @@ public void sendAlert(AlertType alertType, DataCenter dataCenter, Pod pod, Clust @Nullable private AlertVO getAlertForTrivialAlertType(AlertType alertType, long dataCenterId, Long podId, Long clusterId) { - AlertVO alert = null; - if (!ALERTS.contains(alertType)) { - alert = _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId, clusterId); + if (alertType.isRepetitionAllowed() || (StringUtils.isNotBlank(alertType.getName()) && + allowedRepetitiveAlertTypeNames.contains(alertType.getName().toLowerCase()))) { + return null; } - return alert; + return _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId, clusterId); } protected void sendMessage(SMTPMailProperties mailProps) { @@ -883,7 +893,7 @@ public String getConfigComponentName() { @Override public ConfigKey[] getConfigKeys() { return new ConfigKey[] {CPUCapacityThreshold, MemoryCapacityThreshold, StorageAllocatedCapacityThreshold, StorageCapacityThreshold, AlertSmtpEnabledSecurityProtocols, - AlertSmtpUseStartTLS, Ipv6SubnetCapacityThreshold, AlertSmtpUseAuth}; + AlertSmtpUseStartTLS, Ipv6SubnetCapacityThreshold, AlertSmtpUseAuth, AllowedRepetitiveAlertTypes}; } @Override @@ -897,4 +907,16 @@ public boolean generateAlert(AlertType alertType, long dataCenterId, Long podId, return false; } } + + @SuppressWarnings("unchecked") + protected void initMessageBusListener() { + messageBus.subscribe(EventTypes.EVENT_CONFIGURATION_VALUE_EDIT, (senderAddress, subject, args) -> { + Ternary updatedSetting = (Ternary) args; + String updatedSettingName = updatedSetting.first(); + if (!AllowedRepetitiveAlertTypes.key().equals(updatedSettingName)) { + return; + } + setupRepetitiveAlertTypes(); + }); + } } diff --git a/server/src/test/java/com/cloud/alert/AlertManagerImplTest.java b/server/src/test/java/com/cloud/alert/AlertManagerImplTest.java index 170fceae9861..b5932e8a071a 100644 --- a/server/src/test/java/com/cloud/alert/AlertManagerImplTest.java +++ b/server/src/test/java/com/cloud/alert/AlertManagerImplTest.java @@ -16,6 +16,12 @@ // under the License. package com.cloud.alert; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; + import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.List; @@ -25,7 +31,10 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.backup.BackupManager; +import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.messagebus.MessageBus; +import org.apache.cloudstack.framework.messagebus.MessageSubscriber; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.utils.mailing.SMTPMailSender; @@ -40,6 +49,7 @@ import org.mockito.Mockito; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.test.util.ReflectionTestUtils; import com.cloud.alert.dao.AlertDao; import com.cloud.capacity.Capacity; @@ -52,16 +62,12 @@ import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; +import com.cloud.event.EventTypes; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.StorageManager; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.verify; +import com.cloud.utils.Ternary; @RunWith(MockitoJUnitRunner.class) public class AlertManagerImplTest { @@ -112,6 +118,9 @@ public class AlertManagerImplTest { @Mock ConfigurationDao configDao; + @Mock + MessageBus messageBus; + private final String[] recipients = new String[]{"test@test.com"}; private final String senderAddress = "sender@test.com"; @@ -268,4 +277,81 @@ public void testCheckForAlerts() throws ConfigurationException { assertEquals("Available backup storage space is low, total: 200.0 MB, used: 180.0 MB (90%)", capturedAlert.getContent()); assertEquals(AlertManager.AlertType.ALERT_TYPE_BACKUP_STORAGE.getType(), capturedAlert.getType()); } + + @Test + public void initMessageBusListenerSubscribesToConfigurationEditEvent() { + MessageBus messageBusMock = Mockito.mock(MessageBus.class); + alertManagerImplMock.messageBus = messageBusMock; + alertManagerImplMock.initMessageBusListener(); + Mockito.verify(messageBusMock).subscribe(Mockito.eq(EventTypes.EVENT_CONFIGURATION_VALUE_EDIT), Mockito.any()); + } + + @Test + public void initMessageBusListenerTriggersSetupRepetitiveAlertTypesOnAllowedKeyEdit() { + MessageBus messageBusMock = Mockito.mock(MessageBus.class); + alertManagerImplMock.messageBus = messageBusMock; + alertManagerImplMock.initMessageBusListener(); + ArgumentCaptor captor = ArgumentCaptor.forClass(MessageSubscriber.class); + Mockito.verify(messageBusMock).subscribe(Mockito.eq(EventTypes.EVENT_CONFIGURATION_VALUE_EDIT), captor.capture()); + Ternary args = new Ternary<>(AlertManager.AllowedRepetitiveAlertTypes.key(), ConfigKey.Scope.Global, 1L); + captor.getValue().onPublishMessage(null, null, args); + Mockito.verify(alertManagerImplMock).setupRepetitiveAlertTypes(); + } + + @Test + public void initMessageBusListenerDoesNotTriggerSetupRepetitiveAlertTypesOnOtherKeyEdit() { + MessageBus messageBusMock = Mockito.mock(MessageBus.class); + alertManagerImplMock.messageBus = messageBusMock; + alertManagerImplMock.initMessageBusListener(); + ArgumentCaptor captor = ArgumentCaptor.forClass(MessageSubscriber.class); + Mockito.verify(messageBusMock).subscribe(Mockito.eq(EventTypes.EVENT_CONFIGURATION_VALUE_EDIT), captor.capture()); + Ternary args = new Ternary<>("some.other.key", ConfigKey.Scope.Global, 1L); + captor.getValue().onPublishMessage(null, null, args); + Mockito.verify(alertManagerImplMock, Mockito.never()).setupRepetitiveAlertTypes(); + } + + private void mockAllowedRepetitiveAlertTypesConfigKey(String value) { + ReflectionTestUtils.setField(AlertManager.AllowedRepetitiveAlertTypes, "_defaultValue", value); + } + + @Test + public void setupRepetitiveAlertTypesParsesValidAlertTypesCorrectly() { + mockAllowedRepetitiveAlertTypesConfigKey(AlertManager.AlertType.ALERT_TYPE_CPU.getName() + "," + AlertManager.AlertType.ALERT_TYPE_MEMORY.getName()); + alertManagerImplMock.setupRepetitiveAlertTypes(); + List expectedTypes = (List)ReflectionTestUtils.getField(alertManagerImplMock, "allowedRepetitiveAlertTypeNames"); + Assert.assertNotNull(expectedTypes); + Assert.assertEquals(2, expectedTypes.size()); + Assert.assertTrue(expectedTypes.contains(AlertManager.AlertType.ALERT_TYPE_CPU.getName().toLowerCase())); + Assert.assertTrue(expectedTypes.contains(AlertManager.AlertType.ALERT_TYPE_MEMORY.getName().toLowerCase())); + } + + @Test + public void setupRepetitiveAlertTypesHandlesEmptyConfigValue() { + mockAllowedRepetitiveAlertTypesConfigKey(""); + alertManagerImplMock.setupRepetitiveAlertTypes(); + List expectedTypes = (List)ReflectionTestUtils.getField(alertManagerImplMock, "allowedRepetitiveAlertTypeNames"); + Assert.assertNotNull(expectedTypes); + Assert.assertTrue(expectedTypes.isEmpty()); + } + + @Test + public void setupRepetitiveAlertTypesIgnoresCustomAlertTypes() { + String customAlertTypeName = "CUSTOM_ALERT_TYPE"; + mockAllowedRepetitiveAlertTypesConfigKey(AlertManager.AlertType.ALERT_TYPE_CPU.getName() + "," + customAlertTypeName); + alertManagerImplMock.setupRepetitiveAlertTypes(); + List expectedTypes = (List)ReflectionTestUtils.getField(alertManagerImplMock, "allowedRepetitiveAlertTypeNames"); + Assert.assertNotNull(expectedTypes); + Assert.assertEquals(2, expectedTypes.size()); + Assert.assertTrue(expectedTypes.contains(AlertManager.AlertType.ALERT_TYPE_CPU.getName().toLowerCase())); + Assert.assertTrue(expectedTypes.contains(customAlertTypeName.toLowerCase())); + } + + @Test + public void setupRepetitiveAlertTypesHandlesNullConfigValue() { + mockAllowedRepetitiveAlertTypesConfigKey(null); + alertManagerImplMock.setupRepetitiveAlertTypes(); + List expectedTypes = (List)ReflectionTestUtils.getField(alertManagerImplMock, "allowedRepetitiveAlertTypeNames"); + Assert.assertNotNull(expectedTypes); + Assert.assertTrue(expectedTypes.isEmpty()); + } } From bac3421da437d0d3415e83fb3350a8584756e4a7 Mon Sep 17 00:00:00 2001 From: Dattu Date: Fri, 30 Jan 2026 12:12:41 +0530 Subject: [PATCH 090/101] Fixed: unnecessary regeneration of SSH keys in developer mode when they already existed. (#12059) --- .../src/main/java/com/cloud/server/ConfigurationServerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java b/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java index 51793f22e908..8f10dd84b54d 100644 --- a/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java @@ -614,7 +614,7 @@ public void updateKeyPairs() { } // FIXME: take a global database lock here for safety. boolean onWindows = isOnWindows(); - if(!onWindows) { + if (!onWindows && !(privkeyfile.exists() && pubkeyfile.exists())) { Script.runSimpleBashScript("if [ -f " + privkeyfile + " ]; then rm -f " + privkeyfile + "; fi; ssh-keygen -t ecdsa -m PEM -N '' -f " + privkeyfile + " -q 2>/dev/null || ssh-keygen -t ecdsa -N '' -f " + privkeyfile + " -q"); } From bb391c3deb1c4a4172f91a60898decac33854246 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Fri, 30 Jan 2026 07:50:44 +0100 Subject: [PATCH 091/101] test: increase timeout in test_human_readable_logs.py (#11972) --- test/integration/smoke/test_human_readable_logs.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/integration/smoke/test_human_readable_logs.py b/test/integration/smoke/test_human_readable_logs.py index fb972511f9c1..c2478bfe5766 100644 --- a/test/integration/smoke/test_human_readable_logs.py +++ b/test/integration/smoke/test_human_readable_logs.py @@ -48,9 +48,9 @@ def test_01_disableHumanReadableLogs(self): sshClient.execute(command) # CapacityChecker runs as soon as management server is up - # Check if "usedMem: (" is printed out within 60 seconds while server is starting - command = "timeout 60 tail -f /var/log/cloudstack/management/management-server.log | grep 'usedMem: ('" - sshClient.timeout = 60 + # Check if "usedMem: (" is printed out within 120 seconds while server is starting + command = "timeout 120 tail -f /var/log/cloudstack/management/management-server.log | grep 'usedMem: ('" + sshClient.timeout = 120 result = sshClient.runCommand(command) self.assertTrue(result['status'] == "FAILED") @@ -70,7 +70,7 @@ def test_02_enableHumanReadableLogs(self): sshClient.execute(command) # CapacityChecker runs as soon as management server is up - # Check if "usedMem: (" is printed out within 60 seconds while server is restarting + # Check if "usedMem: (" is printed out within 120 seconds while server is restarting command = "timeout 120 tail -f /var/log/cloudstack/management/management-server.log | grep 'usedMem: ('" sshClient.timeout = 120 result = sshClient.runCommand(command) From 9d523cbbfef6c097f7dd1488c282637b3b63c256 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 08:57:24 +0200 Subject: [PATCH 092/101] Bump org.apache.maven.plugins:maven-war-plugin from 3.4.0 to 3.5.1 (#12497) Bumps [org.apache.maven.plugins:maven-war-plugin](https://github.com/apache/maven-war-plugin) from 3.4.0 to 3.5.1. - [Release notes](https://github.com/apache/maven-war-plugin/releases) - [Commits](https://github.com/apache/maven-war-plugin/compare/maven-war-plugin-3.4.0...maven-war-plugin-3.5.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-war-plugin dependency-version: 3.5.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- engine/service/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/service/pom.xml b/engine/service/pom.xml index 9b833804064e..673d9c418d77 100644 --- a/engine/service/pom.xml +++ b/engine/service/pom.xml @@ -69,7 +69,7 @@ org.apache.maven.plugins maven-war-plugin - 3.4.0 + 3.5.1 org.eclipse.jetty From 18972caf5f1cfc90bdad59669dc7f8cb031ba64d Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 30 Jan 2026 13:54:01 +0530 Subject: [PATCH 093/101] api,server: allow cleaning up vm extraconfig (#11974) --- .../apache/cloudstack/api/ApiConstants.java | 1 + .../api/command/user/vm/UpdateVMCmd.java | 18 +++- .../cloud/vm/dao/VMInstanceDetailsDao.java | 1 + .../vm/dao/VMInstanceDetailsDaoImpl.java | 17 ++++ .../vm/dao/VMInstanceDetailsDaoImplTest.java | 86 +++++++++++++++++++ .../java/com/cloud/vm/UserVmManagerImpl.java | 28 ++++-- .../com/cloud/vm/UserVmManagerImplTest.java | 75 +++++++++++++++- ui/src/views/compute/EditVM.vue | 2 + 8 files changed, 212 insertions(+), 16 deletions(-) create mode 100644 engine/schema/src/test/java/com/cloud/vm/dao/VMInstanceDetailsDaoImplTest.java 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 790070e5244b..1ab6fba6081f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -1168,6 +1168,7 @@ public class ApiConstants { public static final String OVM3_VIP = "ovm3vip"; public static final String CLEAN_UP_DETAILS = "cleanupdetails"; public static final String CLEAN_UP_EXTERNAL_DETAILS = "cleanupexternaldetails"; + public static final String CLEAN_UP_EXTRA_CONFIG = "cleanupextraconfig"; public static final String CLEAN_UP_PARAMETERS = "cleanupparameters"; public static final String VIRTUAL_SIZE = "virtualsize"; public static final String NETSCALER_CONTROLCENTER_ID = "netscalercontrolcenterid"; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java index ddc2c06eb097..e0da954d381f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java @@ -163,6 +163,12 @@ public class UpdateVMCmd extends BaseCustomIdCmd implements SecurityGroupAction, description = "Lease expiry action, valid values are STOP and DESTROY") private String leaseExpiryAction; + @Parameter(name = ApiConstants.CLEAN_UP_EXTRA_CONFIG, type = CommandType.BOOLEAN, since = "4.23.0", + description = "Optional boolean field, which indicates if extraconfig for the instance should be " + + "cleaned up or not (If set to true, extraconfig removed for this instance, extraconfig field " + + "ignored; if false or not set, no action)") + private Boolean cleanupExtraConfig; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -271,14 +277,18 @@ public String getExtraConfig() { return extraConfig; } - ///////////////////////////////////////////////////// - /////////////// API Implementation/////////////////// - ///////////////////////////////////////////////////// - public Long getOsTypeId() { return osTypeId; } + public boolean isCleanupExtraConfig() { + return Boolean.TRUE.equals(cleanupExtraConfig); + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override public String getCommandName() { return s_name; diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDetailsDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDetailsDao.java index ea9ac5afba67..4cbdc516ba0b 100644 --- a/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDetailsDao.java +++ b/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDetailsDao.java @@ -22,4 +22,5 @@ import com.cloud.vm.VMInstanceDetailVO; public interface VMInstanceDetailsDao extends GenericDao, ResourceDetailsDao { + int removeDetailsWithPrefix(long vmId, String prefix); } diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDetailsDaoImpl.java index ca11b005fb2b..4c2fdd6f8d45 100644 --- a/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDetailsDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDetailsDaoImpl.java @@ -17,10 +17,13 @@ package com.cloud.vm.dao; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; import com.cloud.vm.VMInstanceDetailVO; @Component @@ -31,4 +34,18 @@ public void addDetail(long resourceId, String key, String value, boolean display super.addDetail(new VMInstanceDetailVO(resourceId, key, value, display)); } + @Override + public int removeDetailsWithPrefix(long vmId, String prefix) { + if (StringUtils.isBlank(prefix)) { + return 0; + } + SearchBuilder sb = createSearchBuilder(); + sb.and("vmId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); + sb.and("prefix", sb.entity().getName(), SearchCriteria.Op.LIKE); + sb.done(); + SearchCriteria sc = sb.create(); + sc.setParameters("vmId", vmId); + sc.setParameters("prefix", prefix + "%"); + return super.remove(sc); + } } diff --git a/engine/schema/src/test/java/com/cloud/vm/dao/VMInstanceDetailsDaoImplTest.java b/engine/schema/src/test/java/com/cloud/vm/dao/VMInstanceDetailsDaoImplTest.java new file mode 100644 index 000000000000..06238e386d5e --- /dev/null +++ b/engine/schema/src/test/java/com/cloud/vm/dao/VMInstanceDetailsDaoImplTest.java @@ -0,0 +1,86 @@ +// 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.vm.dao; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; + +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.vm.VMInstanceDetailVO; + +@RunWith(MockitoJUnitRunner.class) +public class VMInstanceDetailsDaoImplTest { + @Spy + @InjectMocks + private VMInstanceDetailsDaoImpl vmInstanceDetailsDaoImpl; + + @Test + public void removeDetailsWithPrefixReturnsZeroWhenPrefixIsBlank() { + Assert.assertEquals(0, vmInstanceDetailsDaoImpl.removeDetailsWithPrefix(1L, "")); + Assert.assertEquals(0, vmInstanceDetailsDaoImpl.removeDetailsWithPrefix(1L, " ")); + Assert.assertEquals(0, vmInstanceDetailsDaoImpl.removeDetailsWithPrefix(1L, null)); + } + + @Test + public void removeDetailsWithPrefixRemovesMatchingDetails() { + SearchBuilder sb = mock(SearchBuilder.class); + VMInstanceDetailVO entity = mock(VMInstanceDetailVO.class); + when(sb.entity()).thenReturn(entity); + when(sb.and(anyString(), any(), any(SearchCriteria.Op.class))).thenReturn(sb); + SearchCriteria sc = mock(SearchCriteria.class); + when(sb.create()).thenReturn(sc); + when(vmInstanceDetailsDaoImpl.createSearchBuilder()).thenReturn(sb); + doReturn(3).when(vmInstanceDetailsDaoImpl).remove(sc); + int removedCount = vmInstanceDetailsDaoImpl.removeDetailsWithPrefix(1L, "testPrefix"); + Assert.assertEquals(3, removedCount); + Mockito.verify(sc).setParameters("vmId", 1L); + Mockito.verify(sc).setParameters("prefix", "testPrefix%"); + Mockito.verify(vmInstanceDetailsDaoImpl, Mockito.times(1)).remove(sc); + } + + @Test + public void removeDetailsWithPrefixDoesNotRemoveWhenNoMatch() { + SearchBuilder sb = mock(SearchBuilder.class); + VMInstanceDetailVO entity = mock(VMInstanceDetailVO.class); + when(sb.entity()).thenReturn(entity); + when(sb.and(anyString(), any(), any(SearchCriteria.Op.class))).thenReturn(sb); + SearchCriteria sc = mock(SearchCriteria.class); + when(sb.create()).thenReturn(sc); + when(vmInstanceDetailsDaoImpl.createSearchBuilder()).thenReturn(sb); + doReturn(0).when(vmInstanceDetailsDaoImpl).remove(sc); + + int removedCount = vmInstanceDetailsDaoImpl.removeDetailsWithPrefix(1L, "nonExistentPrefix"); + + Assert.assertEquals(0, removedCount); + Mockito.verify(sc).setParameters("vmId", 1L); + Mockito.verify(sc).setParameters("prefix", "nonExistentPrefix%"); + Mockito.verify(vmInstanceDetailsDaoImpl, Mockito.times(1)).remove(sc); + } +} diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index eccea944fe62..b9b6e5a68391 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -2866,6 +2866,22 @@ private void adjustVmLimits(Account owner, UserVmVO vmInstance, ServiceOfferingV } } + protected void updateVmExtraConfig(UserVmVO userVm, String extraConfig, boolean cleanupExtraConfig) { + if (cleanupExtraConfig) { + logger.info("Cleaning up extraconfig from user vm: {}", userVm.getUuid()); + vmInstanceDetailsDao.removeDetailsWithPrefix(userVm.getId(), ApiConstants.EXTRA_CONFIG); + return; + } + if (StringUtils.isNotBlank(extraConfig)) { + if (EnableAdditionalVmConfig.valueIn(userVm.getAccountId())) { + logger.info("Adding extra configuration to user vm: {}", userVm.getUuid()); + addExtraConfig(userVm, extraConfig); + } else { + throw new InvalidParameterValueException("attempted setting extraconfig but enable.additional.vm.configuration is disabled"); + } + } + } + @Override @ActionEvent(eventType = EventTypes.EVENT_VM_UPDATE, eventDescription = "updating Vm") public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException { @@ -2883,6 +2899,7 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx List securityGroupIdList = getSecurityGroupIdList(cmd); boolean cleanupDetails = cmd.isCleanupDetails(); String extraConfig = cmd.getExtraConfig(); + boolean cleanupExtraConfig = cmd.isCleanupExtraConfig(); UserVmVO vmInstance = _vmDao.findById(cmd.getId()); VMTemplateVO template = _templateDao.findById(vmInstance.getTemplateId()); @@ -2919,7 +2936,7 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx .map(item -> (item).trim()) .collect(Collectors.toList()); List existingDetails = vmInstanceDetailsDao.listDetails(id); - if (cleanupDetails){ + if (cleanupDetails) { if (caller != null && caller.getType() == Account.Type.ADMIN) { for (final VMInstanceDetailVO detail : existingDetails) { if (detail != null && detail.isDisplay() && !isExtraConfig(detail.getName())) { @@ -2982,15 +2999,8 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx vmInstance.setDetails(details); _vmDao.saveDetails(vmInstance); } - if (StringUtils.isNotBlank(extraConfig)) { - if (EnableAdditionalVmConfig.valueIn(accountId)) { - logger.info("Adding extra configuration to user vm: " + vmInstance.getUuid()); - addExtraConfig(vmInstance, extraConfig); - } else { - throw new InvalidParameterValueException("attempted setting extraconfig but enable.additional.vm.configuration is disabled"); - } - } } + updateVmExtraConfig(userVm, extraConfig, cleanupExtraConfig); if (VMLeaseManager.InstanceLeaseEnabled.value() && cmd.getLeaseDuration() != null) { applyLeaseOnUpdateInstance(vmInstance, cmd.getLeaseDuration(), cmd.getLeaseExpiryAction()); diff --git a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java index 4ec9caab5aa8..4edafb3a05a8 100644 --- a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java +++ b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java @@ -40,8 +40,10 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import java.lang.reflect.Field; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.ZoneOffset; @@ -59,8 +61,6 @@ import java.util.TimeZone; import java.util.UUID; -import com.cloud.domain.Domain; -import com.cloud.storage.dao.SnapshotPolicyDao; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.api.ApiCommandResourceType; @@ -88,6 +88,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.template.VnfTemplateManager; @@ -117,6 +118,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlanner; import com.cloud.deploy.DeploymentPlanningManager; +import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEventUtils; @@ -142,9 +144,9 @@ import com.cloud.network.dao.LoadBalancerVMMapVO; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; -import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.PortForwardingRule; @@ -172,6 +174,7 @@ import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.SnapshotDao; +import com.cloud.storage.dao.SnapshotPolicyDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.template.VirtualMachineTemplate; @@ -467,6 +470,24 @@ public class UserVmManagerImplTest { Class expectedInvalidParameterValueException = InvalidParameterValueException.class; Class expectedCloudRuntimeException = CloudRuntimeException.class; + private Map originalConfigValues = new HashMap<>(); + + + private void updateDefaultConfigValue(final ConfigKey configKey, final Object o, boolean revert) { + try { + final String name = "_defaultValue"; + Field f = ConfigKey.class.getDeclaredField(name); + f.setAccessible(true); + String stringVal = String.valueOf(o); + if (!revert) { + originalConfigValues.put(configKey, f.get(configKey)); + } + f.set(configKey, stringVal); + } catch (IllegalAccessException | NoSuchFieldException e) { + Assert.fail("Failed to mock config " + configKey.key() + " value due to " + e.getMessage()); + } + } + @Before public void beforeTest() { userVmManagerImpl.resourceLimitService = resourceLimitMgr; @@ -496,6 +517,9 @@ public void beforeTest() { public void afterTest() { CallContext.unregister(); unmanagedVMsManagerMockedStatic.close(); + for (Map.Entry entry : originalConfigValues.entrySet()) { + updateDefaultConfigValue(entry.getKey(), entry.getValue(), true); + } } @Test @@ -4178,4 +4202,49 @@ public void testUnmanageUserVMSuccess() { verify(userVmDao, times(1)).releaseFromLockTable(vmId); } + @Test + public void updateVmExtraConfigCleansUpWhenCleanupFlagIsTrue() { + UserVmVO userVm = mock(UserVmVO.class); + when(userVm.getUuid()).thenReturn("test-uuid"); + when(userVm.getId()).thenReturn(1L); + + userVmManagerImpl.updateVmExtraConfig(userVm, "someConfig", true); + + verify(vmInstanceDetailsDao, times(1)).removeDetailsWithPrefix(1L, ApiConstants.EXTRA_CONFIG); + verifyNoMoreInteractions(vmInstanceDetailsDao); + } + + @Test + public void updateVmExtraConfigAddsConfigWhenValidAndEnabled() { + UserVmVO userVm = mock(UserVmVO.class); + when(userVm.getUuid()).thenReturn("test-uuid"); + when(userVm.getAccountId()).thenReturn(1L); + when(userVm.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM); + doNothing().when(userVmManagerImpl).persistExtraConfigKvm(anyString(), eq(userVm)); + updateDefaultConfigValue(UserVmManagerImpl.EnableAdditionalVmConfig, true, false); + + userVmManagerImpl.updateVmExtraConfig(userVm, "validConfig", false); + + verify(vmInstanceDetailsDao, never()).removeDetailsWithPrefix(anyLong(), anyString()); + verify(userVmManagerImpl, times(1)).addExtraConfig(userVm, "validConfig"); + } + + @Test(expected = InvalidParameterValueException.class) + public void updateVmExtraConfigThrowsExceptionWhenConfigDisabled() { + UserVmVO userVm = mock(UserVmVO.class); + when(userVm.getAccountId()).thenReturn(1L); + updateDefaultConfigValue(UserVmManagerImpl.EnableAdditionalVmConfig, false, false); + + userVmManagerImpl.updateVmExtraConfig(userVm, "validConfig", false); + } + + @Test + public void updateVmExtraConfigDoesNothingWhenExtraConfigIsBlank() { + UserVmVO userVm = mock(UserVmVO.class); + + userVmManagerImpl.updateVmExtraConfig(userVm, "", false); + + verify(vmInstanceDetailsDao, never()).removeDetailsWithPrefix(anyLong(), anyString()); + verify(userVmManagerImpl, never()).addExtraConfig(any(UserVmVO.class), anyString()); + } } diff --git a/ui/src/views/compute/EditVM.vue b/ui/src/views/compute/EditVM.vue index 19055afde973..9f08a3368a2b 100644 --- a/ui/src/views/compute/EditVM.vue +++ b/ui/src/views/compute/EditVM.vue @@ -425,6 +425,8 @@ export default { } if (values.extraconfig && values.extraconfig.length > 0) { params.extraconfig = encodeURIComponent(values.extraconfig) + } else if (this.combinedExtraConfig) { + params.cleanupextraconfig = true } this.loading = true From a7178ee687ac4d3808c1a9f1772d3b08a295b834 Mon Sep 17 00:00:00 2001 From: Vishesh <8760112+vishesh92@users.noreply.github.com> Date: Fri, 30 Jan 2026 14:01:57 +0530 Subject: [PATCH 094/101] Fix mvn warnings (#10909) * Replace maven-jgit-buildnumber-plugin with thread safe buildnumber-maven-plugin * Fix mysql-connector-java warning * Fix thread safe warning for properties-maven-plugin * Fix mvn build - marvin warnings * Update tools/marvin/README.md * Update tools/marvin/README.md Co-authored-by: dahn --------- Co-authored-by: dahn --- client/pom.xml | 24 ++++++++++++------- engine/storage/snapshot/pom.xml | 4 ++-- framework/db/pom.xml | 4 ++-- plugins/network-elements/globodns/pom.xml | 4 ++-- plugins/network-elements/tungsten/pom.xml | 4 ++-- pom.xml | 10 ++------ tools/marvin/README.md | 29 +++++++++++++++++++++++ tools/marvin/mvn-setup.py | 2 +- tools/marvin/setup.py | 2 +- 9 files changed, 56 insertions(+), 27 deletions(-) create mode 100644 tools/marvin/README.md diff --git a/client/pom.xml b/client/pom.xml index d8fa433d5be3..b8dffe65d4fb 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -666,16 +666,22 @@ - ru.concerteza.buildnumber - maven-jgit-buildnumber-plugin - 1.2.6 + org.codehaus.mojo + buildnumber-maven-plugin + 3.2.0 git-buildnumber - extract-buildnumber + create prepare-package + + false + false + true + unknown + @@ -688,11 +694,11 @@ org.apache.cloudstack.ServerDaemon - ${git.branch} - ${git.tag} - ${git.revision} - ${git.revision} - ${git.branch} + ${scmBranch} + ${project.version} + ${buildNumber} + ${buildNumber} + ${scmBranch} diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml index 177ab1069d9f..0966082b45ed 100644 --- a/engine/storage/snapshot/pom.xml +++ b/engine/storage/snapshot/pom.xml @@ -57,8 +57,8 @@ compile - mysql - mysql-connector-java + com.mysql + mysql-connector-j test diff --git a/framework/db/pom.xml b/framework/db/pom.xml index 04d0fcc7e899..ced0f64c663d 100644 --- a/framework/db/pom.xml +++ b/framework/db/pom.xml @@ -53,8 +53,8 @@ commons-pool2 - mysql - mysql-connector-java + com.mysql + mysql-connector-j org.apache.cloudstack diff --git a/plugins/network-elements/globodns/pom.xml b/plugins/network-elements/globodns/pom.xml index 70bf2287e2ac..11e84d777c15 100644 --- a/plugins/network-elements/globodns/pom.xml +++ b/plugins/network-elements/globodns/pom.xml @@ -33,8 +33,8 @@ globodns-client - mysql - mysql-connector-java + com.mysql + mysql-connector-j test diff --git a/plugins/network-elements/tungsten/pom.xml b/plugins/network-elements/tungsten/pom.xml index eb83c468f0c4..12214afebcb1 100644 --- a/plugins/network-elements/tungsten/pom.xml +++ b/plugins/network-elements/tungsten/pom.xml @@ -41,8 +41,8 @@ reload4j - mysql - mysql-connector-java + com.mysql + mysql-connector-j test diff --git a/pom.xml b/pom.xml index d5b5ba121c94..883e7a4e4db6 100644 --- a/pom.xml +++ b/pom.xml @@ -470,8 +470,8 @@ ${cs.reload4j.version} - mysql - mysql-connector-java + com.mysql + mysql-connector-j ${cs.mysql.version} test @@ -486,12 +486,6 @@ - - com.mysql - mysql-connector-j - ${cs.mysql.version} - test - net.sf.ehcache ehcache-core diff --git a/tools/marvin/README.md b/tools/marvin/README.md new file mode 100644 index 000000000000..0d43605fc0a3 --- /dev/null +++ b/tools/marvin/README.md @@ -0,0 +1,29 @@ + +# Marvin + +Marvin is the Apache CloudStack Python client written for running smoke tests. + +## Overview + +Marvin provides a Python-based client for Apache CloudStack. It offers utilities for testing and interacting with CloudStack deployments. + +## License + +Licensed under the Apache License, Version 2.0. See the LICENSE.txt file for details. diff --git a/tools/marvin/mvn-setup.py b/tools/marvin/mvn-setup.py index cabcf0dc6596..0eab94955120 100755 --- a/tools/marvin/mvn-setup.py +++ b/tools/marvin/mvn-setup.py @@ -33,7 +33,7 @@ def replaceVersion(fname, version): """replace VERSION in setup.py""" with open(fname, 'r') as f: content = f.read() - needle = '\nVERSION\s*=\s*[\'"][^\'"]*[\'"]' + needle = r'\nVERSION\s*=\s*[\'"][^\'"]*[\'"]' # Ensure the version is PEP440 compliant version = version.replace('-', '+', 1) replacement = '\nVERSION = "%s"' % version diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py index 6c9aa087bc7d..4694cecc8a53 100644 --- a/tools/marvin/setup.py +++ b/tools/marvin/setup.py @@ -38,7 +38,7 @@ maintainer_email="dev@cloudstack.apache.org", long_description="Marvin is the Apache CloudStack python " "client written around the unittest framework", - platforms=("Any",), + platforms=["Any"], url="https://builds.apache.org/job/cloudstack-marvin/", packages=["marvin", "marvin.cloudstackAPI", "marvin.lib", "marvin.config", "marvin.sandbox", From a38205ebf0e21ac8ba355d60c4f84824c6ca612a Mon Sep 17 00:00:00 2001 From: K Viddya <62757458+viddya673@users.noreply.github.com> Date: Fri, 30 Jan 2026 15:52:07 +0530 Subject: [PATCH 095/101] =?UTF-8?q?=C2=A0=C2=A0Add=20s390x=20Support=20for?= =?UTF-8?q?=20Cloudstack=20Simulator=20(#12337)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Viddya K Signed-off-by: Niyam Siwach Co-authored-by: root --- tools/docker/Dockerfile.s390x | 91 +++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 tools/docker/Dockerfile.s390x diff --git a/tools/docker/Dockerfile.s390x b/tools/docker/Dockerfile.s390x new file mode 100644 index 000000000000..f995cb3058dc --- /dev/null +++ b/tools/docker/Dockerfile.s390x @@ -0,0 +1,91 @@ +# 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. +# +# CloudStack-simulator build + +FROM ubuntu:22.04 + +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.23.0.0-SNAPSHOT" Author="Apache CloudStack " + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get -y update && apt-get install -y \ + genisoimage \ + libffi-dev \ + libssl-dev \ + curl \ + gcc-10 \ + git \ + sudo \ + ipmitool \ + iproute2 \ + maven \ + openjdk-11-jdk \ + python3-dev \ + python-is-python3 \ + python3-setuptools \ + python3-pip \ + python3-mysql.connector \ + # Required on s390x as pre-built wheels for bcrypt, cryptography, and cffi are unavailable, necessitating source builds. + python3-bcrypt \ + python3-cryptography \ + python3-cffi \ + supervisor + +RUN apt-get install -qqy mysql-server && \ + apt-get clean all && \ + mkdir -p /var/run/mysqld; \ + chown mysql /var/run/mysqld + +RUN echo '''sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"''' >> /etc/mysql/mysql.conf.d/mysqld.cnf + +COPY tools/docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY . ./root +WORKDIR /root + +RUN mvn -Pdeveloper -Dsimulator -DskipTests clean install + +RUN find /var/lib/mysql -type f -exec touch {} \; && \ + (/usr/bin/mysqld_safe &) && \ + sleep 5; \ + mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password by ''" --connect-expired-password; \ + mvn -Pdeveloper -pl developer -Ddeploydb; \ + mvn -Pdeveloper -pl developer -Ddeploydb-simulator; \ + MARVIN_FILE=`find /root/tools/marvin/dist/ -name "Marvin*.tar.gz"`; \ + rm -rf /usr/bin/s390x-linux-gnu-gcc && \ + ln -s /usr/bin/gcc-10 /usr/bin/s390x-linux-gnu-gcc && \ + pip3 install maturin && \ + pip3 install $MARVIN_FILE + +RUN apt-get install -y nodejs npm build-essential python3 g++ make + +RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash && \ + . /root/.nvm/nvm.sh && \ + nvm install 16 && \ + nvm use 16 && \ + NVM_BIN="$(dirname "$(nvm which node)")" && \ + ln -sf "$NVM_BIN/node" /usr/local/bin/node && \ + ln -sf "$NVM_BIN/npm" /usr/local/bin/npm && \ + cd ui && npm rebuild node-sass && npm install + + +VOLUME /var/lib/mysql + +EXPOSE 8080 8096 5050 + +CMD ["/usr/bin/supervisord"] + From 7b94ccc443fb89d11842f0611701d4410b531654 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Fri, 30 Jan 2026 11:53:40 +0100 Subject: [PATCH 096/101] eofFix --- tools/docker/Dockerfile.s390x | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/docker/Dockerfile.s390x b/tools/docker/Dockerfile.s390x index f995cb3058dc..7e8c49fb3866 100644 --- a/tools/docker/Dockerfile.s390x +++ b/tools/docker/Dockerfile.s390x @@ -88,4 +88,3 @@ VOLUME /var/lib/mysql EXPOSE 8080 8096 5050 CMD ["/usr/bin/supervisord"] - From e32d08e50e1296853203f2f4d0ff92b824ae2d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20B=C3=B6ck?= <89930804+erikbocks@users.noreply.github.com> Date: Thu, 5 Feb 2026 07:23:40 -0300 Subject: [PATCH 097/101] Create new generic method for resource UUID obtention in event's descriptions (#12502) --- .../org/apache/cloudstack/api/BaseCmd.java | 11 +++++++++ .../admin/account/CreateAccountCmd.java | 2 +- .../admin/account/DisableAccountCmd.java | 12 ++++++++-- .../admin/acl/CreateRolePermissionCmd.java | 2 +- .../api/command/admin/acl/DeleteRoleCmd.java | 2 +- .../admin/acl/DeleteRolePermissionCmd.java | 2 +- .../api/command/admin/acl/DisableRoleCmd.java | 2 +- .../api/command/admin/acl/EnableRoleCmd.java | 2 +- .../admin/acl/UpdateRolePermissionCmd.java | 4 ++-- .../CreateProjectRolePermissionCmd.java | 2 +- .../acl/project/DeleteProjectRoleCmd.java | 2 +- .../DeleteProjectRolePermissionCmd.java | 2 +- .../UpdateProjectRolePermissionCmd.java | 4 ++-- .../admin/autoscale/CreateCounterCmd.java | 2 +- .../admin/autoscale/DeleteCounterCmd.java | 2 +- .../admin/backup/ImportBackupOfferingCmd.java | 2 +- .../command/admin/ca/IssueCertificateCmd.java | 2 +- .../admin/ca/ProvisionCertificateCmd.java | 2 +- .../cluster/ExecuteClusterDrsPlanCmd.java | 2 +- .../diagnostics/GetDiagnosticsDataCmd.java | 2 +- .../admin/diagnostics/RunDiagnosticsCmd.java | 2 +- .../command/admin/domain/CreateDomainCmd.java | 2 +- .../command/admin/domain/DeleteDomainCmd.java | 4 ++-- .../command/admin/domain/UpdateDomainCmd.java | 2 +- .../admin/gpu/DiscoverGpuDevicesCmd.java | 2 +- .../command/admin/guest/AddGuestOsCmd.java | 2 +- .../command/admin/guest/RemoveGuestOsCmd.java | 4 ++-- .../admin/guest/RemoveGuestOsMappingCmd.java | 4 ++-- .../command/admin/guest/UpdateGuestOsCmd.java | 2 +- .../admin/guest/UpdateGuestOsMappingCmd.java | 2 +- .../admin/ha/ConfigureHAForHostCmd.java | 4 ++-- .../admin/ha/DisableHAForClusterCmd.java | 4 ++-- .../command/admin/ha/DisableHAForHostCmd.java | 4 ++-- .../command/admin/ha/DisableHAForZoneCmd.java | 4 ++-- .../admin/ha/EnableHAForClusterCmd.java | 4 ++-- .../command/admin/ha/EnableHAForHostCmd.java | 4 ++-- .../command/admin/ha/EnableHAForZoneCmd.java | 4 ++-- .../admin/host/CancelHostAsDegradedCmd.java | 2 +- .../admin/host/CancelHostMaintenanceCmd.java | 2 +- .../admin/host/DeclareHostAsDegradedCmd.java | 2 +- .../host/PrepareForHostMaintenanceCmd.java | 2 +- .../command/admin/host/ReconnectHostCmd.java | 2 +- .../admin/host/ReleaseHostReservationCmd.java | 2 +- ...nfigureInternalLoadBalancerElementCmd.java | 4 ++-- .../CreateInternalLoadBalancerElementCmd.java | 2 +- .../internallb/StartInternalLBVMCmd.java | 4 ++-- .../admin/internallb/StopInternalLBVMCmd.java | 4 ++-- .../network/AddNetworkServiceProviderCmd.java | 2 +- .../CreateGuestNetworkIpv6PrefixCmd.java | 2 +- .../CreateIpv4SubnetForGuestNetworkCmd.java | 2 +- .../network/CreateIpv4SubnetForZoneCmd.java | 2 +- .../CreateManagementNetworkIpRangeCmd.java | 2 +- .../network/CreatePhysicalNetworkCmd.java | 2 +- .../network/DedicateIpv4SubnetForZoneCmd.java | 2 +- .../DeleteGuestNetworkIpv6PrefixCmd.java | 2 +- .../DeleteIpv4SubnetForGuestNetworkCmd.java | 2 +- .../network/DeleteIpv4SubnetForZoneCmd.java | 2 +- .../DeleteManagementNetworkIpRangeCmd.java | 2 +- .../DeleteNetworkServiceProviderCmd.java | 2 +- .../network/DeletePhysicalNetworkCmd.java | 4 ++-- .../DeleteStorageNetworkIpRangeCmd.java | 2 +- .../admin/network/MigrateNetworkCmd.java | 6 ++--- .../command/admin/network/MigrateVPCCmd.java | 2 +- .../ReleaseDedicatedGuestVlanRangeCmd.java | 4 ++-- .../ReleaseDedicatedIpv4SubnetForZoneCmd.java | 2 +- .../network/UpdateIpv4SubnetForZoneCmd.java | 2 +- .../UpdateNetworkServiceProviderCmd.java | 2 +- .../network/UpdatePhysicalNetworkCmd.java | 2 +- .../UpdatePodManagementNetworkIpRangeCmd.java | 2 +- .../UpdateStorageNetworkIpRangeCmd.java | 2 +- .../bgp/ChangeBgpPeersForNetworkCmd.java | 2 +- .../network/bgp/ChangeBgpPeersForVpcCmd.java | 2 +- .../admin/network/bgp/CreateBgpPeerCmd.java | 2 +- .../admin/network/bgp/DedicateBgpPeerCmd.java | 2 +- .../admin/network/bgp/DeleteBgpPeerCmd.java | 2 +- .../bgp/ReleaseDedicatedBgpPeerCmd.java | 2 +- .../admin/network/bgp/UpdateBgpPeerCmd.java | 2 +- .../ChangeOutOfBandManagementPasswordCmd.java | 4 ++-- ...sableOutOfBandManagementForClusterCmd.java | 4 ++-- .../DisableOutOfBandManagementForHostCmd.java | 4 ++-- .../DisableOutOfBandManagementForZoneCmd.java | 4 ++-- ...nableOutOfBandManagementForClusterCmd.java | 4 ++-- .../EnableOutOfBandManagementForHostCmd.java | 4 ++-- .../EnableOutOfBandManagementForZoneCmd.java | 4 ++-- ...ssueOutOfBandManagementPowerActionCmd.java | 4 ++-- .../region/DeletePortableIpRangeCmd.java | 2 +- .../resource/UploadCustomCertificateCmd.java | 2 +- .../admin/router/ConfigureOvsElementCmd.java | 4 ++-- .../ConfigureVirtualRouterElementCmd.java | 4 ++-- .../router/CreateVirtualRouterElementCmd.java | 2 +- .../admin/router/DestroyRouterCmd.java | 4 ++-- .../GetRouterHealthCheckResultsCmd.java | 2 +- .../command/admin/router/RebootRouterCmd.java | 4 ++-- .../command/admin/router/StartRouterCmd.java | 4 ++-- .../command/admin/router/StopRouterCmd.java | 4 ++-- .../router/UpgradeRouterTemplateCmd.java | 2 +- .../CancelPrimaryStorageMaintenanceCmd.java | 2 +- .../storage/ChangeStoragePoolScopeCmd.java | 11 +-------- .../storage/ConfigureStorageAccessCmd.java | 2 +- .../storage/DownloadImageStoreObjectCmd.java | 2 +- ...reparePrimaryStorageForMaintenanceCmd.java | 2 +- .../admin/storage/SyncStoragePoolCmd.java | 2 +- .../admin/systemvm/DestroySystemVmCmd.java | 6 ++--- .../admin/systemvm/MigrateSystemVMCmd.java | 6 ++--- .../admin/systemvm/PatchSystemVMCmd.java | 3 +-- .../admin/systemvm/RebootSystemVmCmd.java | 6 ++--- .../admin/systemvm/ScaleSystemVMCmd.java | 4 ++-- .../admin/systemvm/StartSystemVMCmd.java | 4 ++-- .../admin/systemvm/StopSystemVmCmd.java | 4 ++-- .../admin/systemvm/UpgradeSystemVMCmd.java | 4 ++-- .../admin/usage/AddTrafficTypeCmd.java | 2 +- .../admin/usage/DeleteTrafficTypeCmd.java | 2 +- .../admin/usage/UpdateTrafficTypeCmd.java | 2 +- .../api/command/admin/user/DeleteUserCmd.java | 2 +- .../command/admin/user/DisableUserCmd.java | 4 ++-- .../api/command/admin/user/EnableUserCmd.java | 2 +- .../api/command/admin/user/MoveUserCmd.java | 2 +- .../api/command/admin/user/UpdateUserCmd.java | 2 +- .../api/command/admin/vm/ExpungeVMCmd.java | 4 ++-- .../admin/vm/ImportUnmanagedInstanceCmd.java | 3 +-- .../api/command/admin/vm/MigrateVMCmd.java | 16 ++++++------- .../MigrateVirtualMachineWithVolumeCmd.java | 2 +- .../admin/vm/UnmanageVMInstanceCmd.java | 4 ++-- .../admin/volume/RecoverVolumeCmdByAdmin.java | 3 ++- .../admin/volume/UnmanageVolumeCmd.java | 2 +- .../admin/vpc/DeletePrivateGatewayCmd.java | 4 ++-- .../admin/vpc/DeleteVPCOfferingCmd.java | 2 +- .../admin/vpc/UpdateVPCOfferingCmd.java | 2 +- .../api/command/admin/zone/DeleteZoneCmd.java | 2 +- .../zone/MarkDefaultZoneForAccountCmd.java | 2 +- .../api/command/admin/zone/UpdateZoneCmd.java | 2 +- .../user/account/AddAccountToProjectCmd.java | 8 ++++--- .../user/account/AddUserToProjectCmd.java | 2 +- .../account/DeleteAccountFromProjectCmd.java | 4 ++-- .../account/DeleteUserFromProjectCmd.java | 4 ++-- .../user/address/AssociateIPAddrCmd.java | 2 +- .../user/address/DisassociateIPAddrCmd.java | 4 ++-- .../user/address/ReleaseIPAddrCmd.java | 2 +- .../affinitygroup/DeleteAffinityGroupCmd.java | 2 +- .../UpdateVMAffinityGroupCmd.java | 2 +- .../autoscale/CreateAutoScalePolicyCmd.java | 2 +- .../autoscale/CreateAutoScaleVmGroupCmd.java | 2 +- .../user/autoscale/CreateConditionCmd.java | 2 +- .../autoscale/DeleteAutoScalePolicyCmd.java | 4 ++-- .../autoscale/DeleteAutoScaleVmGroupCmd.java | 4 ++-- .../DeleteAutoScaleVmProfileCmd.java | 4 ++-- .../user/autoscale/DeleteConditionCmd.java | 2 +- .../autoscale/DisableAutoScaleVmGroupCmd.java | 2 +- .../autoscale/EnableAutoScaleVmGroupCmd.java | 2 +- .../autoscale/UpdateAutoScalePolicyCmd.java | 4 ++-- .../autoscale/UpdateAutoScaleVmGroupCmd.java | 4 ++-- .../UpdateAutoScaleVmProfileCmd.java | 4 ++-- .../user/autoscale/UpdateConditionCmd.java | 2 +- ...signVirtualMachineToBackupOfferingCmd.java | 2 +- .../command/user/backup/CreateBackupCmd.java | 4 +--- .../command/user/backup/DeleteBackupCmd.java | 4 +--- ...veVirtualMachineFromBackupOfferingCmd.java | 2 +- .../command/user/backup/RestoreBackupCmd.java | 4 +--- ...storeVolumeFromBackupAndAttachToVMCmd.java | 2 +- .../command/user/bucket/CreateBucketCmd.java | 2 +- .../command/user/bucket/DeleteBucketCmd.java | 2 +- .../command/user/bucket/UpdateBucketCmd.java | 2 +- .../firewall/CreateEgressFirewallRuleCmd.java | 2 +- .../user/firewall/CreateFirewallRuleCmd.java | 2 +- .../firewall/CreatePortForwardingRuleCmd.java | 2 +- .../firewall/DeleteEgressFirewallRuleCmd.java | 4 ++-- .../user/firewall/DeleteFirewallRuleCmd.java | 4 ++-- .../firewall/DeletePortForwardingRuleCmd.java | 4 ++-- .../firewall/UpdateEgressFirewallRuleCmd.java | 2 +- .../user/firewall/UpdateFirewallRuleCmd.java | 2 +- .../user/ipv6/CreateIpv6FirewallRuleCmd.java | 2 +- .../user/ipv6/DeleteIpv6FirewallRuleCmd.java | 4 ++-- .../user/ipv6/UpdateIpv6FirewallRuleCmd.java | 2 +- .../api/command/user/iso/AttachIsoCmd.java | 4 ++-- .../api/command/user/iso/DeleteIsoCmd.java | 4 ++-- .../api/command/user/iso/DetachIsoCmd.java | 2 +- .../api/command/user/iso/ExtractIsoCmd.java | 11 ++++----- .../AssignCertToLoadBalancerCmd.java | 2 +- .../AssignToLoadBalancerRuleCmd.java | 4 ++-- .../CreateApplicationLoadBalancerCmd.java | 2 +- .../CreateLBHealthCheckPolicyCmd.java | 2 +- .../CreateLBStickinessPolicyCmd.java | 2 +- .../CreateLoadBalancerRuleCmd.java | 2 +- .../DeleteApplicationLoadBalancerCmd.java | 4 ++-- .../DeleteLBHealthCheckPolicyCmd.java | 4 ++-- .../DeleteLBStickinessPolicyCmd.java | 4 ++-- .../DeleteLoadBalancerRuleCmd.java | 4 ++-- .../RemoveCertFromLoadBalancerCmd.java | 2 +- .../RemoveFromLoadBalancerRuleCmd.java | 4 ++-- .../UpdateApplicationLoadBalancerCmd.java | 4 ++-- .../UpdateLoadBalancerRuleCmd.java | 4 ++-- .../user/nat/CreateIpForwardingRuleCmd.java | 2 +- .../user/nat/DeleteIpForwardingRuleCmd.java | 4 ++-- .../command/user/nat/DisableStaticNatCmd.java | 2 +- .../user/network/CreateNetworkACLCmd.java | 2 +- .../user/network/DeleteNetworkACLCmd.java | 4 ++-- .../user/network/DeleteNetworkACLListCmd.java | 4 ++-- .../user/network/DeleteNetworkCmd.java | 4 ++-- .../network/ReplaceNetworkACLListCmd.java | 10 ++++++-- .../user/network/RestartNetworkCmd.java | 2 +- .../user/network/UpdateNetworkACLItemCmd.java | 2 +- .../routing/CreateRoutingFirewallRuleCmd.java | 2 +- .../routing/DeleteRoutingFirewallRuleCmd.java | 4 ++-- .../routing/UpdateRoutingFirewallRuleCmd.java | 2 +- .../user/project/ActivateProjectCmd.java | 4 ++-- .../user/project/DeleteProjectCmd.java | 4 ++-- .../project/DeleteProjectInvitationCmd.java | 4 ++-- .../user/project/SuspendProjectCmd.java | 4 ++-- .../user/project/UpdateProjectCmd.java | 4 ++-- .../project/UpdateProjectInvitationCmd.java | 4 ++-- .../AssignToGlobalLoadBalancerRuleCmd.java | 4 ++-- .../gslb/CreateGlobalLoadBalancerRuleCmd.java | 2 +- .../gslb/DeleteGlobalLoadBalancerRuleCmd.java | 4 ++-- .../RemoveFromGlobalLoadBalancerRuleCmd.java | 4 ++-- .../gslb/UpdateGlobalLoadBalancerRuleCmd.java | 4 ++-- .../RevokeSecurityGroupEgressCmd.java | 2 +- .../RevokeSecurityGroupIngressCmd.java | 2 +- .../user/snapshot/ArchiveSnapshotCmd.java | 4 ++-- .../user/snapshot/CopySnapshotCmd.java | 16 ++++++++----- .../user/snapshot/CreateSnapshotCmd.java | 12 ++++------ .../CreateSnapshotFromVMSnapshotCmd.java | 4 ++-- .../user/snapshot/DeleteSnapshotCmd.java | 4 ++-- .../user/snapshot/ExtractSnapshotCmd.java | 4 ++-- .../user/snapshot/RevertSnapshotCmd.java | 4 ++-- .../snapshot/UpdateSnapshotPolicyCmd.java | 2 +- .../ChangeSharedFSDiskOfferingCmd.java | 2 +- .../ChangeSharedFSServiceOfferingCmd.java | 2 +- .../storage/sharedfs/DestroySharedFSCmd.java | 2 +- .../storage/sharedfs/ExpungeSharedFSCmd.java | 2 +- .../storage/sharedfs/RestartSharedFSCmd.java | 2 +- .../storage/sharedfs/StartSharedFSCmd.java | 2 +- .../storage/sharedfs/StopSharedFSCmd.java | 2 +- .../user/template/CopyTemplateCmd.java | 18 +++++++------- .../user/template/CreateTemplateCmd.java | 2 +- .../user/template/DeleteTemplateCmd.java | 4 ++-- .../user/template/ExtractTemplateCmd.java | 10 ++++---- .../api/command/user/vm/AddIpToVmNicCmd.java | 6 ++--- .../api/command/user/vm/AddNicToVMCmd.java | 5 ++-- .../api/command/user/vm/BaseDeployVMCmd.java | 6 ++--- .../api/command/user/vm/DeployVMCmd.java | 2 +- .../api/command/user/vm/DestroyVMCmd.java | 4 ++-- .../api/command/user/vm/RebootVMCmd.java | 4 ++-- .../command/user/vm/RemoveIpFromVmNicCmd.java | 4 ++-- .../command/user/vm/RemoveNicFromVMCmd.java | 6 ++--- .../command/user/vm/ResetVMPasswordCmd.java | 4 ++-- .../api/command/user/vm/ResetVMSSHKeyCmd.java | 4 ++-- .../command/user/vm/ResetVMUserDataCmd.java | 2 +- .../api/command/user/vm/RestoreVMCmd.java | 4 ++-- .../api/command/user/vm/ScaleVMCmd.java | 3 +-- .../api/command/user/vm/StartVMCmd.java | 4 ++-- .../api/command/user/vm/StopVMCmd.java | 4 ++-- .../user/vm/UpdateDefaultNicForVMCmd.java | 6 ++--- .../api/command/user/vm/UpdateVMCmd.java | 2 +- .../api/command/user/vm/UpdateVmNicIpCmd.java | 6 ++--- .../api/command/user/vm/UpgradeVMCmd.java | 2 +- .../user/vmsnapshot/CreateVMSnapshotCmd.java | 5 ++-- .../user/vmsnapshot/DeleteVMSnapshotCmd.java | 4 ++-- .../vmsnapshot/RevertToVMSnapshotCmd.java | 4 ++-- .../user/volume/AddResourceDetailCmd.java | 2 +- .../command/user/volume/AttachVolumeCmd.java | 4 ++-- .../volume/ChangeOfferingForVolumeCmd.java | 5 ++-- .../user/volume/CheckAndRepairVolumeCmd.java | 4 ++-- .../command/user/volume/CreateVolumeCmd.java | 14 +++++++++-- .../command/user/volume/DeleteVolumeCmd.java | 2 +- .../command/user/volume/DestroyVolumeCmd.java | 4 ++-- .../command/user/volume/DetachVolumeCmd.java | 18 ++++++++------ .../command/user/volume/ExtractVolumeCmd.java | 7 +----- .../command/user/volume/MigrateVolumeCmd.java | 3 +-- .../command/user/volume/RecoverVolumeCmd.java | 2 +- .../command/user/volume/ResizeVolumeCmd.java | 12 ++++++---- .../command/user/volume/UpdateVolumeCmd.java | 2 +- .../command/user/volume/UploadVolumeCmd.java | 3 +-- .../user/vpc/CreateStaticRouteCmd.java | 2 +- .../user/vpc/DeleteStaticRouteCmd.java | 4 ++-- .../api/command/user/vpc/DeleteVPCCmd.java | 2 +- .../api/command/user/vpc/RestartVPCCmd.java | 2 +- .../api/command/user/vpc/UpdateVPCCmd.java | 2 +- .../command/user/vpn/CreateVpnGatewayCmd.java | 2 +- .../user/vpn/DeleteRemoteAccessVpnCmd.java | 2 +- .../user/vpn/DeleteVpnConnectionCmd.java | 2 +- .../user/vpn/DeleteVpnCustomerGatewayCmd.java | 2 +- .../cloudstack/context/CallContext.java | 9 +++++++ ...reateIpv4SubnetForGuestNetworkCmdTest.java | 8 ++++++- .../CreateIpv4SubnetForZoneCmdTest.java | 8 ++++++- .../DedicateIpv4SubnetForZoneCmdTest.java | 8 ++++++- ...eleteIpv4SubnetForGuestNetworkCmdTest.java | 8 ++++++- .../DeleteIpv4SubnetForZoneCmdTest.java | 8 ++++++- ...easeDedicatedIpv4SubnetForZoneCmdTest.java | 8 ++++++- .../UpdateIpv4SubnetForZoneCmdTest.java | 8 ++++++- .../bgp/ChangeBgpPeersForNetworkCmdTest.java | 7 +++++- .../bgp/ChangeBgpPeersForVpcCmdTest.java | 7 +++++- .../network/bgp/CreateBgpPeerCmdTest.java | 8 ++++++- .../network/bgp/DedicateBgpPeerCmdTest.java | 8 ++++++- .../network/bgp/DeleteBgpPeerCmdTest.java | 8 ++++++- .../bgp/ReleaseDedicatedBgpPeerCmdTest.java | 8 ++++++- .../network/bgp/UpdateBgpPeerCmdTest.java | 8 ++++++- .../DownloadImageStoreObjectCmdTest.java | 7 +++++- .../admin/volume/UnmanageVolumeCmdTest.java | 8 ++++++- .../command/test/CreateSnapshotCmdTest.java | 12 +++++----- .../test/UpdateAutoScaleVmProfileCmdTest.java | 2 +- .../command/test/UpdateConditionCmdTest.java | 8 ++++++- .../DeleteRoutingFirewallRuleCmdTest.java | 8 ++++++- .../orchestration/NetworkOrchestrator.java | 2 +- .../orchestration/VolumeOrchestrator.java | 4 ++-- .../extensions/api/RunCustomActionCmd.java | 2 +- .../api/command/QuotaTariffDeleteCmd.java | 2 +- .../api/commands/DedicateClusterCmd.java | 8 ++++++- .../api/commands/DedicateHostCmd.java | 8 ++++++- .../api/commands/DedicatePodCmd.java | 8 ++++++- .../api/commands/DedicateZoneCmd.java | 8 ++++++- .../commands/ReleaseDedicatedClusterCmd.java | 2 +- .../api/commands/ReleaseDedicatedHostCmd.java | 2 +- .../api/commands/ReleaseDedicatedPodCmd.java | 2 +- .../api/commands/ReleaseDedicatedZoneCmd.java | 2 +- .../cloudstack/api/AddBaremetalDhcpCmd.java | 2 +- .../cloudstack/api/AddBaremetalPxeCmd.java | 2 +- ...BaremetalProvisionDoneNotificationCmd.java | 2 +- .../manager/ExternalTemplateAdapter.java | 2 +- .../AddNodesToKubernetesClusterCmd.java | 2 +- .../cluster/DeleteKubernetesClusterCmd.java | 9 +------ .../RemoveNodesFromKubernetesClusterCmd.java | 2 +- .../cluster/UpgradeKubernetesClusterCmd.java | 9 +------ .../commands/AddBigSwitchBcfDeviceCmd.java | 2 +- .../commands/DeleteBigSwitchBcfDeviceCmd.java | 3 ++- .../guru/BigSwitchBcfGuestNetworkGuru.java | 2 +- .../cloudstack/api/AddGloboDnsHostCmd.java | 2 +- .../service/NetrisGuestNetworkGuru.java | 2 +- .../DeleteNetscalerLoadBalancerCmd.java | 2 +- .../api/commands/DeployNetscalerVpxCmd.java | 2 +- .../api/commands/StopNetScalerVMCmd.java | 4 ++-- .../commands/DeleteNiciraNvpDeviceCmd.java | 2 +- .../AddOpenDaylightControllerCmd.java | 2 +- .../DeleteOpenDaylightControllerCmd.java | 2 +- .../network/guru/OvsGuestNetworkGuru.java | 4 ++-- .../api/commands/AddPaloAltoFirewallCmd.java | 2 +- .../ConfigurePaloAltoFirewallCmd.java | 2 +- .../commands/DeletePaloAltoFirewallCmd.java | 2 +- .../network/guru/VxlanGuestNetworkGuru.java | 2 +- .../api/command/LdapCreateAccountCmd.java | 2 +- .../api/command/AuthorizeSAMLSSOCmd.java | 2 +- .../api/dispatch/ParamProcessWorker.java | 11 ++++++++- .../ConfigurationManagerImpl.java | 24 ++++++++++--------- .../cloud/network/IpAddressManagerImpl.java | 2 +- .../com/cloud/network/Ipv6ServiceImpl.java | 2 +- .../network/as/AutoScaleManagerImpl.java | 6 ++--- .../network/firewall/FirewallManagerImpl.java | 2 +- .../guru/ExternalGuestNetworkGuru.java | 2 +- .../cloud/network/guru/GuestNetworkGuru.java | 2 +- .../lb/LoadBalancingRulesManagerImpl.java | 2 +- .../cloud/network/rules/RulesManagerImpl.java | 7 +++--- .../network/vpc/NetworkACLManagerImpl.java | 3 ++- .../com/cloud/network/vpc/VpcManagerImpl.java | 20 ++++++++-------- .../network/vpn/Site2SiteVpnManagerImpl.java | 10 ++++---- .../cloud/projects/ProjectManagerImpl.java | 2 +- .../cloud/server/ManagementServerImpl.java | 2 +- .../cloud/storage/VolumeApiServiceImpl.java | 12 +++++----- .../template/HypervisorTemplateAdapter.java | 2 +- .../cloud/template/TemplateAdapterBase.java | 2 +- .../cloud/template/TemplateManagerImpl.java | 4 ++-- .../java/com/cloud/vm/UserVmManagerImpl.java | 4 ++-- .../apache/cloudstack/ca/CAManagerImpl.java | 10 ++++---- .../gui/theme/GuiThemeServiceImpl.java | 2 +- .../network/RoutedIpv4ManagerImpl.java | 2 +- .../ApplicationLoadBalancerManagerImpl.java | 2 +- 364 files changed, 769 insertions(+), 622 deletions(-) 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 a4de301cc991..f30f6f327826 100644 --- a/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java @@ -27,6 +27,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.regex.Pattern; import javax.inject.Inject; @@ -498,4 +499,14 @@ public Map convertExternalDetailsToMap(Map externalDetails) { } return details; } + + public String getResourceUuid(String parameterName) { + UUID resourceUuid = CallContext.current().getApiResourceUuid(parameterName); + + if (resourceUuid != null) { + return resourceUuid.toString(); + } + + return null; + } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java index ea25c56ee39e..cc154ed964b3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java @@ -177,7 +177,7 @@ public long getEntityOwnerId() { @Override public void execute() { validateParams(); - CallContext.current().setEventDetails("Account Name: " + getUsername() + ", Domain Id:" + getDomainId()); + CallContext.current().setEventDetails("Account Name: " + getUsername() + ", Domain ID:" + getResourceUuid(ApiConstants.DOMAIN_ID)); UserAccount userAccount = _accountService.createUserAccount(this); if (userAccount != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java index 29774e254aa0..f7f8bd974272 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java @@ -108,12 +108,20 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - return "Disabling Account: " + getAccountName() + " in domain: " + getDomainId(); + String message = "Disabling Account "; + + if (getId() != null) { + message += "with ID: " + getResourceUuid(ApiConstants.ID); + } else { + message += getAccountName() + " in Domain: " + getResourceUuid(ApiConstants.DOMAIN_ID); + } + + return message; } @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException { - CallContext.current().setEventDetails("Account Name: " + getAccountName() + ", Domain Id:" + getDomainId()); + CallContext.current().setEventDetails("Account Name: " + getAccountName() + ", Domain Id:" + getResourceUuid(ApiConstants.DOMAIN_ID)); Account result = _regionService.disableAccount(this); if (result != null){ AccountResponse response = _responseGenerator.createAccountResponse(ResponseView.Full, result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java index 232c4760e1e6..13405431f63e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java @@ -81,7 +81,7 @@ public void execute() { if (role == null) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role id provided"); } - CallContext.current().setEventDetails("Role id: " + role.getId() + ", rule:" + getRule() + ", permission: " + getPermission() + ", description: " + getDescription()); + CallContext.current().setEventDetails("Role ID: " + role.getUuid() + ", rule:" + getRule() + ", permission: " + getPermission() + ", description: " + getDescription()); final RolePermission rolePermission = roleService.createRolePermission(role, getRule(), getPermission(), getDescription()); if (rolePermission == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create role permission"); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java index fd2d11aeda0a..80ec08260ab2 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java @@ -70,7 +70,7 @@ public void execute() { if (role == null) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find the role with provided id"); } - CallContext.current().setEventDetails("Role id: " + role.getId()); + CallContext.current().setEventDetails("Role ID: " + role.getUuid()); boolean result = roleService.deleteRole(role); SuccessResponse response = new SuccessResponse(getCommandName()); response.setSuccess(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java index bedaca9e23af..cf4a62bf6c43 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java @@ -68,7 +68,7 @@ public void execute() { if (rolePermission == null) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role permission id provided"); } - CallContext.current().setEventDetails("Role permission id: " + rolePermission.getId()); + CallContext.current().setEventDetails("Role permission ID: " + rolePermission.getUuid()); boolean result = roleService.deleteRolePermission(rolePermission); SuccessResponse response = new SuccessResponse(getCommandName()); response.setSuccess(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DisableRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DisableRoleCmd.java index 80cb92c8362f..2c5659b2bc4b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DisableRoleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DisableRoleCmd.java @@ -55,7 +55,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE if (role == null) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find the role with provided id"); } - CallContext.current().setEventDetails("Role id: " + role.getId()); + CallContext.current().setEventDetails("Role ID: " + role.getUuid()); boolean result = roleService.disableRole(role); SuccessResponse response = new SuccessResponse(getCommandName()); response.setSuccess(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/EnableRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/EnableRoleCmd.java index c4a6505d52f6..05dfbe1270fa 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/EnableRoleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/EnableRoleCmd.java @@ -55,7 +55,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE if (role == null) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find the role with provided id"); } - CallContext.current().setEventDetails("Role id: " + role.getId()); + CallContext.current().setEventDetails("Role ID: " + role.getUuid()); boolean result = roleService.enableRole(role); SuccessResponse response = new SuccessResponse(getCommandName()); response.setSuccess(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java index 8f8115e9957e..992564413f6b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java @@ -111,7 +111,7 @@ public void execute() { if (getRuleId() != null || getRulePermission() != null) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameters permission and ruleid must be mutually exclusive with ruleorder"); } - CallContext.current().setEventDetails("Reordering permissions for role id: " + role.getId()); + CallContext.current().setEventDetails("Reordering permissions for role with ID: " + role.getUuid()); final List rolePermissionsOrder = new ArrayList<>(); for (Long rolePermissionId : getRulePermissionOrder()) { final RolePermission rolePermission = roleService.findRolePermission(rolePermissionId); @@ -129,7 +129,7 @@ public void execute() { if (rolePermission == null) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid rule id provided"); } - CallContext.current().setEventDetails("Updating permission for rule id: " + getRuleId() + " to: " + getRulePermission().toString()); + CallContext.current().setEventDetails("Updating permission for rule with ID: " + getResourceUuid(ApiConstants.RULE_ID) + " to: " + getRulePermission().toString()); result = roleService.updateRolePermission(role, rolePermission, getRulePermission()); } SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRolePermissionCmd.java index d39c2312aa91..e085c10cee0b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRolePermissionCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRolePermissionCmd.java @@ -72,7 +72,7 @@ public void execute() { if (projectRole == null) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid project role ID provided"); } - CallContext.current().setEventDetails("Project Role ID: " + projectRole.getId() + ", Rule:" + getRule() + ", Permission: " + getPermission() + ", Description: " + getDescription()); + CallContext.current().setEventDetails("Project Role ID: " + projectRole.getUuid() + ", Rule:" + getRule() + ", Permission: " + getPermission() + ", Description: " + getDescription()); final ProjectRolePermission projectRolePermission = projRoleService.createProjectRolePermission(this); if (projectRolePermission == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create project role permission"); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRoleCmd.java index 9f8d82489584..84f73e7a1a32 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRoleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRoleCmd.java @@ -69,7 +69,7 @@ public void execute() { if (role == null) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find project role with provided id"); } - CallContext.current().setEventDetails("Deleting Project Role with id: " + role.getId()); + CallContext.current().setEventDetails("Deleting Project Role with ID: " + role.getUuid()); boolean result = projRoleService.deleteProjectRole(role, getProjectId()); SuccessResponse response = new SuccessResponse(getCommandName()); response.setSuccess(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRolePermissionCmd.java index ac68278535e2..d7941a6a4cc3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRolePermissionCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRolePermissionCmd.java @@ -70,7 +70,7 @@ public void execute() { if (rolePermission == null || rolePermission.getProjectId() != getProjectId()) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role permission id provided for the project"); } - CallContext.current().setEventDetails("Deleting Project Role permission with id: " + rolePermission.getId()); + CallContext.current().setEventDetails("Deleting Project Role permission with ID: " + rolePermission.getUuid()); boolean result = projRoleService.deleteProjectRolePermission(rolePermission); SuccessResponse response = new SuccessResponse(); response.setSuccess(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRolePermissionCmd.java index b273b9f58493..fd0c043f2321 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRolePermissionCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRolePermissionCmd.java @@ -115,7 +115,7 @@ public void execute() { if (getProjectRuleId() != null || getProjectRolePermission() != null) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameters permission and ruleid must be mutually exclusive with ruleorder"); } - CallContext.current().setEventDetails("Reordering permissions for role id: " + projectRole.getId()); + CallContext.current().setEventDetails("Reordering permissions for role with ID: " + projectRole.getUuid()); result = updateProjectRolePermissionOrder(projectRole); } else if (getProjectRuleId() != null || getProjectRolePermission() != null ) { @@ -123,7 +123,7 @@ public void execute() { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameters permission and ruleid must be mutually exclusive with ruleorder"); } ProjectRolePermission rolePermission = getValidProjectRolePermission(); - CallContext.current().setEventDetails("Updating project role permission for rule id: " + getProjectRuleId() + " to: " + getProjectRolePermission().toString()); + CallContext.current().setEventDetails("Updating project role permission for rule ID: " + getProjectRuleId() + " to: " + getProjectRolePermission().toString()); result = projRoleService.updateProjectRolePermission(projectId, projectRole, rolePermission, getProjectRolePermission()); } SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java index 0798357b8bcb..d7be56bf3f46 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java @@ -97,7 +97,7 @@ public void create() { @Override public void execute() { - CallContext.current().setEventDetails("Counter ID: " + getEntityId()); + CallContext.current().setEventDetails("Counter ID: " + getEntityUuid()); Counter ctr = _autoScaleService.getCounter(getEntityId()); CounterResponse response = _responseGenerator.createCounterResponse(ctr); response.setResponseName(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java index 769f6fd8b142..8e941965e84b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java @@ -91,6 +91,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting a counter."; + return "Deleting auto scaling counter with ID: " + getResourceUuid(ApiConstants.ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java index 5e702585a2c3..f852f7e25776 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java @@ -156,6 +156,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Importing backup offering: " + name + " (external ID: " + externalId + ") on zone ID " + zoneId ; + return "Importing backup offering: " + name + " (external ID: " + externalId + ") on zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID) ; } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java index 463af000f58b..79dad4269c9b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java @@ -149,6 +149,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "issuing certificate for domain(s)=" + domains + ", ip(s)=" + addresses; + return "Issuing certificate for domain(s)=" + domains + ", ip(s)=" + addresses; } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java index af24e1f10c89..6deaea22ac6c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java @@ -108,7 +108,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Provisioning certificate for host id=" + hostId + " using provider=" + provider; + return "Provisioning certificate for host with ID: " + getResourceUuid(ApiConstants.HOST_ID) + " using provider: " + provider; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ExecuteClusterDrsPlanCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ExecuteClusterDrsPlanCmd.java index 60f2c2b1deea..00e7da6e37c1 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ExecuteClusterDrsPlanCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ExecuteClusterDrsPlanCmd.java @@ -142,6 +142,6 @@ public String getEventType() { @Override public String getEventDescription() { - return String.format("Executing DRS plan for cluster: %d", getId()); + return "Executing DRS plan for cluster with ID: " + getResourceUuid(ApiConstants.ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/GetDiagnosticsDataCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/GetDiagnosticsDataCmd.java index 6a59788715ee..c140de5aa01e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/GetDiagnosticsDataCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/GetDiagnosticsDataCmd.java @@ -140,7 +140,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Getting diagnostics data files from System VM: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); + return "Getting diagnostics data files from System Instance with ID: " + getResourceUuid(ApiConstants.TARGET_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java index 577d86146fdd..d1f22baf6604 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java @@ -153,7 +153,7 @@ public ApiCommandResourceType getApiResourceType() { @Override public String getEventDescription() { - return "Executing diagnostics on System VM: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); + return "Executing diagnostics on System Instance with ID: " + getResourceUuid(ApiConstants.TARGET_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java index a20f69c90f58..d2775548a841 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java @@ -86,7 +86,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Domain Name: " + getDomainName() + ((getParentDomainId() != null) ? ", Parent DomainId :" + getParentDomainId() : "")); + CallContext.current().setEventDetails("Domain Name: " + getDomainName() + ((getParentDomainId() != null) ? ", Parent Domain ID:" + getResourceUuid(ApiConstants.PARENT_DOMAIN_ID) : "")); Domain domain = _domainService.createDomain(getDomainName(), getParentDomainId(), getNetworkDomain(), getDomainUUID()); if (domain != null) { DomainResponse response = _responseGenerator.createDomainResponse(domain); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java index 6adb457f4f83..cf02e6a56bf8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java @@ -88,12 +88,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting domain: " + getId(); + return "Deleting domain with ID: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { - CallContext.current().setEventDetails("Domain Id: " + getId()); + CallContext.current().setEventDetails("Domain ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _regionService.deleteDomain(this); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java index adce521627fb..124a84931548 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java @@ -82,7 +82,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Domain Id: " + getId()); + CallContext.current().setEventDetails("Domain ID: " + getResourceUuid(ApiConstants.ID)); Domain domain = _regionService.updateDomain(this); if (domain != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/gpu/DiscoverGpuDevicesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/gpu/DiscoverGpuDevicesCmd.java index 2ac07a9fb3a0..83aca1a2eb64 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/gpu/DiscoverGpuDevicesCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/gpu/DiscoverGpuDevicesCmd.java @@ -46,7 +46,7 @@ public class DiscoverGpuDevicesCmd extends BaseListCmd { @Override public void execute() { - CallContext.current().setEventDetails("Discovering GPU Devices on host id: " + getId()); + CallContext.current().setEventDetails("Discovering GPU Devices on host with ID: " + getResourceUuid(ApiConstants.ID)); ListResponse response = gpuService.discoverGpuDevices(this); response.setResponseName(getCommandName()); setResponseObject(response); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java index 1868d0412a18..c0e995c497d2 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java @@ -120,7 +120,7 @@ public void create() { @Override public void execute() { - CallContext.current().setEventDetails("Guest OS Id: " + getEntityId()); + CallContext.current().setEventDetails("Guest OS ID: " + getEntityUuid()); GuestOS guestOs = _mgr.getAddedGuestOs(getEntityId()); if (guestOs != null) { GuestOSResponse response = _responseGenerator.createGuestOSResponse(guestOs); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java index d38682ce5bb4..f5c7d965c13f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java @@ -62,7 +62,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Guest OS Id: " + id); + CallContext.current().setEventDetails("Guest OS ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _mgr.removeGuestOs(this); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); @@ -74,7 +74,7 @@ public void execute() { @Override public String getEventDescription() { - return "Removing Guest OS: " + getId(); + return "Removing Guest OS with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java index a472ab672c55..bd4a53889f25 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java @@ -62,7 +62,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Guest OS Mapping Id: " + id); + CallContext.current().setEventDetails("Guest OS Mapping ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _mgr.removeGuestOsMapping(this); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); @@ -74,7 +74,7 @@ public void execute() { @Override public String getEventDescription() { - return "Removing Guest OS Mapping: " + getId(); + return "Removing Guest OS Mapping with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java index 59909e09854a..035ff6a19e24 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java @@ -123,7 +123,7 @@ public void execute() { @Override public String getEventDescription() { - return "Updating guest OS: " + getId(); + return "Updating guest OS with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java index fc67ef0a7e76..161bb5323070 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java @@ -86,7 +86,7 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - return "Updating Guest OS Mapping: " + getId(); + return "Updating Guest OS with ID: " + getResourceUuid(ApiConstants.ID) + " mapping."; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java index d7707e197d64..6804e4355ca8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java @@ -102,7 +102,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE if (!result) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to configure HA provider for the host"); } - CallContext.current().setEventDetails("Host Id:" + host.getId() + " HA configured with provider: " + getHaProvider()); + CallContext.current().setEventDetails("Host ID:" + host.getUuid() + " HA configured with provider: " + getHaProvider()); CallContext.current().putContextParameter(Host.class, host.getUuid()); setupResponse(result, host.getUuid()); @@ -115,6 +115,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Configure HA for host: " + getHostId(); + return "Configuring HA for host with ID: " + getResourceUuid(ApiConstants.HOST_ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java index 51554b7607dc..63c657a9e454 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java @@ -89,7 +89,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to find cluster by ID: " + getClusterId()); } final boolean result = haConfigManager.disableHA(cluster); - CallContext.current().setEventDetails("Cluster Id:" + cluster.getId() + " HA enabled: false"); + CallContext.current().setEventDetails("Cluster ID:" + cluster.getUuid() + " HA enabled: false"); CallContext.current().putContextParameter(Cluster.class, cluster.getUuid()); setupResponse(result); @@ -102,7 +102,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Disable HA for cluster: " + getClusterId(); + return "Disabling HA for cluster with ID: " + getResourceUuid(ApiConstants.CLUSTER_ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java index ad9c64145322..b90f731ff565 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java @@ -91,7 +91,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE } final boolean result = haConfigManager.disableHA(host.getId(), HAResource.ResourceType.Host); - CallContext.current().setEventDetails("Host Id:" + host.getId() + " HA enabled: false"); + CallContext.current().setEventDetails("Host ID:" + host.getUuid() + " HA enabled: false"); CallContext.current().putContextParameter(Host.class, host.getUuid()); setupResponse(result, host.getUuid()); @@ -104,6 +104,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Disable HA for host: " + getHostId(); + return "Disabling HA for host with ID: " + getResourceUuid(ApiConstants.HOST_ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java index 1f0758459b5d..07a6fbd2b399 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java @@ -90,7 +90,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE } final boolean result = haConfigManager.disableHA(dataCenter); - CallContext.current().setEventDetails("Zone Id:" + dataCenter.getId() + " HA enabled: false"); + CallContext.current().setEventDetails("Zone ID:" + dataCenter.getUuid() + " HA enabled: false"); CallContext.current().putContextParameter(DataCenter.class, dataCenter.getUuid()); setupResponse(result); @@ -103,7 +103,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Disable HA for zone: " + getZoneId(); + return "Disabling HA for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java index 3bb7a4c3070d..635fba988c60 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java @@ -90,7 +90,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE } final boolean result = haConfigManager.enableHA(cluster); - CallContext.current().setEventDetails("Cluster Id:" + cluster.getId() + " HA enabled: true"); + CallContext.current().setEventDetails("Cluster ID:" + cluster.getUuid() + " HA enabled: true"); CallContext.current().putContextParameter(Cluster.class, cluster.getUuid()); setupResponse(result); @@ -103,6 +103,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Enable HA for cluster: " + getClusterId(); + return "Enabling HA for cluster with ID: " + getResourceUuid(ApiConstants.CLUSTER_ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java index f54767225432..0bda19a7ad3c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java @@ -91,7 +91,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE } final boolean result = haConfigManager.enableHA(host.getId(), HAResource.ResourceType.Host); - CallContext.current().setEventDetails("Host Id:" + host.getId() + " HA enabled: true"); + CallContext.current().setEventDetails("Host ID:" + host.getUuid() + " HA enabled: true"); CallContext.current().putContextParameter(Host.class, host.getUuid()); setupResponse(result, host.getUuid()); @@ -104,6 +104,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Enable HA for host: " + getHostId(); + return "Enabling HA for host with ID: " + getResourceUuid(ApiConstants.HOST_ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java index 99607315c543..f6d0f62bb120 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java @@ -90,7 +90,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE } final boolean result = haConfigManager.enableHA(dataCenter); - CallContext.current().setEventDetails("Zone Id:" + dataCenter.getId() + " HA enabled: true"); + CallContext.current().setEventDetails("Zone ID:" + dataCenter.getUuid() + " HA enabled: true"); CallContext.current().putContextParameter(DataCenter.class, dataCenter.getUuid()); setupResponse(result); @@ -103,7 +103,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Enable HA for zone: " + getZoneId(); + return "Enabling HA for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostAsDegradedCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostAsDegradedCmd.java index f68da1edcd17..56930d47b2ec 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostAsDegradedCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostAsDegradedCmd.java @@ -78,7 +78,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "declaring host: " + getId() + " as Degraded"; + return "Removing host with ID: " + getResourceUuid(ApiConstants.ID) + " from Degraded state."; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostMaintenanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostMaintenanceCmd.java index 111172200b9a..5d44bafb4b5c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostMaintenanceCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostMaintenanceCmd.java @@ -76,7 +76,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Canceling maintenance for host: " + getId(); + return "Canceling maintenance for host with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeclareHostAsDegradedCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeclareHostAsDegradedCmd.java index 209d8b65fbab..1dd65a583706 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeclareHostAsDegradedCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeclareHostAsDegradedCmd.java @@ -78,7 +78,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "declaring host: " + getId() + " as Degraded"; + return "Declaring host with ID: " + getResourceUuid(ApiConstants.ID) + " as Degraded."; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForHostMaintenanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForHostMaintenanceCmd.java index b76f500359a3..843c7fd7fcbe 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForHostMaintenanceCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForHostMaintenanceCmd.java @@ -76,7 +76,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "preparing host: " + getId() + " for maintenance"; + return "Preparing host with ID: " + getResourceUuid(ApiConstants.ID) + " for maintenance."; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java index 178a96cedbd6..b9892ed6033c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java @@ -77,7 +77,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "reconnecting host: " + getId(); + return "Reconnecting host with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java index d7905421a8f3..bddb5b13e452 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java @@ -72,7 +72,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "releasing reservation for host: " + getId(); + return "Releasing reservation from host with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java index 9bb28523ecad..51aa86546603 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java @@ -84,12 +84,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "configuring internal load balancer element: " + id; + return "Configuring internal load balancer element with ID: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { - CallContext.current().setEventDetails("Internal load balancer element: " + id); + CallContext.current().setEventDetails("Internal load balancer element: " + getResourceUuid(ApiConstants.ID)); InternalLoadBalancerElementService service = _networkService.getInternalLoadBalancerElementById(id); VirtualRouterProvider result = service.configureInternalLoadBalancerElement(getId(), getEnabled()); if (result != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java index 474bbc831e5c..aa9e5f1ba7f4 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java @@ -74,7 +74,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Virtual router element Id: " + getEntityId()); + CallContext.current().setEventDetails("Virtual router element ID: " + getEntityUuid()); InternalLoadBalancerElementService service = _networkService.getInternalLoadBalancerElementByNetworkServiceProviderId(getNspId()); VirtualRouterProvider result = service.getInternalLoadBalancerElement(getEntityId()); if (result != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java index b5aa3c8d9b07..d9d4e46726fc 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java @@ -88,7 +88,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "starting Internal LB Instance: " + getId(); + return "Starting internal LB Instance with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -103,7 +103,7 @@ public Long getApiResourceId() { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { - CallContext.current().setEventDetails("Internal LB Instance ID: " + getId()); + CallContext.current().setEventDetails("Internal LB Instance ID: " + getResourceUuid(ApiConstants.ID)); VirtualRouter result = null; VirtualRouter router = _routerService.findRouter(getId()); if (router == null || router.getRole() != Role.INTERNAL_LB_VM) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java index 82eddb27c7dd..253c59e671e5 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java @@ -86,7 +86,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Stopping Internal LB Instance: " + getId(); + return "Stopping Internal LB Instance: " + getResourceUuid(ApiConstants.ID); } @Override @@ -105,7 +105,7 @@ public boolean isForced() { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException { - CallContext.current().setEventDetails("Internal LB Instance Id: " + getId()); + CallContext.current().setEventDetails("Internal LB Instance ID: " + getResourceUuid(ApiConstants.ID)); VirtualRouter result = null; VirtualRouter vm = _routerService.findRouter(getId()); if (vm == null || vm.getRole() != Role.INTERNAL_LB_VM) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java index a0013f9d6e2b..3e42a0103d8b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java @@ -101,7 +101,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Network ServiceProvider Id: " + getEntityId()); + CallContext.current().setEventDetails("Network ServiceProvider ID: " + getEntityUuid()); PhysicalNetworkServiceProvider result = _networkService.getCreatedPhysicalNetworkServiceProvider(getEntityId()); if (result != null) { ProviderResponse response = _responseGenerator.createNetworkServiceProviderResponse(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateGuestNetworkIpv6PrefixCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateGuestNetworkIpv6PrefixCmd.java index f6b035c57837..614dcf9d0751 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateGuestNetworkIpv6PrefixCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateGuestNetworkIpv6PrefixCmd.java @@ -83,7 +83,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Creating guest IPv6 prefix " + getPrefix() + " for zone=" + getZoneId(); + return "Creating guest IPv6 prefix " + getPrefix() + " for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmd.java index a482cb1d4f27..4d645376a909 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmd.java @@ -85,7 +85,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Creating guest IPv4 subnet " + getSubnet() + " in zone subnet=" + getParentId(); + return "Creating guest IPv4 subnet " + getSubnet() + " in zone subnet: " + getResourceUuid(ApiConstants.PARENT_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmd.java index 5f48cf9c6327..48a6002fb5c0 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmd.java @@ -102,7 +102,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Creating guest IPv4 subnet " + getSubnet() + " for zone=" + getZoneId(); + return "Creating guest IPv4 subnet " + getSubnet() + " for zone: " + getResourceUuid(ApiConstants.ZONE_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java index a7826e022a68..2780c4eaf050 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java @@ -132,7 +132,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Creating management ip range from " + getStartIp() + " to " + getEndIp() + " and gateway=" + getGateWay() + ", netmask=" + getNetmask() + " of pod=" + getPodId(); + return "Creating management IP range from " + getStartIp() + " to " + getEndIp() + ", with gateway: " + getGateWay() + ", netmask:" + getNetmask() + " on pod:" + getPodId(); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java index f4ce9483bfbd..75444bebd3dd 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java @@ -148,7 +148,7 @@ public String getEventDescription() { @Override public void execute() { - CallContext.current().setEventDetails("Physical Network ID: " + getEntityId()); + CallContext.current().setEventDetails("Physical Network ID: " + getEntityUuid()); PhysicalNetwork result = _networkService.getCreatedPhysicalNetwork(getEntityId()); if (result != null) { PhysicalNetworkResponse response = _responseGenerator.createPhysicalNetworkResponse(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmd.java index 2df032c559c5..cc76b284e24a 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmd.java @@ -82,7 +82,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Dedicating zone IPv4 subnet " + getId(); + return "Dedicating zone's IPv4 subnet with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteGuestNetworkIpv6PrefixCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteGuestNetworkIpv6PrefixCmd.java index e2ada4191a82..405bbb594edb 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteGuestNetworkIpv6PrefixCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteGuestNetworkIpv6PrefixCmd.java @@ -63,7 +63,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting guest IPv6 prefix " + getId(); + return "Deleting guest IPv6 prefix with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmd.java index 28a646f9d036..f6b22f79dfc7 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmd.java @@ -59,7 +59,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting guest IPv4 subnet " + getId(); + return "Deleting guest IPv4 subnet with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmd.java index 222bc1bad98d..0ff2a9ad70b8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmd.java @@ -59,7 +59,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting zone IPv4 subnet " + getId(); + return "Deleting zone IPv4 subnet with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java index 5b50c90b3964..1e69aaa6c440 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java @@ -100,7 +100,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting management ip range from " + getStartIp() + " to " + getEndIp() + " of Pod: " + getPodId(); + return "Deleting management IP range from " + getStartIp() + " to " + getEndIp() + " from Pod: " + getResourceUuid(ApiConstants.POD_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java index 23d14966c49b..2573e92b9860 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java @@ -91,7 +91,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting Physical network ServiceProvider: " + getId(); + return "Deleting Physical network ServiceProvider with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java index 70c35716b657..9994e8e391d7 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java @@ -65,7 +65,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Physical Network Id: " + id); + CallContext.current().setEventDetails("Physical Network Id: " + getResourceUuid(ApiConstants.ID)); boolean result = _networkService.deletePhysicalNetwork(getId()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); @@ -77,7 +77,7 @@ public void execute() { @Override public String getEventDescription() { - return "Deleting Physical network: " + getId(); + return "Deleting Physical network with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java index 4ffe58332ebf..dcab38561408 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java @@ -64,7 +64,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting storage ip range " + getId(); + return "Deleting storage IP range with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java index 8ac9c8da691d..ad78bd3b406c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java @@ -115,7 +115,7 @@ public void execute() { @Override public String getEventDescription() { - StringBuilder eventMsg = new StringBuilder("Migrating network: " + getId()); + String description = "Migrating Network with ID: " + getResourceUuid(ApiConstants.NETWORK_ID); if (getNetworkOfferingId() != null) { Network network = _networkService.getNetwork(getId()); if (network == null) { @@ -128,11 +128,11 @@ public String getEventDescription() { throw new InvalidParameterValueException("Network offering id supplied is invalid"); } - eventMsg.append(". Original network offering id: " + oldOff.getUuid() + ", new network offering id: " + newOff.getUuid()); + description += ". Original Network Offering id: " + oldOff.getUuid() + ", new Network Offering id: " + newOff.getUuid(); } } - return eventMsg.toString(); + return description; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java index edef1f846ed7..2973fea33c6a 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java @@ -120,7 +120,7 @@ public void execute() { } @Override - public String getEventDescription() { return "Migrating VPC : " + getId() + " to new VPC offering (" + vpcOfferingId + ")"; } + public String getEventDescription() { return "Migrating VPC with ID: " + getResourceUuid(ApiConstants.VPC_ID) + " to new VPC offering with ID: " + getResourceUuid(ApiConstants.VPC_OFF_ID);} @Override public String getEventType() { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedGuestVlanRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedGuestVlanRangeCmd.java index 632ff9c6ac7f..56d042719f68 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedGuestVlanRangeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedGuestVlanRangeCmd.java @@ -72,7 +72,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Releasing a dedicated guest vlan range."; + return "Releasing dedicated guest VLAN range with ID: " + getResourceUuid(ApiConstants.ID); } // /////////////////////////////////////////////////// @@ -81,7 +81,7 @@ public String getEventDescription() { @Override public void execute() { - CallContext.current().setEventDetails("Dedicated guest vlan range Id: " + id); + CallContext.current().setEventDetails("Dedicated guest VLAN range ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _networkService.releaseDedicatedGuestVlanRange(getId()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedIpv4SubnetForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedIpv4SubnetForZoneCmd.java index 3e151b9b58f4..a5e763c0cb00 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedIpv4SubnetForZoneCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedIpv4SubnetForZoneCmd.java @@ -59,7 +59,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Releasing a dedicated zone IPv4 subnet " + getId(); + return "Releasing dedicated zone IPv4 subnet with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateIpv4SubnetForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateIpv4SubnetForZoneCmd.java index da7a23f50d9c..db5daa505bee 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateIpv4SubnetForZoneCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateIpv4SubnetForZoneCmd.java @@ -69,7 +69,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Updating zone IPv4 subnet " + getId(); + return "Updating zone IPv4 subnet with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkServiceProviderCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkServiceProviderCmd.java index db57abad2489..e0ce0aade1ee 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkServiceProviderCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkServiceProviderCmd.java @@ -100,7 +100,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Updating physical network ServiceProvider: " + getId(); + return "Updating Physical Network ServiceProvider with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java index a9ad46fdd78f..6a6264e418ce 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java @@ -98,7 +98,7 @@ public void execute() { @Override public String getEventDescription() { - return "Updating Physical network: " + getId(); + return "Updating Physical Network with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePodManagementNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePodManagementNetworkIpRangeCmd.java index 394d42a65a3a..0dfa83a68289 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePodManagementNetworkIpRangeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePodManagementNetworkIpRangeCmd.java @@ -113,7 +113,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Updating pod management IP range " + getNewStartIP() + "-" + getNewEndIP() + " of Pod: " + getPodId(); + return "Updating pod management IP range " + getNewStartIP() + "-" + getNewEndIP() + " of Pod: " + getResourceUuid(ApiConstants.POD_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateStorageNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateStorageNetworkIpRangeCmd.java index a1f4d2ed1002..978e94a783a9 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateStorageNetworkIpRangeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateStorageNetworkIpRangeCmd.java @@ -93,7 +93,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Update storage ip range " + getId() + " [StartIp=" + getStartIp() + ", EndIp=" + getEndIp() + ", vlan=" + getVlan() + ", netmask=" + getNetmask() + ']'; + return "Updating storage IP range " + getResourceUuid(ApiConstants.ID) + " [StartIp=" + getStartIp() + ", EndIp=" + getEndIp() + ", VLAN=" + getVlan() + ", netmask=" + getNetmask() + ']'; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForNetworkCmd.java index 1d6bffca342e..3c58cbb3c532 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForNetworkCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForNetworkCmd.java @@ -80,7 +80,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Changing Bgp Peers for network " + getNetworkId(); + return "Changing BGP Peers for Network with ID: " + getResourceUuid(ApiConstants.NETWORK_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForVpcCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForVpcCmd.java index 0c89f3f1d43c..8784f0672790 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForVpcCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForVpcCmd.java @@ -80,7 +80,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Changing Bgp Peers for VPC " + getVpcId(); + return "Changing BGP Peers for VPC with ID: " + getResourceUuid(ApiConstants.VPC_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmd.java index 80642124938a..f1d9b6723091 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmd.java @@ -145,7 +145,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Creating Bgp Peer " + getAsNumber() + " for zone=" + getZoneId(); + return "Creating BGP Peer " + getAsNumber() + " for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DedicateBgpPeerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DedicateBgpPeerCmd.java index ec3d0ea11629..f1ef963e9872 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DedicateBgpPeerCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DedicateBgpPeerCmd.java @@ -82,7 +82,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Dedicating Bgp Peer " + getId(); + return "Dedicating BGP Peer with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DeleteBgpPeerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DeleteBgpPeerCmd.java index a01711efa44f..a412e91bc48e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DeleteBgpPeerCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/DeleteBgpPeerCmd.java @@ -59,7 +59,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting Bgp Peer " + getId(); + return "Deleting BGP Peer with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ReleaseDedicatedBgpPeerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ReleaseDedicatedBgpPeerCmd.java index 92610c233ef0..c754d443c051 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ReleaseDedicatedBgpPeerCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/ReleaseDedicatedBgpPeerCmd.java @@ -59,7 +59,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Releasing a dedicated Bgp Peer " + getId(); + return "Releasing dedicated BGP Peer with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmd.java index ae44330ea033..f45c1ee5a2f3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmd.java @@ -120,7 +120,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Updating Bgp Peer " + getId(); + return "Updating BGP Peer with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ChangeOutOfBandManagementPasswordCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ChangeOutOfBandManagementPasswordCmd.java index b22697768681..b9a729bc1b77 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ChangeOutOfBandManagementPasswordCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ChangeOutOfBandManagementPasswordCmd.java @@ -70,7 +70,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to find host by ID: " + getHostId()); } - CallContext.current().setEventDetails("Host Id: " + host.getId() + " Password: " + getPassword().charAt(0) + "****"); + CallContext.current().setEventDetails("Host ID: " + host.getUuid() + " Password: " + getPassword().charAt(0) + "****"); CallContext.current().putContextParameter(Host.class, host.getUuid()); final OutOfBandManagementResponse response = outOfBandManagementService.changePassword(host, getPassword()); @@ -101,7 +101,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "change out-of-band management password for host: " + getHostId(); + return "Changing out-of-band management password for host with ID: " + getResourceUuid(ApiConstants.HOST_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForClusterCmd.java index 26b0eac6be4a..5b0f3a802071 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForClusterCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForClusterCmd.java @@ -70,7 +70,7 @@ final public void execute() throws ResourceUnavailableException, InsufficientCap OutOfBandManagementResponse response = outOfBandManagementService.disableOutOfBandManagement(cluster); - CallContext.current().setEventDetails("Cluster Id:" + cluster.getId() + " out-of-band management enabled: false"); + CallContext.current().setEventDetails("Cluster ID:" + cluster.getUuid() + " out-of-band management enabled: false"); CallContext.current().putContextParameter(Cluster.class, cluster.getUuid()); response.setResponseName(getCommandName()); @@ -93,7 +93,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "disable out-of-band management password for cluster: " + getClusterId(); + return "Disabling out-of-band management password for cluster with ID: " + getResourceUuid(ApiConstants.CLUSTER_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForHostCmd.java index 6c9b48ef28f7..c70622134531 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForHostCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForHostCmd.java @@ -70,7 +70,7 @@ final public void execute() throws ResourceUnavailableException, InsufficientCap OutOfBandManagementResponse response = outOfBandManagementService.disableOutOfBandManagement(host); - CallContext.current().setEventDetails("Host Id:" + host.getId() + " out-of-band management enabled: false"); + CallContext.current().setEventDetails("Host ID:" + host.getUuid() + " out-of-band management enabled: false"); CallContext.current().putContextParameter(Host.class, host.getUuid()); response.setId(host.getUuid()); @@ -94,7 +94,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "disable out-of-band management password for host: " + getHostId(); + return "Disabling out-of-band management password for host with ID: " + getResourceUuid(ApiConstants.HOST_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForZoneCmd.java index 4f262ca5c09f..2f2750580516 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForZoneCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForZoneCmd.java @@ -70,7 +70,7 @@ final public void execute() throws ResourceUnavailableException, InsufficientCap OutOfBandManagementResponse response = outOfBandManagementService.disableOutOfBandManagement(zone); - CallContext.current().setEventDetails("Zone Id:" + zone.getId() + " out-of-band management enabled: false"); + CallContext.current().setEventDetails("Zone ID:" + zone.getUuid() + " out-of-band management enabled: false"); CallContext.current().putContextParameter(DataCenter.class, zone.getUuid()); response.setResponseName(getCommandName()); @@ -93,7 +93,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "disable out-of-band management password for zone: " + getZoneId(); + return "Disabling out-of-band management password for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForClusterCmd.java index 6620f86907e9..4419ed18ee59 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForClusterCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForClusterCmd.java @@ -70,7 +70,7 @@ final public void execute() throws ResourceUnavailableException, InsufficientCap OutOfBandManagementResponse response = outOfBandManagementService.enableOutOfBandManagement(cluster); - CallContext.current().setEventDetails("Cluster Id:" + cluster.getId() + " out-of-band management enabled: true"); + CallContext.current().setEventDetails("Cluster ID:" + cluster.getUuid() + " out-of-band management enabled: true"); CallContext.current().putContextParameter(Cluster.class, cluster.getUuid()); response.setResponseName(getCommandName()); @@ -93,7 +93,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "enable out-of-band management password for cluster: " + getClusterId(); + return "Enabling out-of-band management password for cluster with ID: " + getResourceUuid(ApiConstants.CLUSTER_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForHostCmd.java index 3cfee31f78a8..b3f2e8aaf821 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForHostCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForHostCmd.java @@ -70,7 +70,7 @@ final public void execute() throws ResourceUnavailableException, InsufficientCap OutOfBandManagementResponse response = outOfBandManagementService.enableOutOfBandManagement(host); - CallContext.current().setEventDetails("Host Id:" + host.getId() + " out-of-band management enabled: true"); + CallContext.current().setEventDetails("Host ID:" + host.getUuid() + " out-of-band management enabled: true"); CallContext.current().putContextParameter(Host.class, host.getUuid()); response.setId(host.getUuid()); @@ -94,7 +94,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "enable out-of-band management password for host: " + getHostId(); + return "Enabling out-of-band management password for host with ID: " + getResourceUuid(ApiConstants.HOST_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForZoneCmd.java index 99d2324b1b66..8f6eb2dc3500 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForZoneCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForZoneCmd.java @@ -70,7 +70,7 @@ final public void execute() throws ResourceUnavailableException, InsufficientCap OutOfBandManagementResponse response = outOfBandManagementService.enableOutOfBandManagement(zone); - CallContext.current().setEventDetails("Zone Id:" + zone.getId() + " out-of-band management enabled: true"); + CallContext.current().setEventDetails("Zone ID:" + zone.getUuid() + " out-of-band management enabled: true"); CallContext.current().putContextParameter(DataCenter.class, zone.getUuid()); response.setResponseName(getCommandName()); @@ -93,7 +93,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "enable out-of-band management password for zone: " + getZoneId(); + return "Enabling out-of-band management password for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/IssueOutOfBandManagementPowerActionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/IssueOutOfBandManagementPowerActionCmd.java index c63b03aad1b8..bba3fee6ceca 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/IssueOutOfBandManagementPowerActionCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/IssueOutOfBandManagementPowerActionCmd.java @@ -75,7 +75,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE } final PowerOperation powerOperation = PowerOperation.valueOf(getPowerAction()); - CallContext.current().setEventDetails("Host Id: " + host.getId() + " Action: " + powerOperation.toString()); + CallContext.current().setEventDetails("Host ID: " + host.getUuid() + " Action: " + powerOperation.toString()); CallContext.current().putContextParameter(Host.class, host.getUuid()); final OutOfBandManagementResponse response = outOfBandManagementService.executePowerOperation(host, powerOperation, getActionTimeout()); @@ -107,7 +107,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "issue out-out-band management power action: " + getPowerAction() + " on host: " + getHostId(); + return "Issuing out-out-band management power action: " + getPowerAction() + " to host: " + getResourceUuid(ApiConstants.HOST_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/region/DeletePortableIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/DeletePortableIpRangeCmd.java index da7293ea2198..ac8fe66a8144 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/region/DeletePortableIpRangeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/DeletePortableIpRangeCmd.java @@ -83,7 +83,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "deleting a portable public ip range"; + return "Deleting a portable public ip range with ID: " + getResourceUuid(ApiConstants.ID) ; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/UploadCustomCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/UploadCustomCertificateCmd.java index c5ae6890c3e5..7144bbaa6015 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/UploadCustomCertificateCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/UploadCustomCertificateCmd.java @@ -84,7 +84,7 @@ public String getEventType() { @Override public String getEventDescription() { - return ("Uploading custom certificate to the db, and applying it to all the cpvms in the system"); + return ("Uploading custom certificate and applying it to all the CPVMs in the system"); } public static String getResultObjectName() { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ConfigureOvsElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ConfigureOvsElementCmd.java index e40462149582..474e13de32f3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ConfigureOvsElementCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ConfigureOvsElementCmd.java @@ -93,7 +93,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "configuring ovs provider: " + id; + return "Configuring OVS provider with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -109,7 +109,7 @@ public Long getApiResourceId() { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { - CallContext.current().setEventDetails("Ovs element: " + id); + CallContext.current().setEventDetails("OVS element: " + getResourceUuid(ApiConstants.ID)); OvsProvider result = _service.get(0).configure(this); if (result != null) { OvsProviderResponse ovsResponse = _responseGenerator diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ConfigureVirtualRouterElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ConfigureVirtualRouterElementCmd.java index 7be41834cd5a..ba0110f014a0 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ConfigureVirtualRouterElementCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ConfigureVirtualRouterElementCmd.java @@ -100,7 +100,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "configuring virtual router provider: " + id; + return "Configuring virtual router with provider that has ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -115,7 +115,7 @@ public Long getApiResourceId() { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { - CallContext.current().setEventDetails("Virtual router element: " + id); + CallContext.current().setEventDetails("Virtual router element ID: " + getResourceUuid(ApiConstants.ID)); VirtualRouterProvider result = _service.get(0).configure(this); if (result != null) { VirtualRouterProviderResponse routerResponse = _responseGenerator.createVirtualRouterProviderResponse(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java index 7c17fd794da6..094e87ae0058 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java @@ -98,7 +98,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Virtual router element Id: " + getEntityUuid()); + CallContext.current().setEventDetails("Virtual router element ID: " + getEntityUuid()); VirtualRouterProvider result = _service.get(0).getCreatedElement(getEntityId()); if (result != null) { VirtualRouterProviderResponse response = _responseGenerator.createVirtualRouterProviderResponse(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java index 66fc2eb79e6d..d8355cadb0a0 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java @@ -74,7 +74,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "destroying router: " + this._uuidMgr.getUuid(VirtualMachine.class,getId()); + return "Destroying virtual router with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -90,7 +90,7 @@ public Long getApiResourceId() { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException { CallContext ctx = CallContext.current(); - ctx.setEventDetails("Router Id: " + this._uuidMgr.getUuid(VirtualMachine.class,getId())); + ctx.setEventDetails("Router ID: " + getResourceUuid(ApiConstants.ID)); VirtualRouter result = _routerService.destroyRouter(getId(), ctx.getCallingAccount(), ctx.getCallingUserId()); if (result != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/GetRouterHealthCheckResultsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/GetRouterHealthCheckResultsCmd.java index 6d4d62929ded..a302ebee1046 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/GetRouterHealthCheckResultsCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/GetRouterHealthCheckResultsCmd.java @@ -87,7 +87,7 @@ public long getEntityOwnerId() { @Override public void execute() throws ResourceUnavailableException, InvalidParameterValueException, ServerApiException { - CallContext.current().setEventDetails("Router Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getRouterId())); + CallContext.current().setEventDetails("Router ID: " + getResourceUuid(ApiConstants.ROUTER_ID)); VirtualRouter router = _routerService.findRouter(getRouterId()); if (router == null || router.getRole() != VirtualRouter.Role.VIRTUAL_ROUTER) { throw new InvalidParameterValueException("Can't find router by routerId"); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java index 36ffdcb42d00..d90208e36d34 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java @@ -78,7 +78,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "rebooting router: " + this._uuidMgr.getUuid(VirtualMachine.class,getId()); + return "Rebooting router with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -97,7 +97,7 @@ public boolean isForced() { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { - CallContext.current().setEventDetails("Router Id: " + this._uuidMgr.getUuid(VirtualMachine.class,getId())); + CallContext.current().setEventDetails("Router ID: " + getResourceUuid(ApiConstants.ID)); VirtualRouter result = _routerService.rebootRouter(getId(), true, isForced()); if (result != null) { DomainRouterResponse response = _responseGenerator.createDomainRouterResponse(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java index 65849be0d685..263f53ca2e48 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java @@ -81,7 +81,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "starting router: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); + return "Starting virtual router with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -96,7 +96,7 @@ public Long getApiResourceId() { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { - CallContext.current().setEventDetails("Router Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("Router Id: " + getResourceUuid(ApiConstants.ID)); VirtualRouter result = null; VirtualRouter router = _routerService.findRouter(getId()); if (router == null || router.getRole() != Role.VIRTUAL_ROUTER) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java index 775ffcb4d38e..838762740281 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java @@ -79,7 +79,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Stopping router: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); + return "Stopping virtual router with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -98,7 +98,7 @@ public boolean isForced() { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException { - CallContext.current().setEventDetails("Router Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("Router ID: " + getResourceUuid(ApiConstants.ID)); VirtualRouter result = null; VirtualRouter router = _routerService.findRouter(getId()); if (router == null || router.getRole() != Role.VIRTUAL_ROUTER) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/UpgradeRouterTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/UpgradeRouterTemplateCmd.java index 1bbc3a141dbc..6fdfa7d3642d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/UpgradeRouterTemplateCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/UpgradeRouterTemplateCmd.java @@ -119,7 +119,7 @@ public Long getInstanceId() { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { - CallContext.current().setEventDetails("Upgrading router Template"); + CallContext.current().setEventDetails("Upgrading router with with ID: " + getResourceUuid(ApiConstants.ID) + " template"); List result = _routerService.upgradeRouterTemplate(this); if (result != null) { ListResponse response = _responseGenerator.createUpgradeRouterTemplateResponse(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CancelPrimaryStorageMaintenanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CancelPrimaryStorageMaintenanceCmd.java index 35f7b19f709d..7b69d25caef4 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CancelPrimaryStorageMaintenanceCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CancelPrimaryStorageMaintenanceCmd.java @@ -93,7 +93,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "canceling maintenance for primary storage pool: " + getId(); + return "Canceling maintenance mode for primary storage pool with ID: " + getResourceUuid(ApiConstants.ID); } @Override 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 index d3b6a0746106..3bb16dfea5a4 100644 --- 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 @@ -28,7 +28,6 @@ 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. " + @@ -61,15 +60,7 @@ public String getEventType() { @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; + return "Changing storage pool with ID: " + getResourceUuid(ApiConstants.ID) + " to scope " + scope; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ConfigureStorageAccessCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ConfigureStorageAccessCmd.java index bfa2589921f7..c5459adfd2d0 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ConfigureStorageAccessCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ConfigureStorageAccessCmd.java @@ -130,6 +130,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "configuring storage access groups"; + return "Configuring storage access groups"; } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/DownloadImageStoreObjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/DownloadImageStoreObjectCmd.java index 92019e70eca2..1d927ac5cbd6 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/DownloadImageStoreObjectCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/DownloadImageStoreObjectCmd.java @@ -94,6 +94,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Downloading object at path " + getPath() + " on image store " + getStoreId(); + return "Downloading object at path " + getPath() + " on image store " + getResourceUuid(ApiConstants.ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/PreparePrimaryStorageForMaintenanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/PreparePrimaryStorageForMaintenanceCmd.java index 818b3a5bbeab..9f0efe7f7a1b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/PreparePrimaryStorageForMaintenanceCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/PreparePrimaryStorageForMaintenanceCmd.java @@ -93,7 +93,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "preparing storage pool: " + getId() + " for maintenance"; + return "Preparing storage pool with ID: " + getResourceUuid(ApiConstants.ID) + " for maintenance"; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/SyncStoragePoolCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/SyncStoragePoolCmd.java index 9f81f2f6c86c..684243c08299 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/SyncStoragePoolCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/SyncStoragePoolCmd.java @@ -67,7 +67,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Attempting to synchronise storage pool with management server"; + return "Attempting to synchronise storage pool with ID:" + getResourceUuid(ApiConstants.ID) + " with management server"; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java index 3a7e1caa4dc3..6b776d067784 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java @@ -76,7 +76,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Destroying system Instance: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); + return "Destroying System VM with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -91,14 +91,14 @@ public Long getApiResourceId() { @Override public void execute() { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("System VM ID: " + getResourceUuid(ApiConstants.ID)); VirtualMachine instance = _mgr.destroySystemVM(this); if (instance != null) { SystemVmResponse response = _responseGenerator.createSystemVmResponse(instance); response.setResponseName(getCommandName()); setResponseObject(response); } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to destroy system vm"); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to destroy System VM"); } } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java index 8319883ec442..feeb3f44553d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java @@ -120,7 +120,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Attempting to migrate Instance Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId()) + " to host Id: " + this._uuidMgr.getUuid(Host.class, getHostId()); + return "Attempting to migrate System VM with ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID) + " to host with ID: " + getResourceUuid(ApiConstants.HOST_ID); } @Override @@ -138,7 +138,7 @@ public void execute() { if (destStoragePool == null) { throw new InvalidParameterValueException("Unable to find the storage pool to migrate the Instance"); } - CallContext.current().setEventDetails("VM Id: " + getVirtualMachineId() + " to storage pool Id: " + getStorageId()); + CallContext.current().setEventDetails("System VM ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID) + " to storage pool with ID: " + getResourceUuid(ApiConstants.STORAGE_ID)); migratedVm = _userVmService.vmStorageMigration(getVirtualMachineId(), destStoragePool); } else { Host destinationHost = null; @@ -153,7 +153,7 @@ public void execute() { } else if (! isAutoSelect()) { throw new InvalidParameterValueException("Please specify a host or storage as destination, or pass 'autoselect=true' to automatically select a destination host which do not require storage migration"); } - CallContext.current().setEventDetails("VM Id: " + getVirtualMachineId() + " to host Id: " + getHostId()); + CallContext.current().setEventDetails("System VM ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID) + " to host with ID: " + getResourceUuid(ApiConstants.HOST_ID)); if (destinationHost == null) { migratedVm = _userVmService.migrateVirtualMachine(getVirtualMachineId(), null); } else { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/PatchSystemVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/PatchSystemVMCmd.java index 6a4361061dfa..13f6167513b0 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/PatchSystemVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/PatchSystemVMCmd.java @@ -19,7 +19,6 @@ import com.cloud.event.EventTypes; import com.cloud.user.Account; import com.cloud.utils.Pair; -import com.cloud.vm.VirtualMachine; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -72,7 +71,7 @@ public String getEventType() { @Override public String getEventDescription() { - return String.format("Attempting to live patch System VM with Id: %s ", this._uuidMgr.getUuid(VirtualMachine.class, getId())); + return String.format("Attempting to live patch System VM with ID: %s ", getResourceUuid(ApiConstants.ID)); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java index 81affc714525..0a0ffe847adc 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java @@ -86,7 +86,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "rebooting system vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); + return "Rebooting System VM with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -105,14 +105,14 @@ public boolean isForced() { @Override public void execute() { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); VirtualMachine result = _mgr.rebootSystemVM(this); if (result != null) { SystemVmResponse response = _responseGenerator.createSystemVmResponse(result); response.setResponseName(getCommandName()); setResponseObject(response); } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to reboot system vm"); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to reboot System Instance"); } } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java index eaf927ae0f72..061a2ad2deed 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java @@ -98,7 +98,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("SystemVm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("System VM ID: " + getResourceUuid(ApiConstants.ID)); ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId); if (serviceOffering == null) { @@ -137,6 +137,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Upgrading system vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()) + " to service offering: " + this._uuidMgr.getUuid(ServiceOffering.class, getServiceOfferingId()); + return "Upgrading System VM with ID: " + getResourceUuid(ApiConstants.ID) + " to service offering: " + getResourceUuid(ApiConstants.SERVICE_OFFERING_ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java index bfb6a240a62d..734b553c2dd5 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java @@ -87,7 +87,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "starting system vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); + return "Starting System VM with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -102,7 +102,7 @@ public Long getApiResourceId() { @Override public void execute() { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); VirtualMachine instance = _mgr.startSystemVM(getId()); if (instance != null) { SystemVmResponse response = _responseGenerator.createSystemVmResponse(instance); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java index e86b6a281215..bdcb5b407b39 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java @@ -89,7 +89,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Stopping system vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); + return "Stopping System VM with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -108,7 +108,7 @@ public boolean isForced() { @Override public void execute() throws ResourceUnavailableException, ConcurrentOperationException { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); VirtualMachine result = _mgr.stopSystemVM(this); if (result != null) { SystemVmResponse response = _responseGenerator.createSystemVmResponse(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java index 4567c25a0d1a..a27c04374c32 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java @@ -87,7 +87,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId); if (serviceOffering == null) { @@ -100,7 +100,7 @@ public void execute() { response.setResponseName(getCommandName()); setResponseObject(response); } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to reboot system vm"); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to reboot System VM"); } } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java index 2ba3b321887d..50abd953e63f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java @@ -148,7 +148,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("TrafficType Id: " + getEntityId()); + CallContext.current().setEventDetails("Traffic type ID: " + getEntityUuid()); PhysicalNetworkTrafficType result = _networkService.getPhysicalNetworkTrafficType(getEntityId()); if (result != null) { TrafficTypeResponse response = _responseGenerator.createTrafficTypeResponse(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/DeleteTrafficTypeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/DeleteTrafficTypeCmd.java index d8813eefa6af..3f07020e5fa2 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/DeleteTrafficTypeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/DeleteTrafficTypeCmd.java @@ -71,7 +71,7 @@ public void execute() { @Override public String getEventDescription() { - return "Deleting Traffic Type: " + getId(); + return "Deleting Traffic Type with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/UpdateTrafficTypeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/UpdateTrafficTypeCmd.java index 0de4cfb7edda..29b06a3b5259 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/UpdateTrafficTypeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/UpdateTrafficTypeCmd.java @@ -118,7 +118,7 @@ public void execute() { @Override public String getEventDescription() { - return "Updating Traffic Type: " + getId(); + return "Updating Traffic Type with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java index f954ac939c3c..01886187f9b9 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java @@ -82,7 +82,7 @@ public ApiCommandResourceType getApiResourceType() { @Override public void execute() { - CallContext.current().setEventDetails("UserId: " + getId()); + CallContext.current().setEventDetails("User ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _regionService.deleteUser(this); if (!result) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete user"); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java index 6ce669d8523d..cc2bc0906a24 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java @@ -78,12 +78,12 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - return "disabling user: " + this._uuidMgr.getUuid(User.class, getId()); + return "Disabling User with ID: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { - CallContext.current().setEventDetails("User ID: " + this._uuidMgr.getUuid(User.class, getId())); + CallContext.current().setEventDetails("User ID: " + getResourceUuid(ApiConstants.ID)); UserAccount user = _regionService.disableUser(this); if (user != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java index 77d8d530daf2..9141a9bccf8a 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java @@ -71,7 +71,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("UserId: " + getId()); + CallContext.current().setEventDetails("User ID: " + getResourceUuid(ApiConstants.ID)); UserAccount user = _regionService.enableUser(this); if (user != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/MoveUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/MoveUserCmd.java index a160486c51c4..aab20f108f9e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/MoveUserCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/MoveUserCmd.java @@ -116,7 +116,7 @@ public void execute() { Preconditions.checkNotNull(getId(),"I have to have an user to move!"); Preconditions.checkState(ObjectUtils.anyNotNull(getAccountId(),getAccountName()),"provide either an account name or an account id!"); - CallContext.current().setEventDetails("UserId: " + getId()); + CallContext.current().setEventDetails("User ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _regionService.moveUser(this); if (result) { 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 cc0b2e4954ce..b61550c70875 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 @@ -156,7 +156,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("UserId: " + getId()); + CallContext.current().setEventDetails("User ID: " + getResourceUuid(ApiConstants.ID)); UserAccount user = _regionService.updateUser(this); if (user != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java index 74ebab59de48..2d9c5f93383c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java @@ -81,7 +81,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Expunging Instance: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); + return "Expunging Instance with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -96,7 +96,7 @@ public Long getApiResourceId() { @Override public void execute() throws ResourceUnavailableException, ConcurrentOperationException { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); try { UserVm result = _userVmService.expungeVm(this.getId()); 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 ad7e8a48b252..3284dbafe7ca 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 @@ -271,8 +271,7 @@ public String getEventType() { @Override public String getEventDescription() { - String vmName = this.name; - return String.format("Importing unmanaged Instance: %s", vmName); + return "Importing unmanaged Instance: " + name; } public boolean isForced() { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java index f6335307a382..467b92d415d2 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java @@ -124,15 +124,15 @@ public String getEventType() { @Override public String getEventDescription() { - String eventDescription; + String description = "Attempting to migrate Instance with ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID); + if (getHostId() != null) { - eventDescription = String.format("Attempting to migrate Instance id: %s to host Id: %s", getVirtualMachineId(), getHostId()); + description += " to host with ID: " +getResourceUuid(ApiConstants.HOST_ID); } else if (getStoragePoolId() != null) { - eventDescription = String.format("Attempting to migrate Instance id: %s to storage pool Id: %s", getVirtualMachineId(), getStoragePoolId()); - } else { - eventDescription = String.format("Attempting to migrate Instance id: %s", getVirtualMachineId()); + description = " to storage pool with ID: " + getResourceUuid(ApiConstants.STORAGE_ID); } - return eventDescription; + + return description; } @Override @@ -158,7 +158,7 @@ public void execute() { if (destStoragePool == null) { throw new InvalidParameterValueException("Unable to find the storage pool to migrate the Instance"); } - CallContext.current().setEventDetails("VM Id: " + getVirtualMachineId() + " to storage pool Id: " + getStoragePoolId()); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID) + " to storage pool with ID: " + getResourceUuid(ApiConstants.STORAGE_ID)); } else if (getHostId() != null) { destinationHost = _resourceService.getHost(getHostId()); if (destinationHost == null) { @@ -167,7 +167,7 @@ public void execute() { if (destinationHost.getType() != Host.Type.Routing) { throw new InvalidParameterValueException("The specified host(" + destinationHost.getName() + ") is not suitable to migrate the Instance, please specify another one"); } - CallContext.current().setEventDetails("Instance Id: " + getVirtualMachineId() + " to host Id: " + getHostId()); + CallContext.current().setEventDetails("Instance Id: " + getVirtualMachineId() + " to host with ID: " + getResourceUuid(ApiConstants.HOST_ID)); } else if (! isAutoSelect()) { throw new InvalidParameterValueException("Please specify a host or storage as destination, or pass 'autoselect=true' to automatically select a destination host which do not require storage migration"); } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java index 0142f6fc81ab..ad298513ac0b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java @@ -135,7 +135,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Attempting to migrate Instance Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId()) + " to host Id: " + this._uuidMgr.getUuid(Host.class, getHostId()); + return "Attempting to migrate Instance with ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID) + " to host with ID: " + getResourceUuid(ApiConstants.HOST_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/UnmanageVMInstanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/UnmanageVMInstanceCmd.java index b1d17cf02f62..2c9f09dcd626 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/UnmanageVMInstanceCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/UnmanageVMInstanceCmd.java @@ -97,7 +97,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Unmanaging Instance. Instance ID = " + vmId; + return "Unmanaging Instance with ID: " + getResourceUuid(ApiConstants.ID); } public Long getHostId() { @@ -121,7 +121,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { UnmanageVMInstanceResponse response = new UnmanageVMInstanceResponse(); try { - CallContext.current().setEventDetails("VM ID = " + vmId); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); Pair result = unmanagedVMsManager.unmanageVMInstance(vmId, hostId, isForced()); if (result.first()) { response.setSuccess(true); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/RecoverVolumeCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/RecoverVolumeCmdByAdmin.java index e276c8a00b65..b7c084ee6e78 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/RecoverVolumeCmdByAdmin.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/RecoverVolumeCmdByAdmin.java @@ -19,6 +19,7 @@ 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.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; @@ -38,7 +39,7 @@ public class RecoverVolumeCmdByAdmin extends RecoverVolumeCmd implements AdminCm @Override public void execute() { - CallContext.current().setEventDetails("Volume Id: " + getId()); + CallContext.current().setEventDetails("Volume ID: " + getResourceUuid(ApiConstants.ID)); Volume result = _volumeService.recoverVolume(getId()); if (result != null) { VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/UnmanageVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/UnmanageVolumeCmd.java index dcc8b2af8d74..ac573dd4ecb9 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/UnmanageVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/UnmanageVolumeCmd.java @@ -81,7 +81,7 @@ public String getEventType() { @Override public String getEventDescription() { - return String.format("Unmanaging Volume with ID %s", volumeId); + return "Unmanaging Volume with ID: " + getResourceUuid(ApiConstants.ID); } ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/DeletePrivateGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/DeletePrivateGatewayCmd.java index cd88d81da675..a6b0538062b1 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/DeletePrivateGatewayCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/DeletePrivateGatewayCmd.java @@ -66,7 +66,7 @@ public String getEventType() { @Override public String getEventDescription() { - return ("Deleting private gateway id=" + id); + return "Deleting private gateway with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -76,7 +76,7 @@ public long getEntityOwnerId() { @Override public void execute() throws ResourceUnavailableException, ConcurrentOperationException { - CallContext.current().setEventDetails("Network ACL Id: " + id); + CallContext.current().setEventDetails("Network ACL ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _vpcService.deleteVpcPrivateGateway(id); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/DeleteVPCOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/DeleteVPCOfferingCmd.java index b322a6d55890..f579eeb87e4d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/DeleteVPCOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/DeleteVPCOfferingCmd.java @@ -76,7 +76,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting VPC offering id=" + getId(); + return "Deleting VPC offering with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java index d4565cbada26..97f30f6fa2ef 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java @@ -127,7 +127,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Updating VPC offering id=" + getId(); + return "Updating VPC offering with ID:" + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/DeleteZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/DeleteZoneCmd.java index 565baab6e4c6..28d14a318753 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/DeleteZoneCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/DeleteZoneCmd.java @@ -60,7 +60,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Zone Id: " + getId()); + CallContext.current().setEventDetails("Zone ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _configService.deleteZone(this); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/MarkDefaultZoneForAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/MarkDefaultZoneForAccountCmd.java index 5d3f5dcd47fa..42040290a411 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/MarkDefaultZoneForAccountCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/MarkDefaultZoneForAccountCmd.java @@ -95,7 +95,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Marking account with the default zone: " + getDefaultZoneId(); + return "Marking zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID) + " as default for account " + getResourceUuid(ApiConstants.ACCOUNT) + " in domain: " + getResourceUuid(ApiConstants.DOMAIN_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java index 3e7fffb5fafc..888ee6603ddf 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java @@ -178,7 +178,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Zone Id: " + getId()); + CallContext.current().setEventDetails("Zone ID: " + getResourceUuid(ApiConstants.ID)); DataCenter result = _configService.editZone(this); if (result != null) { ZoneResponse response = _responseGenerator.createZoneResponse(ResponseView.Full, result, false, false); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/account/AddAccountToProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/account/AddAccountToProjectCmd.java index 93021487040b..85e7b0af3193 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/account/AddAccountToProjectCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/account/AddAccountToProjectCmd.java @@ -111,7 +111,7 @@ public void execute() { throw new InvalidParameterValueException("Either accountName or email is required"); } - CallContext.current().setEventDetails("Project ID: " + projectId + "; accountName " + accountName); + CallContext.current().setEventDetails("Project ID: " + getResourceUuid(ApiConstants.PROJECT_ID) + "; accountName " + accountName); boolean result = _projectService.addAccountToProject(getProjectId(), getAccountName(), getEmail(), getProjectRoleId(), getRoleType()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); @@ -146,10 +146,12 @@ public String getEventType() { @Override public String getEventDescription() { + String projectUuid = getResourceUuid(ApiConstants.PROJECT_ID); + if (accountName != null) { - return "Adding Account " + getAccountName() + " to project: " + getProjectId(); + return "Adding account " + getAccountName() + " to project: " + projectUuid; } else { - return "Sending invitation to email " + email + " to join project: " + getProjectId(); + return "Sending invitation to email " + email + " to join project: " + projectUuid; } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/account/AddUserToProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/account/AddUserToProjectCmd.java index 9bdc85bc5c71..69832d4dfdc9 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/account/AddUserToProjectCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/account/AddUserToProjectCmd.java @@ -103,7 +103,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Adding User " + getUsername() + " to Project: " + getProjectId(); + return "Adding User " + getUsername() + " to Project: " + getResourceUuid(ApiConstants.PROJECT_ID); } ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteAccountFromProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteAccountFromProjectCmd.java index 510f97ff7437..74e6f2c804c7 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteAccountFromProjectCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteAccountFromProjectCmd.java @@ -70,7 +70,7 @@ public String getAccountName() { @Override public void execute() { - CallContext.current().setEventDetails("Project ID: " + projectId + "; accountName " + accountName); + CallContext.current().setEventDetails("Project ID: " + getResourceUuid(ApiConstants.PROJECT_ID) + "; accountName " + accountName); boolean result = _projectService.deleteAccountFromProject(projectId, accountName); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); @@ -103,7 +103,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Removing Account " + accountName + " from project: " + projectId; + return "Removing Account " + accountName + " from project: " + getResourceUuid(ApiConstants.PROJECT_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteUserFromProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteUserFromProjectCmd.java index 5db604fe05c3..2677b206bdc1 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteUserFromProjectCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteUserFromProjectCmd.java @@ -78,7 +78,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Removing User " + userId + " from project: " + projectId; + return "Removing User " + getResourceUuid(ApiConstants.USER_ID) + " from project: " + getResourceUuid(ApiConstants.PROJECT_ID); } @Override @@ -107,7 +107,7 @@ public ApiCommandResourceType getApiResourceType() { @Override public void execute() { - CallContext.current().setEventDetails("Project ID: " + projectId + "; User ID: " + userId); + CallContext.current().setEventDetails("Project ID: " + getResourceUuid(ApiConstants.PROJECT_ID) + "; User ID: " + getResourceUuid(ApiConstants.USER_ID)); boolean result = _projectService.deleteUserFromProject(getProjectId(), getUserId()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java index c18d08299c3a..a62f9f316606 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java @@ -334,7 +334,7 @@ public void create() throws ResourceAllocationException { @Override public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { - CallContext.current().setEventDetails("IP ID: " + getEntityId()); + CallContext.current().setEventDetails("IP address ID: " + getEntityUuid()); IpAddress result = null; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/address/DisassociateIPAddrCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/address/DisassociateIPAddrCmd.java index 531f9bb86495..835a2a69e3c9 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/address/DisassociateIPAddrCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/address/DisassociateIPAddrCmd.java @@ -82,7 +82,7 @@ public Long getIpAddressId() { @Override public void execute() throws InsufficientAddressCapacityException { Long ipAddressId = getIpAddressId(); - CallContext.current().setEventDetails("IP ID: " + ipAddressId); + CallContext.current().setEventDetails("IP address ID: " + getResourceUuid(ApiConstants.ID)); boolean result = false; if (!isPortable()) { result = _networkService.releaseIpAddress(ipAddressId); @@ -108,7 +108,7 @@ public String getEventType() { @Override public String getEventDescription() { - return ("Disassociating IP address with ID=" + id); + return ("Disassociating IP address with ID:" + getResourceUuid(ApiConstants.ID)); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/address/ReleaseIPAddrCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/address/ReleaseIPAddrCmd.java index 0d2ff89930d5..2fe94b29346d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/address/ReleaseIPAddrCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/address/ReleaseIPAddrCmd.java @@ -73,7 +73,7 @@ public long getEntityOwnerId() { @Override public void execute() throws InsufficientAddressCapacityException { - CallContext.current().setEventDetails("IP ID: " + getIpAddressId()); + CallContext.current().setEventDetails("IP address ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _networkService.releaseReservedIpAddress(getIpAddressId()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java index 6eb75c7c1838..4eace28f5555 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java @@ -123,7 +123,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting Affinity Group"; + return "Deleting Affinity Group with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java index e522747780f2..7a7e3ee298a9 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java @@ -141,7 +141,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE throw new InvalidParameterValueException("affinitygroupids parameter or affinitygroupnames parameter must be given"); } - CallContext.current().setEventDetails("VM ID: " + getId()); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); UserVm result = _affinityGroupService.updateVMAffinityGroups(getId(), getAffinityGroupIdList()); ArrayList dc = new ArrayList(); dc.add(VMDetails.valueOf("affgrp")); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScalePolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScalePolicyCmd.java index e160a1a90103..f4bfcf4f135d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScalePolicyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScalePolicyCmd.java @@ -160,7 +160,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "creating AutoScale Policy"; + return "Creating AutoScale Policy"; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmGroupCmd.java index 66a1a56fbe2c..7c04a4c9d53b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmGroupCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmGroupCmd.java @@ -185,7 +185,7 @@ public String getCreateEventDescription() { @Override public String getEventDescription() { - return "Configuring AutoScale Instance Group. Instance Group Id: " + getEntityId(); + return "Configuring AutoScale Instance Group with ID: " + getEntityId(); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java index 2bb101de5593..61745ccda7d1 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java @@ -127,7 +127,7 @@ public ApiCommandResourceType getApiResourceType() { @Override public String getEventDescription() { - return "creating a condition"; + return "Creating AutoScale condition"; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScalePolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScalePolicyCmd.java index fac7ffe37d30..45315cc744ca 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScalePolicyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScalePolicyCmd.java @@ -79,12 +79,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "deleting AutoScale Policy: " + getId(); + return "Deleting AutoScale Policy with ID: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { - CallContext.current().setEventDetails("AutoScale Policy Id: " + getId()); + CallContext.current().setEventDetails("AutoScale Policy ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _autoScaleService.deleteAutoScalePolicy(id); if (result) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmGroupCmd.java index c2dd6d5424d9..99d6d903ba45 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmGroupCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmGroupCmd.java @@ -89,12 +89,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting autoscale Instance group: " + getId(); + return "Deleting AutoScale Instance group with ID: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { - CallContext.current().setEventDetails("AutoScale Instance Group Id: " + getId()); + CallContext.current().setEventDetails("AutoScale Instance Group ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _autoScaleService.deleteAutoScaleVmGroup(id, getCleanup()); if (result) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmProfileCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmProfileCmd.java index 9e2f63deda2e..bf1e8ecb1677 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmProfileCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmProfileCmd.java @@ -79,12 +79,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting autoscale Instance profile: " + getId(); + return "Deleting AutoScale Instance profile with ID: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { - CallContext.current().setEventDetails("AutoScale Instance Profile Id: " + getId()); + CallContext.current().setEventDetails("AutoScale Instance Profile ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _autoScaleService.deleteAutoScaleVmProfile(id); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteConditionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteConditionCmd.java index 2eeed8b49da1..38b77c1553f5 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteConditionCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteConditionCmd.java @@ -100,6 +100,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting a condition."; + return "Deleting AutoScale condition with ID: " + getResourceUuid(ApiConstants.ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DisableAutoScaleVmGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DisableAutoScaleVmGroupCmd.java index 814f35c9f70a..316fefd62deb 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DisableAutoScaleVmGroupCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DisableAutoScaleVmGroupCmd.java @@ -96,7 +96,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Disabling AutoScale Instance Group. Instance Group Id: " + getId(); + return "Disabling AutoScale Instance Group with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/EnableAutoScaleVmGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/EnableAutoScaleVmGroupCmd.java index 962c5af0e2c1..8aea4690425e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/EnableAutoScaleVmGroupCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/EnableAutoScaleVmGroupCmd.java @@ -96,7 +96,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Enabling AutoScale Instance Group. Instance Group Id: " + getId(); + return "Enabling AutoScale Instance Group with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScalePolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScalePolicyCmd.java index 368f9c01fe18..05af6a53a5d3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScalePolicyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScalePolicyCmd.java @@ -77,7 +77,7 @@ public class UpdateAutoScalePolicyCmd extends BaseAsyncCmd { @Override public void execute() { - CallContext.current().setEventDetails("AutoScale Policy Id: " + getId()); + CallContext.current().setEventDetails("AutoScale Policy ID: " + getResourceUuid(ApiConstants.ID)); AutoScalePolicy result = _autoScaleService.updateAutoScalePolicy(this); if (result != null) { AutoScalePolicyResponse response = _responseGenerator.createAutoScalePolicyResponse(result); @@ -130,7 +130,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Updating Auto Scale Policy. Policy Id: " + getId(); + return "Updating AutoScale Policy with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmGroupCmd.java index 128a1368c529..3e13ce10bfb4 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmGroupCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmGroupCmd.java @@ -97,7 +97,7 @@ public class UpdateAutoScaleVmGroupCmd extends BaseAsyncCustomIdCmd { @Override public void execute() { - CallContext.current().setEventDetails("AutoScale Instance Group Id: " + getId()); + CallContext.current().setEventDetails("AutoScale Instance Group ID: " + getResourceUuid(ApiConstants.ID)); AutoScaleVmGroup result = _autoScaleService.updateAutoScaleVmGroup(this); if (result != null) { AutoScaleVmGroupResponse response = _responseGenerator.createAutoScaleVmGroupResponse(result); @@ -151,7 +151,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Updating AutoScale Instance Group. Instance Group Id: " + getId(); + return "Updating AutoScale Instance Group with ID: " + getId(); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java index 5192f0382db6..9495989df189 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java @@ -124,7 +124,7 @@ public class UpdateAutoScaleVmProfileCmd extends BaseAsyncCustomIdCmd { @Override public void execute() { - CallContext.current().setEventDetails("AutoScale Policy Id: " + getId()); + CallContext.current().setEventDetails("AutoScale Policy ID: " + getResourceUuid(ApiConstants.ID)); AutoScaleVmProfile result = _autoScaleService.updateAutoScaleVmProfile(this); if (result != null) { AutoScaleVmProfileResponse response = _responseGenerator.createAutoScaleVmProfileResponse(result); @@ -190,7 +190,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Updating AutoScale Instance Profile. Instance Profile Id: " + getId(); + return "Updating AutoScale Instance Profile with ID: " + getId(); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateConditionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateConditionCmd.java index a386db478438..43de212da7b9 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateConditionCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateConditionCmd.java @@ -110,6 +110,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Updating a condition."; + return "Updating Instance AutoScale condition with ID: " + getResourceUuid(ApiConstants.ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/AssignVirtualMachineToBackupOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/AssignVirtualMachineToBackupOfferingCmd.java index e8914e45c429..28cd642e1a41 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/AssignVirtualMachineToBackupOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/AssignVirtualMachineToBackupOfferingCmd.java @@ -109,6 +109,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Assigning Instance to backup offering ID: " + offeringId; + return "Assigning Instance with ID " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID) + " to backup offering with ID: " + getResourceUuid(ApiConstants.BACKUP_OFFERING_ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/CreateBackupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/CreateBackupCmd.java index df417ef3a60f..ca60ea674fe3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/CreateBackupCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/CreateBackupCmd.java @@ -19,7 +19,6 @@ import javax.inject.Inject; -import com.cloud.vm.VirtualMachine; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandResourceType; @@ -139,8 +138,7 @@ public String getEventType() { @Override public String getEventDescription() { - String vmUuid = _uuidMgr.getUuid(VirtualMachine.class, getVmId()); - return "Creating backup for Instance " + vmUuid; + return "Creating backup for Instance " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/DeleteBackupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/DeleteBackupCmd.java index 8c32dac6c3ac..faaf1735e1e9 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/DeleteBackupCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/DeleteBackupCmd.java @@ -28,7 +28,6 @@ import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.BackupResponse; import org.apache.cloudstack.api.response.SuccessResponse; -import org.apache.cloudstack.backup.Backup; import org.apache.cloudstack.backup.BackupManager; import org.apache.cloudstack.context.CallContext; import org.apache.commons.lang3.BooleanUtils; @@ -112,7 +111,6 @@ public String getEventType() { @Override public String getEventDescription() { - String backupUuid = _uuidMgr.getUuid(Backup.class, getId()); - return "Deleting backup ID " + backupUuid; + return "Deleting Backup with ID: " + getResourceUuid(ApiConstants.ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/RemoveVirtualMachineFromBackupOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/RemoveVirtualMachineFromBackupOfferingCmd.java index 81f11edb7d90..dcf9f15b4dc5 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/RemoveVirtualMachineFromBackupOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/RemoveVirtualMachineFromBackupOfferingCmd.java @@ -106,6 +106,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Removing Instance ID" + vmId + " from backup offering"; + return "Removing Instance with ID:" + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID) + " from backup offering"; } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/RestoreBackupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/RestoreBackupCmd.java index 3d096c0bb388..c29d117161f2 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/RestoreBackupCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/RestoreBackupCmd.java @@ -28,7 +28,6 @@ import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.cloudstack.api.response.BackupResponse; -import org.apache.cloudstack.backup.Backup; import org.apache.cloudstack.backup.BackupManager; import org.apache.cloudstack.context.CallContext; @@ -100,7 +99,6 @@ public String getEventType() { @Override public String getEventDescription() { - String backupUuid = _uuidMgr.getUuid(Backup.class, getBackupId()); - return "Restoring Instance from backup: " + backupUuid; + return "Restoring Instance from backup with ID: " + getResourceUuid(ApiConstants.ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/RestoreVolumeFromBackupAndAttachToVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/RestoreVolumeFromBackupAndAttachToVMCmd.java index cee367a149c2..703a1b2e8802 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/RestoreVolumeFromBackupAndAttachToVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/RestoreVolumeFromBackupAndAttachToVMCmd.java @@ -121,6 +121,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Restoring volume "+ volumeUuid + " from backup " + backupId + " and attaching it to Instance " + vmId; + return "Restoring volume "+ volumeUuid + " from backup " + getResourceUuid(ApiConstants.BACKUP_ID) + " and attaching it to Instance " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/bucket/CreateBucketCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/bucket/CreateBucketCmd.java index f1c149854d92..099b56368676 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/bucket/CreateBucketCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/bucket/CreateBucketCmd.java @@ -181,7 +181,7 @@ public void create() throws ResourceAllocationException { @Override public void execute() { - CallContext.current().setEventDetails("Bucket Id: " + getEntityUuid()); + CallContext.current().setEventDetails("Bucket ID: " + getEntityUuid()); Bucket bucket; try { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/bucket/DeleteBucketCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/bucket/DeleteBucketCmd.java index 8cd2790e4ae2..4a9a0569c3b8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/bucket/DeleteBucketCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/bucket/DeleteBucketCmd.java @@ -83,7 +83,7 @@ public ApiCommandResourceType getApiResourceType() { @Override public void execute() throws ConcurrentOperationException { - CallContext.current().setEventDetails("Bucket Id: " + this._uuidMgr.getUuid(Bucket.class, getId())); + CallContext.current().setEventDetails("Bucket ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _bucketService.deleteBucket(id, CallContext.current().getCallingAccount()); SuccessResponse response = new SuccessResponse(getCommandName()); response.setSuccess(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/bucket/UpdateBucketCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/bucket/UpdateBucketCmd.java index f913373c04b6..dc873c300497 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/bucket/UpdateBucketCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/bucket/UpdateBucketCmd.java @@ -113,7 +113,7 @@ public ApiCommandResourceType getApiResourceType() { @Override public void execute() throws ConcurrentOperationException { - CallContext.current().setEventDetails("Bucket Id: " + this._uuidMgr.getUuid(Bucket.class, getId())); + CallContext.current().setEventDetails("Bucket ID: " + getResourceUuid(ApiConstants.ID)); boolean result = false; try { result = _bucketService.updateBucket(this, CallContext.current().getCallingAccount()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java index f972cbdc6758..3fd571b7a479 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java @@ -147,7 +147,7 @@ public void execute() throws ResourceUnavailableException { boolean success = false; FirewallRule rule = _entityMgr.findById(FirewallRule.class, getEntityId()); try { - CallContext.current().setEventDetails("Rule Id: " + getEntityId()); + CallContext.current().setEventDetails("Rule ID: " + getEntityUuid()); success = _firewallService.applyEgressFirewallRules(rule, callerContext.getCallingAccount()); // State is different after the rule is applied, so get new object here rule = _entityMgr.findById(FirewallRule.class, getEntityId()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java index 92be579a1ced..bc65126f33bd 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java @@ -150,7 +150,7 @@ public void execute() throws ResourceUnavailableException { boolean success = false; FirewallRule rule = _entityMgr.findById(FirewallRule.class, getEntityId()); try { - CallContext.current().setEventDetails("Rule ID: " + getEntityId()); + CallContext.current().setEventDetails("Rule ID: " + getEntityUuid()); success = _firewallService.applyIngressFwRules(rule.getSourceIpAddressId(), callerContext.getCallingAccount()); // State is different after the rule is applied, so get new object here diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java index db6b788178ab..056807b9b535 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java @@ -199,7 +199,7 @@ public void execute() throws ResourceUnavailableException { boolean success = true; PortForwardingRule rule = null; try { - CallContext.current().setEventDetails("Rule Id: " + getEntityId()); + CallContext.current().setEventDetails("Rule ID: " + getEntityUuid()); if (getOpenFirewall()) { success = success && _firewallService.applyIngressFirewallRules(ipAddressId, callerContext.getCallingAccount()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeleteEgressFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeleteEgressFirewallRuleCmd.java index 60c7839bdc6d..4b606683a396 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeleteEgressFirewallRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeleteEgressFirewallRuleCmd.java @@ -71,7 +71,7 @@ public String getEventType() { @Override public String getEventDescription() { - return ("Deleting egress firewall rule id=" + id); + return ("Deleting egress firewall rule with ID: " + getResourceUuid(ApiConstants.ID)); } @Override @@ -89,7 +89,7 @@ public long getEntityOwnerId() { @Override public void execute() throws ResourceUnavailableException { - CallContext.current().setEventDetails("Rule Id: " + id); + CallContext.current().setEventDetails("Rule ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _firewallService.revokeEgressFirewallRule(id, true); if (result) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeleteFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeleteFirewallRuleCmd.java index 7c4d5f2249f5..ff2dce8dacf0 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeleteFirewallRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeleteFirewallRuleCmd.java @@ -69,7 +69,7 @@ public String getEventType() { @Override public String getEventDescription() { - return ("Deleting firewall rule ID=" + id); + return ("Deleting firewall rule with ID:" + getResourceUuid(ApiConstants.ID)); } @Override @@ -87,7 +87,7 @@ public long getEntityOwnerId() { @Override public void execute() throws ResourceUnavailableException { - CallContext.current().setEventDetails("Rule Id: " + id); + CallContext.current().setEventDetails("Rule ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _firewallService.revokeIngressFwRule(id, true); if (result) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeletePortForwardingRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeletePortForwardingRuleCmd.java index 47dd9e039eb3..d0b607d7af48 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeletePortForwardingRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeletePortForwardingRuleCmd.java @@ -73,7 +73,7 @@ public String getEventType() { @Override public String getEventDescription() { - return ("Deleting port forwarding rule for ID=" + id); + return "Deleting port forwarding rule with ID:" + getResourceUuid(ApiConstants.ID); } @Override @@ -92,7 +92,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Rule ID: " + id); + CallContext.current().setEventDetails("Rule ID: " + getResourceUuid(ApiConstants.ID)); //revoke corresponding firewall rule first boolean result = _firewallService.revokeRelatedFirewallRule(id, true); result = result && _rulesService.revokePortForwardingRule(id, true); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdateEgressFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdateEgressFirewallRuleCmd.java index 7516a78f0bac..26d561dbe03d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdateEgressFirewallRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdateEgressFirewallRuleCmd.java @@ -69,7 +69,7 @@ public Boolean getDisplay() { @Override public void execute() throws ResourceUnavailableException { - CallContext.current().setEventDetails("Rule Id: " + id); + CallContext.current().setEventDetails("Rule ID: " + getResourceUuid(ApiConstants.ID)); FirewallRule rule = _firewallService.updateEgressFirewallRule(id, this.getCustomId(), getDisplay()); FirewallResponse fwResponse = new FirewallResponse(); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdateFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdateFirewallRuleCmd.java index 347434d23940..1c2ea2b1897e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdateFirewallRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdateFirewallRuleCmd.java @@ -70,7 +70,7 @@ public Boolean getDisplay() { @Override public void execute() throws ResourceUnavailableException { - CallContext.current().setEventDetails("Rule ID: " + id); + CallContext.current().setEventDetails("Rule ID: " + getResourceUuid(ApiConstants.ID)); FirewallRule rule = _firewallService.updateIngressFirewallRule(id, this.getCustomId(), getDisplay()); FirewallResponse fwResponse = new FirewallResponse(); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/CreateIpv6FirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/CreateIpv6FirewallRuleCmd.java index 8db66112cdbe..237af7e4601b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/CreateIpv6FirewallRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/CreateIpv6FirewallRuleCmd.java @@ -232,7 +232,7 @@ public void execute() throws ResourceUnavailableException { boolean success = false; FirewallRule rule = ipv6Service.getIpv6FirewallRule(getEntityId()); try { - CallContext.current().setEventDetails("Rule ID: " + getEntityId()); + CallContext.current().setEventDetails("Rule ID: " + getEntityUuid()); success = ipv6Service.applyIpv6FirewallRule(rule.getId()); // State is different after the rule is applied, so get new object here diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/DeleteIpv6FirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/DeleteIpv6FirewallRuleCmd.java index 19ecbda290c6..6df5ce1438a1 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/DeleteIpv6FirewallRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/DeleteIpv6FirewallRuleCmd.java @@ -66,7 +66,7 @@ public String getEventType() { @Override public String getEventDescription() { - return ("Deleting IPv6 firewall rule ID=" + id); + return "Deleting IPv6 firewall rule with ID:" + getResourceUuid(ApiConstants.ID); } @Override @@ -81,7 +81,7 @@ public long getEntityOwnerId() { @Override public void execute() throws ResourceUnavailableException { - CallContext.current().setEventDetails("IPv6 firewall rule ID: " + id); + CallContext.current().setEventDetails("IPv6 firewall rule ID: " + getResourceUuid(ApiConstants.ID)); boolean result = ipv6Service.revokeIpv6FirewallRule(id); if (result) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/UpdateIpv6FirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/UpdateIpv6FirewallRuleCmd.java index 353f28e908b5..f090de4e8849 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/UpdateIpv6FirewallRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/UpdateIpv6FirewallRuleCmd.java @@ -156,7 +156,7 @@ public Integer getIcmpType() { @Override public void execute() throws ResourceUnavailableException { - CallContext.current().setEventDetails("Rule Id: " + getId()); + CallContext.current().setEventDetails("Rule ID: " + getResourceUuid(ApiConstants.ID)); FirewallRule rules = ipv6Service.updateIpv6FirewallRule(this); FirewallResponse ruleResponse = _responseGenerator.createIpv6FirewallRuleResponse(rules); setResponseObject(ruleResponse); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/iso/AttachIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/AttachIsoCmd.java index 27026d62a674..47d8d6c35f26 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/iso/AttachIsoCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/AttachIsoCmd.java @@ -99,7 +99,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "attaching ISO: " + getId() + " to Instance: " + getVirtualMachineId(); + return "Attaching ISO with ID: " + getResourceUuid(ApiConstants.ID) + " to Instance with ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID); } @Override @@ -114,7 +114,7 @@ public ApiCommandResourceType getApiResourceType() { @Override public void execute() { - CallContext.current().setEventDetails("Vm Id: " + getVirtualMachineId() + " ISO ID: " + getId()); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID) + " ISO ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _templateService.attachIso(id, virtualMachineId, isForced()); if (result) { UserVm userVm = _responseGenerator.findUserVmById(virtualMachineId); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/iso/DeleteIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/DeleteIsoCmd.java index b00b11ab1d31..28dfd25b2428 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/iso/DeleteIsoCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/DeleteIsoCmd.java @@ -87,7 +87,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting ISO " + getId(); + return "Deleting ISO with ID: " + getResourceUuid(ApiConstants.ID) + " from zone " + getResourceUuid(ApiConstants.ZONE_ID); } @Override @@ -102,7 +102,7 @@ public Long getApiResourceId() { @Override public void execute() { - CallContext.current().setEventDetails("ISO Id: " + getId()); + CallContext.current().setEventDetails("ISO ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _templateService.deleteIso(this); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/iso/DetachIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/DetachIsoCmd.java index 03d433827984..cf4aa41f795c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/iso/DetachIsoCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/DetachIsoCmd.java @@ -89,7 +89,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "detaching ISO from Instance: " + getVirtualMachineId(); + return "Detaching ISO from Instance with ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java index 6cd8b312f979..279db0f3104e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java @@ -17,7 +17,6 @@ package org.apache.cloudstack.api.command.user.iso; -import com.cloud.dc.DataCenter; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandResourceType; import org.apache.cloudstack.api.ApiConstants; @@ -102,15 +101,13 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - String isoId = this._uuidMgr.getUuid(VirtualMachineTemplate.class, getId()); - String baseDescription = String.format("Extracting ISO: %s", isoId); + String description = "Extracting ISO: " + getResourceUuid(ApiConstants.ID); - Long zoneId = getZoneId(); - if (zoneId == null) { - return baseDescription; + if (getZoneId() == null) { + description += "from zone: " + getResourceUuid(ApiConstants.ZONE_ID); } - return String.format("%s from zone: %s", baseDescription, this._uuidMgr.getUuid(DataCenter.class, zoneId)); + return description; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java index 87b193e2513f..c9b31dc84271 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java @@ -83,7 +83,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Assigning a certificate to a load balancer"; + return "Assigning certificate with ID: " + getResourceUuid(ApiConstants.CERTIFICATE_ID) + " to load balancer with ID: " + getResourceUuid(ApiConstants.LBID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java index f7962dab1379..6d8d356cea4d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java @@ -112,7 +112,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "applying Instances for load balancer: " + getLoadBalancerId() + " (ids: " + StringUtils.join(getVirtualMachineIds(), ",") + ")"; + return "Applying Instances for load balancer with ID: " + getResourceUuid(ApiConstants.ID) + " (Instances IDs: " + StringUtils.join(getVirtualMachineIds(), ",") + ")"; } @@ -155,7 +155,7 @@ public Map> getVmIdIpListMap() { @Override public void execute() { - CallContext.current().setEventDetails("Load balancer Id: " + getLoadBalancerId() + " Instance IDs: " + StringUtils.join(getVirtualMachineIds(), ",")); + CallContext.current().setEventDetails("Load balancer ID: " + getResourceUuid(ApiConstants.ID) + " Instances IDs: " + StringUtils.join(getVirtualMachineIds(), ",")); Map> vmIdIpsMap = getVmIdIpListMap(); boolean result = false; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateApplicationLoadBalancerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateApplicationLoadBalancerCmd.java index b244375d64b9..ae9eb31a2292 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateApplicationLoadBalancerCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateApplicationLoadBalancerCmd.java @@ -193,7 +193,7 @@ public long getEntityOwnerId() { public void execute() throws ResourceAllocationException, ResourceUnavailableException { ApplicationLoadBalancerRule rule = null; try { - CallContext.current().setEventDetails("Load Balancer Id: " + getEntityId()); + CallContext.current().setEventDetails("Load Balancer ID: " + getEntityUuid()); // State might be different after the rule is applied, so get new object here rule = _entityMgr.findById(ApplicationLoadBalancerRule.class, getEntityId()); ApplicationLoadBalancerResponse lbResponse = _responseGenerator.createLoadBalancerContainerReponse(rule, _lbService.getLbInstances(getEntityId())); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java index c4dfcad7918a..7b5cda13f1a5 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java @@ -155,7 +155,7 @@ public void execute() throws ResourceAllocationException, ResourceUnavailableExc boolean success = false; try { - CallContext.current().setEventDetails("Load balancer health check policy ID : " + getEntityId()); + CallContext.current().setEventDetails("Load balancer health check policy ID : " + getEntityUuid()); success = _lbService.applyLBHealthCheckPolicy(this); if (success) { // State might be different after the rule is applied, so get new object here diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java index b336b84517f4..e816e0f95ebb 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java @@ -138,7 +138,7 @@ public void execute() throws ResourceAllocationException, ResourceUnavailableExc boolean success = false; try { - CallContext.current().setEventDetails("Rule Id: " + getEntityId()); + CallContext.current().setEventDetails("Rule ID: " + getEntityUuid()); success = _lbService.applyLBStickinessPolicy(this); if (success) { // State might be different after the rule is applied, so get new object here diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java index c39b8b9c6ec0..bd72f248364e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java @@ -268,7 +268,7 @@ public void execute() throws ResourceAllocationException, ResourceUnavailableExc boolean success = true; LoadBalancer rule = null; try { - CallContext.current().setEventDetails("Rule Id: " + getEntityId()); + CallContext.current().setEventDetails("Rule ID: " + getEntityUuid()); if (getOpenFirewall()) { success = success && _firewallService.applyIngressFirewallRules(getSourceIpAddressId(), callerContext.getCallingAccount()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteApplicationLoadBalancerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteApplicationLoadBalancerCmd.java index f2064d42ca4f..8cfd1876325a 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteApplicationLoadBalancerCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteApplicationLoadBalancerCmd.java @@ -71,12 +71,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "deleting load balancer: " + getId(); + return "Deleting load balancer with ID: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { - CallContext.current().setEventDetails("Load balancer ID: " + getId()); + CallContext.current().setEventDetails("Load balancer ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _appLbService.deleteApplicationLoadBalancer(getId()); if (result) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBHealthCheckPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBHealthCheckPolicyCmd.java index 27a92bb25fc6..c01c5a4ca01e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBHealthCheckPolicyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBHealthCheckPolicyCmd.java @@ -76,12 +76,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "deleting load balancer health check policy: " + getId(); + return "Deleting load balancer health check policy with ID: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { - CallContext.current().setEventDetails("Load balancer health check policy Id: " + getId()); + CallContext.current().setEventDetails("Load balancer health check policy ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _lbService.deleteLBHealthCheckPolicy(getId(), true); if (result) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBStickinessPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBStickinessPolicyCmd.java index cc83835cd0e7..f26382478f4e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBStickinessPolicyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBStickinessPolicyCmd.java @@ -82,12 +82,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "deleting load balancer stickiness policy: " + getId(); + return "Deleting load balancer stickiness policy with ID: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { - CallContext.current().setEventDetails("Load balancer stickiness policy ID: " + getId()); + CallContext.current().setEventDetails("Load balancer stickiness policy ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _lbService.deleteLBStickinessPolicy(getId(), true); if (result) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLoadBalancerRuleCmd.java index fee9067d6950..a41808ced397 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLoadBalancerRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLoadBalancerRuleCmd.java @@ -76,12 +76,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "deleting load balancer: " + getId(); + return "Deleting load balancer with ID: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { - CallContext.current().setEventDetails("Load balancer ID: " + getId()); + CallContext.current().setEventDetails("Load balancer ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _firewallService.revokeRelatedFirewallRule(id, true); result = result && _lbService.deleteLoadBalancerRule(id, true); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java index 0fccddf68445..010a5ad6022d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java @@ -67,7 +67,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Removing a certificate from a load balancer with ID " + getLbRuleId(); + return "Removing certificate from load balancer with ID " + getResourceUuid(ApiConstants.LBID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/RemoveFromLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/RemoveFromLoadBalancerRuleCmd.java index 713879c8c785..ffcafd47822c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/RemoveFromLoadBalancerRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/RemoveFromLoadBalancerRuleCmd.java @@ -143,12 +143,12 @@ public Map> getVmIdIpListMap() { @Override public String getEventDescription() { - return "removing Instances from load balancer: " + getId() + " (ids: " + StringUtils.join(getVirtualMachineIds(), ",") + ")"; + return "Removing Instances from load balancer with ID: " + getResourceUuid(ApiConstants.ID) + " (instances IDs: " + StringUtils.join(getVirtualMachineIds(), ",") + ")"; } @Override public void execute() { - CallContext.current().setEventDetails("Load balancer Id: " + getId() + " Instance IDs: " + StringUtils.join(getVirtualMachineIds(), ",")); + CallContext.current().setEventDetails("Load balancer ID: " + getResourceUuid(ApiConstants.ID) + " Instances IDs: " + StringUtils.join(getVirtualMachineIds(), ",")); Map> vmIdIpsMap = getVmIdIpListMap(); try { boolean result = _lbService.removeFromLoadBalancer(id, virtualMachineIds, vmIdIpsMap, false); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateApplicationLoadBalancerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateApplicationLoadBalancerCmd.java index 19a366732d54..c2075c2c79e0 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateApplicationLoadBalancerCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateApplicationLoadBalancerCmd.java @@ -72,7 +72,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "updating load balancer: " + getId(); + return "Updating load balancer with ID: " + getResourceUuid(ApiConstants.ID); } @@ -81,7 +81,7 @@ public String getEventDescription() { ///////////////////////////////////////////////////// @Override public void execute() { - CallContext.current().setEventDetails("Load balancer ID: " + getId()); + CallContext.current().setEventDetails("Load balancer ID: " + getResourceUuid(ApiConstants.ID)); ApplicationLoadBalancerRule rule = _appLbService.updateApplicationLoadBalancer(getId(), this.getCustomId(), getDisplay()); ApplicationLoadBalancerResponse lbResponse = _responseGenerator.createLoadBalancerContainerReponse(rule, _lbService.getLbInstances(getId())); setResponseObject(lbResponse); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java index 5e6a877954ff..0ac99f1c760c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java @@ -119,12 +119,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "updating load balancer rule"; + return "Updating load balancer rule with ID: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { - CallContext.current().setEventDetails("Load balancer ID: " + getId()); + CallContext.current().setEventDetails("Load balancer ID: " + getResourceUuid(ApiConstants.ID)); LoadBalancer result = _lbService.updateLoadBalancerRule(this); if (result != null) { LoadBalancerResponse response = _responseGenerator.createLoadBalancerResponse(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java index 596d5952706a..7963dfe5c7d3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java @@ -108,7 +108,7 @@ public void execute() throws ResourceUnavailableException { boolean result = true; FirewallRule rule = null; try { - CallContext.current().setEventDetails("Rule ID: " + getEntityId()); + CallContext.current().setEventDetails("Rule ID: " + getEntityUuid()); if (getOpenFirewall()) { result = result && _firewallService.applyIngressFirewallRules(ipAddressId, CallContext.current().getCallingAccount()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/nat/DeleteIpForwardingRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/nat/DeleteIpForwardingRuleCmd.java index 6ca48bf36c43..ef9f428f8c8c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/nat/DeleteIpForwardingRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/nat/DeleteIpForwardingRuleCmd.java @@ -63,7 +63,7 @@ public Long getId() { @Override public void execute() { - CallContext.current().setEventDetails("Rule ID: " + id); + CallContext.current().setEventDetails("Rule ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _firewallService.revokeRelatedFirewallRule(id, true); result = result && _rulesService.revokeStaticNatRule(id, true); @@ -95,7 +95,7 @@ public String getEventType() { @Override public String getEventDescription() { - return ("Deleting an IP forwarding 1:1 NAT rule ID:" + id); + return "Deleting IP forwarding 1:1 NAT rule with ID:" + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/nat/DisableStaticNatCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/nat/DisableStaticNatCmd.java index f3d03b8beb37..d80d63541c0f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/nat/DisableStaticNatCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/nat/DisableStaticNatCmd.java @@ -67,7 +67,7 @@ public String getEventType() { @Override public String getEventDescription() { - return ("Disabling static NAT for IP ID=" + ipAddressId); + return ("Disabling static NAT for IP with ID: " + getResourceUuid(ApiConstants.IP_ADDRESS_ID)); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java index 087e31c08829..1776436b31a3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java @@ -274,7 +274,7 @@ public void execute() throws ResourceUnavailableException { boolean success = false; NetworkACLItem rule = _networkACLService.getNetworkACLItem(getEntityId()); try { - CallContext.current().setEventDetails("Rule ID: " + getEntityId()); + CallContext.current().setEventDetails("Rule ID: " + getEntityUuid()); success = _networkACLService.applyNetworkACL(rule.getAclId()); // State is different after the rule is applied, so get new object here diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLCmd.java index 76bbd127066c..a8506e06c4a3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLCmd.java @@ -61,7 +61,7 @@ public String getEventType() { @Override public String getEventDescription() { - return ("Deleting Network ACL ID=" + id); + return "Deleting Network ACL with ID:" + getResourceUuid(ApiConstants.ID); } @Override @@ -82,7 +82,7 @@ public ApiCommandResourceType getApiResourceType() { @Override public void execute() throws ResourceUnavailableException { - CallContext.current().setEventDetails("Network ACL item ID: " + id); + CallContext.current().setEventDetails("Network ACL item ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _networkACLService.revokeNetworkACLItem(id); if (result) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLListCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLListCmd.java index 0352a5756b18..3e3894a26864 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLListCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLListCmd.java @@ -61,7 +61,7 @@ public String getEventType() { @Override public String getEventDescription() { - return ("Deleting network ACL ID=" + id); + return ("Deleting network ACL with ID: " + getResourceUuid(ApiConstants.ID)); } @Override @@ -82,7 +82,7 @@ public ApiCommandResourceType getApiResourceType() { @Override public void execute() throws ResourceUnavailableException { - CallContext.current().setEventDetails("Network ACL ID: " + id); + CallContext.current().setEventDetails("Network ACL ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _networkACLService.deleteNetworkACL(id); if (result) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkCmd.java index 7063be7ee180..0543794e8bf5 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkCmd.java @@ -66,7 +66,7 @@ public boolean isForced() { @Override public void execute() { - CallContext.current().setEventDetails("Network Id: " + id); + CallContext.current().setEventDetails("Network ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _networkService.deleteNetwork(id, isForced()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); @@ -93,7 +93,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting network: " + id; + return "Deleting network with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java index faddd340f83a..0b210b6b95d8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java @@ -76,7 +76,13 @@ public String getEventType() { @Override public String getEventDescription() { - return ("Associating network ACL ID=" + aclId + " with network ID=" + networkId); + String description = "Associating Network ACL with ID:" + getResourceUuid(ApiConstants.ACL_ID); + + if (getNetworkId() != null) { + description += " to Network with ID:" + getResourceUuid(ApiConstants.NETWORK_ID); + } + + return description; } @Override @@ -95,7 +101,7 @@ public void execute() throws ResourceUnavailableException { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Network ID and private gateway can't be passed at the same time"); } - CallContext.current().setEventDetails("Network ACL ID: " + aclId); + CallContext.current().setEventDetails("Network ACL ID: " + getResourceUuid(ApiConstants.ACL_ID)); boolean result = false; if (getPrivateGatewayId() != null) { result = _networkACLService.replaceNetworkACLonPrivateGw(aclId, privateGatewayId); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/RestartNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/RestartNetworkCmd.java index c04a50cb05d8..2742e5ef6d18 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/network/RestartNetworkCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/RestartNetworkCmd.java @@ -115,7 +115,7 @@ public Long getSyncObjId() { @Override public String getEventDescription() { - return "Restarting network: " + getNetworkId(); + return "Restarting Network with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java index 9e7e1b5b8542..f1ba3a55a96c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java @@ -176,7 +176,7 @@ public String getReason() { @Override public void execute() throws ResourceUnavailableException { - CallContext.current().setEventDetails("Rule Id: " + getId()); + CallContext.current().setEventDetails("Rule ID: " + getResourceUuid(ApiConstants.ID)); NetworkACLItem aclItem = _networkACLService.updateNetworkACLItem(this); NetworkACLItemResponse aclResponse = _responseGenerator.createNetworkACLItemResponse(aclItem); setResponseObject(aclResponse); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/routing/CreateRoutingFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/routing/CreateRoutingFirewallRuleCmd.java index ad52916c7a92..85166f5ab84a 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/network/routing/CreateRoutingFirewallRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/routing/CreateRoutingFirewallRuleCmd.java @@ -238,7 +238,7 @@ public void execute() throws ResourceUnavailableException { boolean success = false; FirewallRule rule = _firewallService.getFirewallRule(getEntityId()); try { - CallContext.current().setEventDetails("Rule ID: " + getEntityId()); + CallContext.current().setEventDetails("Rule ID: " + getEntityUuid()); success = routedIpv4Manager.applyRoutingFirewallRule(rule.getId()); // State is different after the rule is applied, so get new object here diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/routing/DeleteRoutingFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/routing/DeleteRoutingFirewallRuleCmd.java index 16696f5f71b7..646b704e088c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/network/routing/DeleteRoutingFirewallRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/routing/DeleteRoutingFirewallRuleCmd.java @@ -67,7 +67,7 @@ public String getEventType() { @Override public String getEventDescription() { - return String.format("Deleting ipv4 routing firewall rule ID=%s", id); + return String.format("Deleting IPv4 routing firewall rule with ID: %s", getResourceUuid(ApiConstants.ID)); } @Override @@ -82,7 +82,7 @@ public long getEntityOwnerId() { @Override public void execute() throws ResourceUnavailableException { - CallContext.current().setEventDetails("Routing firewall rule ID: " + id); + CallContext.current().setEventDetails("Routing firewall rule with ID: " + getResourceUuid(ApiConstants.ID)); boolean result = routedIpv4Manager.revokeRoutingFirewallRule(id); if (result) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/routing/UpdateRoutingFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/routing/UpdateRoutingFirewallRuleCmd.java index c6f6034b1ba1..3c3a07ceece1 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/network/routing/UpdateRoutingFirewallRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/routing/UpdateRoutingFirewallRuleCmd.java @@ -95,7 +95,7 @@ public String getEventDescription() { @Override public void execute() throws ResourceUnavailableException { - CallContext.current().setEventDetails("Rule Id: " + getId()); + CallContext.current().setEventDetails("Rule ID: " + getResourceUuid(ApiConstants.ID)); FirewallRule rule = routedIpv4Manager.updateRoutingFirewallRule(this); FirewallResponse ruleResponse = _responseGenerator.createFirewallResponse(rule); setResponseObject(ruleResponse); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/project/ActivateProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/ActivateProjectCmd.java index 228afb5a1862..c6717ac659a4 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/project/ActivateProjectCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/project/ActivateProjectCmd.java @@ -80,7 +80,7 @@ public List getEntityOwnerIds() { @Override public void execute() { - CallContext.current().setEventDetails("Project id: " + getId()); + CallContext.current().setEventDetails("Project ID: " + getResourceUuid(ApiConstants.ID)); Project project = _projectService.activateProject(getId()); if (project != null) { ProjectResponse response = _responseGenerator.createProjectResponse(project); @@ -98,6 +98,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Activating project: " + id; + return "Activating project with ID: " + getResourceUuid(ApiConstants.ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/project/DeleteProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/DeleteProjectCmd.java index d4e2b8f56f91..c2a0c132448b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/project/DeleteProjectCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/project/DeleteProjectCmd.java @@ -66,7 +66,7 @@ public Boolean isCleanup() { @Override public void execute() { - CallContext.current().setEventDetails("Project Id: " + id); + CallContext.current().setEventDetails("Project ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _projectService.deleteProject(id, isCleanup()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); @@ -83,7 +83,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting project: " + id; + return "Deleting project with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/project/DeleteProjectInvitationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/DeleteProjectInvitationCmd.java index 7fe2c3c4abc6..b1d129b8af77 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/project/DeleteProjectInvitationCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/project/DeleteProjectInvitationCmd.java @@ -59,7 +59,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Project invitation id " + id); + CallContext.current().setEventDetails("Project invitation ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _projectService.deleteProjectInvitation(id); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); @@ -76,7 +76,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Project invitatino id " + id + " is being removed"; + return "Removing project invitation with ID: " + getResourceUuid(ApiConstants.ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/project/SuspendProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/SuspendProjectCmd.java index 7850e7bf694b..f67d0d55587d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/project/SuspendProjectCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/project/SuspendProjectCmd.java @@ -60,7 +60,7 @@ public Long geId() { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException { - CallContext.current().setEventDetails("Project Id: " + id); + CallContext.current().setEventDetails("Project ID: " + getResourceUuid(ApiConstants.ID)); Project project = _projectService.suspendProject(id); if (project != null) { ProjectResponse response = _responseGenerator.createProjectResponse(project); @@ -78,7 +78,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Suspending project: " + id; + return "Suspending project with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/project/UpdateProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/UpdateProjectCmd.java index e38f9417e8a8..2d9bb92e4a36 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/project/UpdateProjectCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/project/UpdateProjectCmd.java @@ -133,7 +133,7 @@ public List getEntityOwnerIds() { @Override public void execute() throws ResourceAllocationException { - CallContext.current().setEventDetails("Project id: " + getId()); + CallContext.current().setEventDetails("Project ID: " + getResourceUuid(ApiConstants.ID)); if (getAccountName() != null && getUserId() != null) { throw new InvalidParameterValueException("Account name and User ID are mutually exclusive. Provide either Account name" + "to update Account or user ID to update the user of the project"); @@ -161,6 +161,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Updating project: " + id; + return "Updating project with ID: " + getResourceUuid(ApiConstants.ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/project/UpdateProjectInvitationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/UpdateProjectInvitationCmd.java index a8a6fb802fbf..34918de7339f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/project/UpdateProjectInvitationCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/project/UpdateProjectInvitationCmd.java @@ -92,7 +92,7 @@ public long getEntityOwnerId() { @Override public void execute() { - String eventDetails = "Project id: " + projectId + ";"; + String eventDetails = "Project id: " + getResourceUuid(ApiConstants.PROJECT_ID) + ";"; if (accountName != null) { eventDetails += " accountName: " + accountName + ";"; } else if (userId != null) { @@ -116,6 +116,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Updating project invitation for projectId " + projectId; + return "Updating project invitation for project with ID: " + getResourceUuid(ApiConstants.PROJECT_ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java index 1cda9ab2757d..8bb38d97c134 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java @@ -145,13 +145,13 @@ public String getEventType() { @Override public String getEventDescription() { - return "assign load balancer rules " + StringUtils.join(getLoadBalancerRulesIds(), ",") + " to global load balancer rule " + getGlobalLoadBalancerRuleId(); + return "Assigning load balancer rules " + StringUtils.join(getLoadBalancerRulesIds(), ",") + " to global load balancer rule " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { CallContext.current().setEventDetails( - "Global Load balancer rule Id: " + getGlobalLoadBalancerRuleId() + " VmIds: " + StringUtils.join(getLoadBalancerRulesIds(), ",")); + "Global Load balancer rule ID: " + getResourceUuid(ApiConstants.ID) + " Instances IDs: " + StringUtils.join(getLoadBalancerRulesIds(), ",")); boolean result = _gslbService.assignToGlobalLoadBalancerRule(this); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java index 20b227b831c1..2ecd8ef22e65 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java @@ -153,7 +153,7 @@ public void create() { GlobalLoadBalancerRule gslbRule = _gslbService.createGlobalLoadBalancerRule(this); this.setEntityId(gslbRule.getId()); this.setEntityUuid(gslbRule.getUuid()); - CallContext.current().setEventDetails("Rule Id: " + getEntityId()); + CallContext.current().setEventDetails("Rule ID: " + getEntityUuid()); } catch (Exception ex) { logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java index 6053a11cf711..b44b547463e5 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java @@ -85,12 +85,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "deleting global load balancer rule: " + getGlobalLoadBalancerId(); + return "Deleting global load balancer rule with ID: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { - CallContext.current().setEventDetails("Deleting global Load balancer rule Id: " + getGlobalLoadBalancerId()); + CallContext.current().setEventDetails("Deleting global Load balancer rule with ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _gslbService.deleteGlobalLoadBalancerRule(this); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/RemoveFromGlobalLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/RemoveFromGlobalLoadBalancerRuleCmd.java index eb72cad86f29..a0ec9a1296ab 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/RemoveFromGlobalLoadBalancerRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/RemoveFromGlobalLoadBalancerRuleCmd.java @@ -108,13 +108,13 @@ public String getEventType() { @Override public String getEventDescription() { - return "removing load balancer rules:" + StringUtils.join(getLoadBalancerRulesIds(), ",") + " from global load balancer: " + getGlobalLoadBalancerRuleId(); + return "Removing load balancer rules:" + StringUtils.join(getLoadBalancerRulesIds(), ",") + " from global load balancer: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { CallContext.current().setEventDetails( - "Global Load balancer rule Id: " + getGlobalLoadBalancerRuleId() + " VmIds: " + StringUtils.join(getLoadBalancerRulesIds(), ",")); + "Global Load balancer rule Id: " + getResourceUuid(ApiConstants.ID) + " VmIds: " + StringUtils.join(getLoadBalancerRulesIds(), ",")); boolean result = _gslbService.removeFromGlobalLoadBalancerRule(this); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/UpdateGlobalLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/UpdateGlobalLoadBalancerRuleCmd.java index 7ccf62a293af..a56672e29cac 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/UpdateGlobalLoadBalancerRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/UpdateGlobalLoadBalancerRuleCmd.java @@ -107,7 +107,7 @@ public long getEntityOwnerId() { @Override public void execute() { - org.apache.cloudstack.context.CallContext.current().setEventDetails("Global Load balancer Id: " + getId()); + org.apache.cloudstack.context.CallContext.current().setEventDetails("Global Load balancer ID: " + getResourceUuid(ApiConstants.ID)); GlobalLoadBalancerRule gslbRule = _gslbService.updateGlobalLoadBalancerRule(this); if (gslbRule != null) { GlobalLoadBalancerResponse response = _responseGenerator.createGlobalLoadBalancerResponse(gslbRule); @@ -125,6 +125,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "updating global load balancer rule"; + return "Updating global load balancer rule with ID: " + getResourceUuid(ApiConstants.ID); } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java index bf435406174c..91f2b7ad999a 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java @@ -82,7 +82,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "revoking egress rule id: " + getId(); + return "Revoking egress rule with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java index c426647fe36c..2d7e591214df 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java @@ -83,7 +83,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "revoking ingress rule id: " + getId(); + return "Revoking ingress rule with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ArchiveSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ArchiveSnapshotCmd.java index c6ed36ccef53..cae2a32a09fd 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ArchiveSnapshotCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ArchiveSnapshotCmd.java @@ -54,12 +54,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "Archiving Snapshot " + id + " to secondary storage"; + return "Archiving Snapshot with ID: " + getResourceUuid(ApiConstants.ID) + " to secondary storage"; } @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { - CallContext.current().setEventDetails("Snapshot Id: " + this._uuidMgr.getUuid(Snapshot.class,getId())); + CallContext.current().setEventDetails("Snapshot ID: " + getResourceUuid(ApiConstants.ID)); Snapshot snapshot = _snapshotService.archiveSnapshot(getId()); if (snapshot != null) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CopySnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CopySnapshotCmd.java index 519f9876b960..c67439a2ef7c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CopySnapshotCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CopySnapshotCmd.java @@ -144,18 +144,22 @@ public String getEventType() { @Override public String getEventDescription() { - StringBuilder descBuilder = new StringBuilder(); + StringBuilder descBuilder = new StringBuilder("Copying snapshot with ID: " + getResourceUuid(ApiConstants.ID)); + if (getDestinationZoneIds() != null) { + descBuilder.append(" to zones: ["); + for (Long destId : getDestinationZoneIds()) { - descBuilder.append(", "); descBuilder.append(_uuidMgr.getUuid(DataCenter.class, destId)); + descBuilder.append(", "); } - if (descBuilder.length() > 0) { - descBuilder.deleteCharAt(0); - } + + descBuilder.deleteCharAt(descBuilder.length() - 1); + + descBuilder.append("]"); } - return "copying snapshot: " + _uuidMgr.getUuid(Snapshot.class, getId()) + ((descBuilder.length() > 0) ? " to zones: " + descBuilder.toString() : ""); + return descBuilder.toString(); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java index b2b1da91abea..d03df501847a 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java @@ -229,7 +229,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Creating Snapshot for volume: " + getVolumeUuid(); + return "Creating Snapshot for volume: " + getResourceUuid(ApiConstants.VOLUME_ID); } @Override @@ -244,7 +244,7 @@ public void create() throws ResourceAllocationException { setEntityId(snapshot.getId()); setEntityUuid(snapshot.getUuid()); } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create Snapshot for volume" + getVolumeUuid()); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create Snapshot for volume" + getResourceUuid(ApiConstants.VOLUME_ID)); } } @@ -260,14 +260,14 @@ public void execute() { response.setResponseName(getCommandName()); setResponseObject(response); } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Snapshot from volume [%s] was not found in database.", getVolumeUuid())); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Snapshot from volume [%s] was not found in database.", getResourceUuid(ApiConstants.VOLUME_ID))); } } catch (Exception e) { if (e.getCause() instanceof UnsupportedOperationException) { throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, String.format("Failed to create Snapshot due to unsupported operation: %s", e.getCause().getMessage())); } - String errorMessage = "Failed to create Snapshot due to an internal error creating Snapshot for volume " + getVolumeUuid(); + String errorMessage = "Failed to create Snapshot due to an internal error creating Snapshot for volume " + getResourceUuid(ApiConstants.VOLUME_ID); logger.error(errorMessage, e); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMessage); } @@ -312,8 +312,4 @@ public Boolean getAsyncBackup() { return asyncBackup; } } - - protected String getVolumeUuid() { - return _uuidMgr.getUuid(Volume.class, getVolumeId()); - } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotFromVMSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotFromVMSnapshotCmd.java index 0dd275cb4ae2..6fb5fb0463ab 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotFromVMSnapshotCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotFromVMSnapshotCmd.java @@ -143,7 +143,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Creating Snapshot from Instance Snapshot : " + this._uuidMgr.getUuid(VMSnapshot.class, getVMSnapshotId()); + return "Creating Snapshot from Instance Snapshot : " + getResourceUuid(ApiConstants.VOLUME_ID); } @Override @@ -166,7 +166,7 @@ public void create() throws ResourceAllocationException { public void execute() { VMSnapshot vmSnapshot = _vmSnapshotService.getVMSnapshotById(getVMSnapshotId()); logger.info("CreateSnapshotFromVMSnapshotCmd with {} and Snapshot [ID: {}, UUID: {}]", vmSnapshot, getEntityId(), getEntityUuid()); - CallContext.current().setEventDetails("Instance Snapshot Id: " + vmSnapshot.getUuid()); + CallContext.current().setEventDetails("Instance Snapshot ID: " + vmSnapshot.getUuid()); Snapshot snapshot = null; try { snapshot = _snapshotService.backupSnapshotFromVmSnapshot(getEntityId(), getVmId(), getVolumeId(), getVMSnapshotId()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java index 894777375819..b4eaceb61ba6 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java @@ -85,7 +85,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting Snapshot: " + this._uuidMgr.getUuid(Snapshot.class, getId()); + return "Deleting Snapshot with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -100,7 +100,7 @@ public Long getApiResourceId() { @Override public void execute() { - CallContext.current().setEventDetails("Snapshot Id: " + this._uuidMgr.getUuid(Snapshot.class, getId())); + CallContext.current().setEventDetails("Snapshot ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _snapshotService.deleteSnapshot(getId(), getZoneId()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ExtractSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ExtractSnapshotCmd.java index 3f0f82ea4e3b..dacdd20b3969 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ExtractSnapshotCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ExtractSnapshotCmd.java @@ -96,12 +96,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "Snapshot extraction job"; + return "Starting Snapshot extraction for Snapshot with ID: " + getResourceUuid(ApiConstants.ID); } @Override public void execute() { - CallContext.current().setEventDetails("Snapshot ID: " + this._uuidMgr.getUuid(Snapshot.class, getId())); + CallContext.current().setEventDetails("Snapshot ID: " + getResourceUuid(ApiConstants.ID)); String uploadUrl = _snapshotService.extractSnapshot(this); logger.info("Extract URL [{}] of snapshot [{}].", uploadUrl, id); if (uploadUrl != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java index 7cee7e71cf37..59881dfdabe2 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java @@ -74,7 +74,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "revert Snapshot: " + this._uuidMgr.getUuid(Snapshot.class, getId()); + return "Reverting Snapshot with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -89,7 +89,7 @@ public Long getApiResourceId() { @Override public void execute() { - CallContext.current().setEventDetails("Snapshot Id: " + this._uuidMgr.getUuid(Snapshot.class, getId())); + CallContext.current().setEventDetails("Snapshot ID: " + getResourceUuid(ApiConstants.ID)); Snapshot snapshot = _snapshotService.revertSnapshot(getId()); if (snapshot != null) { SnapshotResponse response = _responseGenerator.createSnapshotResponse(snapshot); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java index ba98956644cb..84f8d0b3c390 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java @@ -104,7 +104,7 @@ public String getEventDescription() { @Override public void execute() { - CallContext.current().setEventDetails("SnapshotPolicy ID: " + getId()); + CallContext.current().setEventDetails("Snapshot policy ID: " + getResourceUuid(ApiConstants.ID)); SnapshotPolicy result = _snapshotService.updateSnapshotPolicy(this); if (result != null) { SnapshotPolicyResponse response = _responseGenerator.createSnapshotPolicyResponse(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ChangeSharedFSDiskOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ChangeSharedFSDiskOfferingCmd.java index b078ce4aae95..24290bc345e1 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ChangeSharedFSDiskOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ChangeSharedFSDiskOfferingCmd.java @@ -117,7 +117,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Changing disk offering for the Shared FileSystem " + id; + return "Changing disk offering for the Shared FileSystem with ID:" + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ChangeSharedFSServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ChangeSharedFSServiceOfferingCmd.java index 70fb543d64c3..1ac0f27067b4 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ChangeSharedFSServiceOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ChangeSharedFSServiceOfferingCmd.java @@ -96,7 +96,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Changing service offering for the Shared FileSystem " + id; + return "Changing service offering for the Shared FileSystem with ID:" + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/DestroySharedFSCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/DestroySharedFSCmd.java index 09fae53f1284..35f16a4dc2a0 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/DestroySharedFSCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/DestroySharedFSCmd.java @@ -95,7 +95,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Destroying Shared FileSystem " + id; + return "Destroying Shared FileSystem with ID:" + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ExpungeSharedFSCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ExpungeSharedFSCmd.java index 39b99218b667..8960aa3e4d40 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ExpungeSharedFSCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/ExpungeSharedFSCmd.java @@ -74,7 +74,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Expunging Shared FileSystem " + id; + return "Expunging Shared FileSystem with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/RestartSharedFSCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/RestartSharedFSCmd.java index 576c472b6eb2..75565796caa4 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/RestartSharedFSCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/RestartSharedFSCmd.java @@ -94,7 +94,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Restarting Shared FileSystem " + id; + return "Restarting Shared FileSystem with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/StartSharedFSCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/StartSharedFSCmd.java index bd384aceef73..d7440b532b31 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/StartSharedFSCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/StartSharedFSCmd.java @@ -84,7 +84,7 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - return "Starting Shared FileSystem " + id; + return "Starting Shared FileSystem with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/StopSharedFSCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/StopSharedFSCmd.java index d6e0737144a5..3800b16289e7 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/StopSharedFSCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/storage/sharedfs/StopSharedFSCmd.java @@ -92,7 +92,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Stopping Shared FileSystem " + id; + return "Stopping Shared FileSystem with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java index 66a20fac8606..02601b2257f1 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java @@ -136,19 +136,21 @@ public String getEventType() { @Override public String getEventDescription() { - StringBuilder descBuilder = new StringBuilder(); - if (getDestinationZoneIds() != null) { + String description = "Copying Template: " + getResourceUuid(ApiConstants.ID); + + if (getSourceZoneId() != null) { + description += " from zone: " + getResourceUuid(ApiConstants.SOURCE_ZONE_ID); + } + if (getDestinationZoneIds() != null) { + description += " to zones: "; for (Long destId : getDestinationZoneIds()) { - descBuilder.append(", "); - descBuilder.append(this._uuidMgr.getUuid(DataCenter.class, destId)); - } - if (descBuilder.length() > 0) { - descBuilder.deleteCharAt(0); + description += this._uuidMgr.getUuid(DataCenter.class, destId); + description += ", "; } } - return "Copying Template: " + this._uuidMgr.getUuid(VirtualMachineTemplate.class, getId()) +((getSourceZoneId() != null) ? " from zone: " + this._uuidMgr.getUuid(DataCenter.class, getSourceZoneId()) : "") + ((descBuilder.length() > 0) ? " to zones: " + descBuilder.toString() : ""); + return description; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java index 76fadb7853ba..b5e41ff449ca 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java @@ -301,7 +301,7 @@ public void create() throws ResourceAllocationException { @Override public void execute() { CallContext.current().setEventDetails( - "Template Id: " + getEntityUuid() + ((getSnapshotId() == null) ? " from volume Id: " + this._uuidMgr.getUuid(Volume.class, getVolumeId()) : " from Snapshot Id: " + this._uuidMgr.getUuid(Snapshot.class, getSnapshotId()))); + "Template ID: " + getEntityUuid() + ((getSnapshotId() == null) ? " from volume with ID: " + getResourceUuid(ApiConstants.VOLUME_ID) : " from Snapshot with ID: " + getResourceUuid(ApiConstants.SNAPSHOT_ID))); VirtualMachineTemplate template = _templateService.createPrivateTemplate(this); if (template != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/template/DeleteTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/DeleteTemplateCmd.java index fef70d188e59..3c7b1e2708b8 100755 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/template/DeleteTemplateCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/template/DeleteTemplateCmd.java @@ -98,7 +98,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting Template " + this._uuidMgr.getUuid(VirtualMachineTemplate.class, getId()); + return "Deleting Template with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -113,7 +113,7 @@ public Long getApiResourceId() { @Override public void execute() { - CallContext.current().setEventDetails("Template Id: " + this._uuidMgr.getUuid(VirtualMachineTemplate.class, getId())); + CallContext.current().setEventDetails("Template ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _templateService.deleteTemplate(this); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java index b0215b12ef2e..d3f039ce38de 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java @@ -28,7 +28,6 @@ import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.context.CallContext; -import com.cloud.dc.DataCenter; import com.cloud.event.EventTypes; import com.cloud.exception.InternalErrorException; import com.cloud.template.VirtualMachineTemplate; @@ -101,15 +100,14 @@ public String getEventType() { @Override public String getEventDescription() { - String templateId = this._uuidMgr.getUuid(VirtualMachineTemplate.class, getId()); - String baseDescription = String.format("Extracting Template: %s", templateId); + String description = "Extracting Template with ID: " + getResourceUuid(ApiConstants.ID); Long zoneId = getZoneId(); - if (zoneId == null) { - return baseDescription; + if (zoneId != null) { + description += "from zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID); } - return String.format("%s from zone: %s", baseDescription, this._uuidMgr.getUuid(DataCenter.class, zoneId)); + return description; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java index 3882b157e6e8..6274e7e14963 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java @@ -89,7 +89,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Associating IP to NIC id=" + this._uuidMgr.getUuid(Nic.class, getNicId()) + " belonging to Network id=" + this._uuidMgr.getUuid(Network.class, getNetworkId()); + return "Associating secondary IP address to NIC with ID: " + getResourceUuid(ApiConstants.NIC_ID) + " belonging to Network with ID: " + this._uuidMgr.getUuid(Network.class, getNetworkId()); } ///////////////////////////////////////////////////// @@ -108,11 +108,11 @@ public static String getResultObjectName() { @Override public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { - CallContext.current().setEventDetails("Nic Id: " + this._uuidMgr.getUuid(Nic.class, getNicId())); + CallContext.current().setEventDetails("Nic ID: " + getResourceUuid(ApiConstants.NIC_ID)); NicSecondaryIp result = _entityMgr.findById(NicSecondaryIp.class, getEntityId()); if (result != null) { - CallContext.current().setEventDetails("secondary Ip Id: " + getEntityUuid()); + CallContext.current().setEventDetails("Secondary IP address ID: " + getEntityUuid()); boolean success = false; success = _networkService.configureNicSecondaryIp(result, isZoneSGEnabled()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java index cf91e15601ba..6347c38811e8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java @@ -40,7 +40,6 @@ import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.network.Network; import com.cloud.user.Account; import com.cloud.uservm.UserVm; import com.cloud.utils.net.Dhcp; @@ -121,7 +120,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Adding Network " + this._uuidMgr.getUuid(Network.class, getNetworkId()) + " to User Instance: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()); + return "Adding NIC on Network " + getResourceUuid(ApiConstants.NETWORK_ID) + " to User Instance: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID); } @Override @@ -167,7 +166,7 @@ public ApiCommandResourceType getApiResourceType() { @Override public void execute() { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()) + " Network Id: " + this._uuidMgr.getUuid(Network.class, getNetworkId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID) + " Network ID: " + getResourceUuid(ApiConstants.NETWORK_ID)); UserVm result = _userVmService.addNicToVirtualMachine(this); ArrayList dc = new ArrayList(); dc.add(VMDetails.valueOf("nics")); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/BaseDeployVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/BaseDeployVMCmd.java index 07c11b21107a..438f3b2d323f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/BaseDeployVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/BaseDeployVMCmd.java @@ -828,15 +828,15 @@ public String getCreateEventType() { @Override public String getCreateEventDescription() { - return "creating Vm"; + return "Creating Instance"; } @Override public String getEventDescription() { if(getStartVm()) { - return "starting Vm. Vm Id: " + getEntityUuid(); + return "Starting Instance with ID: " + getEntityUuid(); } - return "deploying Vm. Vm Id: " + getEntityUuid(); + return "Deploying Instance with ID: " + getEntityUuid(); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java index 528a8b0c7359..050592b97a3b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java @@ -92,7 +92,7 @@ public boolean isVolumeOrSnapshotProvided() { public void execute() { UserVm result; - CallContext.current().setEventDetails("Instance Id: " + getEntityUuid()); + CallContext.current().setEventDetails("Instance ID: " + getEntityUuid()); if (getStartVm()) { try { result = _userVmService.startVirtualMachine(this); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java index 1ca73c0cb3cd..9e2f2bcb72ce 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java @@ -116,7 +116,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "destroying Instance: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); + return "Destroying Instance with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -131,7 +131,7 @@ public Long getApiResourceId() { @Override public void execute() throws ResourceUnavailableException, ConcurrentOperationException { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); UserVm result = _userVmService.destroyVm(this); UserVmResponse response = new UserVmResponse(); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java index 32756755f395..6f4431547848 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java @@ -100,7 +100,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Rebooting User Instance: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); + return "Rebooting User Instance with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -115,7 +115,7 @@ public Long getApiResourceId() { @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); UserVm result; result = _userVmService.rebootVirtualMachine(this); if (result !=null){ diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java index 09c84fdbb380..f4c4d82b30d4 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java @@ -93,7 +93,7 @@ public NicSecondaryIp getIpEntry() { @Override public String getEventDescription() { - return ("Disassociating ip address with id=" + id); + return "Disassociating IP address with ID:" + getResourceUuid(ApiConstants.ID); } ///////////////////////////////////////////////////// @@ -132,7 +132,7 @@ private boolean isZoneSGEnabled() { @Override public void execute() throws InvalidParameterValueException { - CallContext.current().setEventDetails("Ip Id: " + id); + CallContext.current().setEventDetails("IP address ID: " + getResourceUuid(ApiConstants.ID)); NicSecondaryIp nicSecIp = getIpEntry(); if (nicSecIp == null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java index 8a891e824eea..cfbc64339909 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java @@ -19,8 +19,6 @@ import java.util.ArrayList; import java.util.EnumSet; -import com.cloud.vm.Nic; - import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -89,7 +87,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Removing NIC " + this._uuidMgr.getUuid(Nic.class, getNicId()) + " from User Instance: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()); + return "Removing NIC with ID: " + getResourceUuid(ApiConstants.NIC_ID) + " from User Instance: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID); } @Override @@ -103,7 +101,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()) + " Nic Id: " + this._uuidMgr.getUuid(Nic.class, getNicId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID) + " NIC ID: " + getResourceUuid(ApiConstants.NIC_ID)); UserVm result = _userVmService.removeNicFromVirtualMachine(this); ArrayList dc = new ArrayList(); dc.add(VMDetails.valueOf("nics")); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java index 5302675fb5f1..b6179efc0d35 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java @@ -101,7 +101,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "resetting password for Instance: " + getId(); + return "Resetting password for Instance with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -124,7 +124,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE } else { logger.debug("Resetting VM [{}] password to password defined by user.", vm.getUuid()); } - CallContext.current().setEventDetails("Vm Id: " + getId()); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); UserVm result = _userVmService.resetVMPassword(this, password); if (result != null){ UserVmResponse response = _responseGenerator.createUserVmResponse(getResponseView(), "virtualmachine", result).get(0); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMSSHKeyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMSSHKeyCmd.java index 530677edf383..73e4ec623f23 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMSSHKeyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMSSHKeyCmd.java @@ -121,7 +121,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "resetting SSHKey for Instance: " + getId(); + return "Resetting SSH key for Instance with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -152,7 +152,7 @@ public Long getApiResourceId() { @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException { - CallContext.current().setEventDetails("Vm Id: " + getId()); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); UserVm result = _userVmService.resetVMSSHKey(this); if (result != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMUserDataCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMUserDataCmd.java index 9fb60b537c5a..8c513549506f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMUserDataCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMUserDataCmd.java @@ -143,7 +143,7 @@ public Long getApiResourceId() { @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException { - CallContext.current().setEventDetails("Vm Id: " + getId()); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); UserVm result = _userVmService.resetVMUserData(this); if (result != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java index b92b2d1b3c16..d3459347687a 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java @@ -90,14 +90,14 @@ public String getEventType() { @Override public String getEventDescription() { - return "Restore an Instance to original Template or specific Snapshot"; + return "Restoring Instance with ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID) + " to original Template or specific Snapshot"; } @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { UserVm result; - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID)); result = _userVmService.restoreVM(this); if (result != null) { UserVmResponse response = _responseGenerator.createUserVmResponse(getResponseView(), "virtualmachine", result).get(0); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java index cd3aeefc44b2..36d0ad9c6500 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java @@ -39,7 +39,6 @@ import com.cloud.exception.ManagementServerException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.VirtualMachineMigrationException; -import com.cloud.offering.ServiceOffering; import com.cloud.user.Account; import com.cloud.uservm.UserVm; import com.cloud.vm.VirtualMachine; @@ -148,7 +147,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Upgrading Instance: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()) + " to service offering: " + this._uuidMgr.getUuid(ServiceOffering.class, getServiceOfferingId()); + return "Upgrading Instance with ID: " + getResourceUuid(ApiConstants.ID) + " to service offering with ID: " + getResourceUuid(ApiConstants.SERVICE_OFFERING_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java index af7058d44923..40ae91d4c264 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java @@ -161,7 +161,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Starting User Instance: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); + return "Starting User Instance with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -177,7 +177,7 @@ public Long getApiResourceId() { @Override public void execute() { try { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); UserVm result; result = _userVmService.startVirtualMachine(this); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java index d20f27eb56db..232eeebd34be 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java @@ -96,7 +96,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Stopping User Instance: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); + return "Stopping User Instance with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -115,7 +115,7 @@ public boolean isForced() { @Override public void execute() throws ServerApiException, ConcurrentOperationException { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); UserVm result; result = _userVmService.stopVirtualMachine(getId(), isForced()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java index 591d3871493e..011edb1a9df4 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java @@ -19,8 +19,6 @@ import java.util.ArrayList; import java.util.EnumSet; -import com.cloud.vm.Nic; - import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -90,7 +88,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Updating NIC " + this._uuidMgr.getUuid(Nic.class, getNicId()) + " on User Instance: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()); + return "Setting NIC " + getResourceUuid(ApiConstants.NIC_ID) + " as default to User Instance: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID); } @Override @@ -104,7 +102,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()) + " Nic Id: " + this._uuidMgr.getUuid(Nic.class, getNicId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID) + " NIC ID: " + getResourceUuid(ApiConstants.NIC_ID)); UserVm result = _userVmService.updateDefaultNicForVirtualMachine(this); ArrayList dc = new ArrayList(); dc.add(VMDetails.valueOf("nics")); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java index 115b37d61d17..e3ad0502f454 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java @@ -313,7 +313,7 @@ public long getEntityOwnerId() { @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException { - CallContext.current().setEventDetails("Instance Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("Instance ID: " + ApiConstants.ID); UserVm result = null; try { result = _userVmService.updateVirtualMachine(this); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java index f8ca0b7afea0..6da34c7ef0b0 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java @@ -53,7 +53,7 @@ public class UpdateVmNicIpCmd extends BaseAsyncCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// @Parameter(name=ApiConstants.NIC_ID, type=CommandType.UUID, entityType = NicResponse.class, required = true, - description = "The ID of the NIC to which you want to assign private IP") + description = "The ID of the NIC to which you want to assign private IP") private Long nicId; @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = false, @@ -123,7 +123,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Associating IP to NIC id: " + this._uuidMgr.getUuid(Network.class, getNetworkId()) + " in zone " + this._uuidMgr.getUuid(DataCenter.class, getZoneId()); + return "Associating IP to NIC with ID: " + getResourceUuid(ApiConstants.NIC_ID) + " in zone " + this._uuidMgr.getUuid(DataCenter.class, getZoneId()); } ///////////////////////////////////////////////////// @@ -139,7 +139,7 @@ public static String getResultObjectName() { public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { - CallContext.current().setEventDetails("Nic Id: " + getNicId() ); + CallContext.current().setEventDetails("NIC ID: " + getResourceUuid(ApiConstants.NIC_ID)); String ip; if ((ip = getIpaddress()) != null) { if (!NetUtils.isValidIp4(ip)) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java index c45a18d2fa2b..83908802a690 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java @@ -139,7 +139,7 @@ public long getEntityOwnerId() { @Override public void execute() throws ResourceAllocationException { - CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.ID)); ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId); if (serviceOffering == null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java index 6e1a7daf4c23..d3128599b616 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java @@ -34,7 +34,6 @@ import com.cloud.event.EventTypes; import com.cloud.exception.ResourceAllocationException; import com.cloud.uservm.UserVm; -import com.cloud.vm.VirtualMachine; import com.cloud.vm.snapshot.VMSnapshot; @APICommand(name = "createVMSnapshot", description = "Creates Snapshot for an Instance.", responseObject = VMSnapshotResponse.class, since = "4.2.0", entityType = {VMSnapshot.class}, @@ -105,7 +104,7 @@ public void create() throws ResourceAllocationException { @Override public String getEventDescription() { - return "Creating Snapshot for Instance: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()); + return "Creating Snapshot for Instance: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID); } @Override @@ -115,7 +114,7 @@ public String getEventType() { @Override public void execute() { - CallContext.current().setEventDetails("VM Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId())); + CallContext.current().setEventDetails("Instance ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID)); VMSnapshot result = _vmSnapshotService.createVMSnapshot(getVmId(), getEntityId(), getQuiescevm()); if (result != null) { VMSnapshotResponse response = _responseGenerator.createVMSnapshotResponse(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java index afd63e8e64be..3373ac534cc8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java @@ -62,7 +62,7 @@ public long getEntityOwnerId() { @Override public void execute() { - CallContext.current().setEventDetails("vmsnapshot id: " + this._uuidMgr.getUuid(VMSnapshot.class, getId())); + CallContext.current().setEventDetails("Instance Snapshot ID: " + getResourceUuid(ApiConstants.VM_SNAPSHOT_ID)); boolean result = _vmSnapshotService.deleteVMSnapshot(getId()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); @@ -74,7 +74,7 @@ public void execute() { @Override public String getEventDescription() { - return "Delete Instance Snapshot: " + this._uuidMgr.getUuid(VMSnapshot.class, getId()); + return "Deleting Instance Snapshot with ID: " + getResourceUuid(ApiConstants.VM_SNAPSHOT_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToVMSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToVMSnapshotCmd.java index 43f20362e98d..d44cefca5027 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToVMSnapshotCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToVMSnapshotCmd.java @@ -74,7 +74,7 @@ public long getEntityOwnerId() { @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException, ConcurrentOperationException { - CallContext.current().setEventDetails("vmsnapshot id: " + this._uuidMgr.getUuid(VMSnapshot.class, getVmSnapShotId())); + CallContext.current().setEventDetails("Instance Snapshot ID: " + getResourceUuid(ApiConstants.VM_SNAPSHOT_ID)); UserVm result = _vmSnapshotService.revertToSnapshot(getVmSnapShotId()); if (result != null) { UserVmResponse response = _responseGenerator.createUserVmResponse(getResponseView(), @@ -88,7 +88,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacity @Override public String getEventDescription() { - return "Revert from Instance Snapshot: " + this._uuidMgr.getUuid(VMSnapshot.class, getVmSnapShotId()); + return "Reverting from Instance Snapshot with ID: " + getResourceUuid(ApiConstants.VM_SNAPSHOT_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java index b1e58bb6ef63..9e1c1056fdf9 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java @@ -90,7 +90,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "adding details to the resource "; + return "Adding details to the resource "; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java index 23fbc0fa0c75..8624043afc51 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java @@ -111,12 +111,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "Attaching volume: " + this._uuidMgr.getUuid(Volume.class, getId()) + " to Instance: " + this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId()); + return "Attaching volume with ID: " + getResourceUuid(ApiConstants.ID) + " to Instance with ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID); } @Override public void execute() { - CallContext.current().setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, getId()) + " Instance Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId())); + CallContext.current().setEventDetails("Volume ID: " + getResourceUuid(ApiConstants.ID) + " Instance ID: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID)); Volume result = _volumeService.attachVolumeToVM(this); if (result != null) { VolumeResponse response = _responseGenerator.createVolumeResponse(getResponseView(), result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ChangeOfferingForVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ChangeOfferingForVolumeCmd.java index 77c30aa6be92..c8cda7e1c19c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ChangeOfferingForVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ChangeOfferingForVolumeCmd.java @@ -22,7 +22,6 @@ import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.offering.DiskOffering; import com.cloud.storage.Volume; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; @@ -130,12 +129,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "Changing Disk offering of Volume Id: " + this._uuidMgr.getUuid(Volume.class, getId()) + " to " + this._uuidMgr.getUuid(DiskOffering.class, getNewDiskOfferingId()); + return "Changing disk offering of volume with ID: " + getResourceUuid(ApiConstants.ID) + " to " + getResourceUuid(ApiConstants.DISK_OFFERING_ID); } @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { - CallContext.current().setEventDetails("Volume Id: " + getId()); + CallContext.current().setEventDetails("Volume ID: " + getResourceUuid(ApiConstants.ID)); Volume result = _volumeService.changeDiskOfferingForVolume(this); if (result != null) { VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseObject.ResponseView.Restricted, result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/CheckAndRepairVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/CheckAndRepairVolumeCmd.java index 56fdf6bc126c..fdbd4a61c072 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/CheckAndRepairVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/CheckAndRepairVolumeCmd.java @@ -105,7 +105,7 @@ public String getEventType() { @Override public String getEventDescription() { - return String.format("check and repair operation on volume: %s", this._uuidMgr.getUuid(Volume.class, getId())); + return "Starting checking and repairing operation on volume: " + getResourceUuid(ApiConstants.ID); } @Override @@ -120,7 +120,7 @@ public ApiCommandResourceType getApiResourceType() { @Override public void execute() throws ResourceAllocationException { - CallContext.current().setEventDetails("Volume Id: " + getId()); + CallContext.current().setEventDetails("Volume ID: " + getResourceUuid(ApiConstants.ID)); Pair result = _volumeService.checkAndRepairVolume(this); Volume volume = _responseGenerator.findVolumeById(getId()); if (result != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java index 5938bdb810f5..5bcf3a141178 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java @@ -203,7 +203,17 @@ public String getEventType() { @Override public String getEventDescription() { - return "Creating volume: " + getVolumeName() + ((getSnapshotId() == null) ? "" : " from Snapshot: " + this._uuidMgr.getUuid(Snapshot.class, getSnapshotId())); + String description = "Creating volume "; + + if (getVolumeName() != null) { + description += getVolumeName(); + } + + if (getSnapshotId() != null) { + description += " from Snapshot: " + getResourceUuid(ApiConstants.SNAPSHOT_ID); + } + + return description; } @Override @@ -220,7 +230,7 @@ public void create() throws ResourceAllocationException { @Override public void execute() { - CallContext.current().setEventDetails("Volume Id: " + getEntityUuid() + ((getSnapshotId() == null) ? "" : " from Snapshot: " + this._uuidMgr.getUuid(Snapshot.class, getSnapshotId()))); + CallContext.current().setEventDetails("Volume ID: " + getEntityUuid() + ((getSnapshotId() == null) ? "" : " from Snapshot with ID: " + getResourceUuid(ApiConstants.SNAPSHOT_ID))); Volume volume = _volumeService.createVolume(this); if (volume != null) { VolumeResponse response = _responseGenerator.createVolumeResponse(getResponseView(), volume); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java index e21103654c81..e102d51f0378 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java @@ -84,7 +84,7 @@ public ApiCommandResourceType getApiResourceType() { @Override public void execute() throws ConcurrentOperationException { - CallContext.current().setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, getId())); + CallContext.current().setEventDetails("Volume ID: " + getResourceUuid(ApiConstants.ID)); Volume result = _volumeService.destroyVolume(id, CallContext.current().getCallingAccount(), true, false); if (result != null) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DestroyVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DestroyVolumeCmd.java index 32ddec880861..12a44f76ea15 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DestroyVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DestroyVolumeCmd.java @@ -100,7 +100,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "destroying volume: " + getId(); + return "Destroying volume with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -115,7 +115,7 @@ public Long getApiResourceId() { @Override public void execute() { - CallContext.current().setEventDetails("Volume Id: " + getId()); + CallContext.current().setEventDetails("Volume ID: " + getResourceUuid(ApiConstants.ID)); Volume result = _volumeService.destroyVolume(getId(), CallContext.current().getCallingAccount(), getExpunge(), false); if (result != null) { VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java index 9c8b8fcf6e67..66a558abf982 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java @@ -38,7 +38,7 @@ import com.cloud.uservm.UserVm; import com.cloud.vm.VirtualMachine; -@APICommand(name = "detachVolume", description = "Detaches a disk volume from an Instance.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, +@APICommand(name = "detachVolume", description = "Detaches a disk volume from an Instance.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DetachVolumeCmd extends BaseAsyncCmd implements UserCmd { private static final String s_name = "detachvolumeresponse"; @@ -126,15 +126,19 @@ public String getEventType() { @Override public String getEventDescription() { - StringBuilder sb = new StringBuilder(); + String description = "Detaching volume"; + if (id != null) { - sb.append(": " + this._uuidMgr.getUuid(Volume.class, id)); - } else if ((deviceId != null) && (virtualMachineId != null)) { - sb.append(" with device id: " + deviceId + " from Instance: " + ((getVirtualMachineId() != null) ? this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId()) : "" )); + description += ": " + getResourceUuid(ApiConstants.ID); + } + + if ((deviceId != null) && (virtualMachineId != null)) { + description += " with device id: " + deviceId + " from Instance: " + getResourceUuid(ApiConstants.VIRTUAL_MACHINE_ID); } else { - sb.append(" "); + description += " "; } - return "detaching volume" + sb.toString(); + + return description; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java index 2b225f4fd347..f50d23a6b60c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java @@ -16,8 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.user.volume; - -import com.cloud.dc.DataCenter; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; @@ -115,10 +113,7 @@ public String getEventType() { @Override public String getEventDescription() { - String volumeId = this._uuidMgr.getUuid(Volume.class, getId()); - String zoneId = this._uuidMgr.getUuid(DataCenter.class, getZoneId()); - - return String.format("Extracting volume: %s from zone: %s", volumeId, zoneId); + return "Extracting volume with ID: " + getResourceUuid(ApiConstants.ID) + " from zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java index ea6890ac3e82..9927978ad55e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java @@ -30,7 +30,6 @@ import org.apache.cloudstack.api.response.VolumeResponse; import com.cloud.event.EventTypes; -import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; import com.cloud.user.Account; @@ -110,7 +109,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Attempting to migrate volume Id: " + this._uuidMgr.getUuid(Volume.class, getVolumeId()) + " to storage pool Id: " + this._uuidMgr.getUuid(StoragePool.class, getStoragePoolId()); + return "Attempting to migrate volume with ID: " + getResourceUuid(ApiConstants.VOLUME_ID) + " to storage pool: " + getResourceUuid(ApiConstants.STORAGE_ID); } public Long getNewDiskOfferingId() { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/RecoverVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/RecoverVolumeCmd.java index cd5a7735e382..4d6be7270afb 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/RecoverVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/RecoverVolumeCmd.java @@ -87,7 +87,7 @@ public ApiCommandResourceType getApiResourceType() { @Override public void execute() { - CallContext.current().setEventDetails("Volume Id: " + getId()); + CallContext.current().setEventDetails("Volume ID: " + getResourceUuid(ApiConstants.ID)); Volume result = _volumeService.recoverVolume(getId()); if (result != null) { VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java index 5b2b6709cf64..f8f744285c04 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java @@ -190,11 +190,13 @@ public String getEventType() { @Override public String getEventDescription() { + String baseDescription = "Resizing volume with ID: " + getResourceUuid(ApiConstants.ID); + if (getSize() != null) { - return "Volume Id: " + this._uuidMgr.getUuid(Volume.class, getEntityId()) + " to size " + getSize() + " GB"; - } else { - return "Volume Id: " + this._uuidMgr.getUuid(Volume.class, getEntityId()); + baseDescription = baseDescription + " to size " + getSize() + " GB."; } + + return baseDescription; } @Override @@ -202,9 +204,9 @@ public void execute() { Volume volume = null; try { if (size != null) { - CallContext.current().setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, getEntityId()) + " to size " + getSize() + " GB"); + CallContext.current().setEventDetails("Volume ID: " + getResourceUuid(ApiConstants.ID) + " to size " + getSize() + " GB"); } else { - CallContext.current().setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, getEntityId())); + CallContext.current().setEventDetails("Volume ID: " + getResourceUuid(ApiConstants.ID)); } volume = _volumeService.resizeVolume(this); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java index 0d3fc59a5285..00c50fa5ffff 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java @@ -178,7 +178,7 @@ public String getEventDescription() { @Override public void execute() { - CallContext.current().setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, getId())); + CallContext.current().setEventDetails("Volume ID: " + getResourceUuid(ApiConstants.ID)); Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId(), getDisplayVolume(), getDeleteProtection(), getCustomId(), getEntityOwnerId(), getChainInfo(), getName()); if (result != null) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java index 81077deff654..33a9251e094f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java @@ -32,7 +32,6 @@ import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.context.CallContext; -import com.cloud.dc.DataCenter; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; @@ -169,7 +168,7 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - return "uploading volume: " + getVolumeName() + " in the zone " + this._uuidMgr.getUuid(DataCenter.class, getZoneId()); + return "Uploading volume: " + getVolumeName() + " to zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java index 1605e4830bd1..11930bcbab61 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java @@ -116,7 +116,7 @@ public void execute() throws ResourceUnavailableException { boolean success = false; StaticRoute route = null; try { - CallContext.current().setEventDetails("Static route Id: " + getEntityId()); + CallContext.current().setEventDetails("Static route ID: " + getEntityUuid()); success = _vpcService.applyStaticRoute(getEntityId()); // State is different after the route is applied, so retrieve the object only here route = _entityMgr.findById(StaticRoute.class, getEntityId()); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/DeleteStaticRouteCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/DeleteStaticRouteCmd.java index 532a4108076c..cf1805973b77 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/DeleteStaticRouteCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/DeleteStaticRouteCmd.java @@ -69,7 +69,7 @@ public String getEventType() { @Override public String getEventDescription() { - return ("Deleting static route id=" + id); + return "Deleting static route with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -87,7 +87,7 @@ public long getEntityOwnerId() { @Override public void execute() throws ResourceUnavailableException { - CallContext.current().setEventDetails("Route Id: " + id); + CallContext.current().setEventDetails("Route ID: " + getResourceUuid(ApiConstants.ID)); boolean result = _vpcService.revokeStaticRoute(id); if (result) { diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/DeleteVPCCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/DeleteVPCCmd.java index ccaac2b1e29b..e42b4761ea8f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/DeleteVPCCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/DeleteVPCCmd.java @@ -65,7 +65,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting VPC id=" + getId(); + return "Deleting VPC with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java index 9dadf061753a..f6a408a66a3d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java @@ -118,7 +118,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "restarting VPC id=" + getId(); + return "Restarting VPC with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java index 88e38649802b..f2327c9073f3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java @@ -143,7 +143,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "updating VPC id=" + getId(); + return "Updating VPC " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java index 533d2c0ab814..665f699c4ef3 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java @@ -106,7 +106,7 @@ public String getEventType() { @Override public void execute() { - CallContext.current().setEventDetails("VPN gateway Id: " + getEntityId()); + CallContext.current().setEventDetails("VPN gateway ID: " + getEntityUuid()); Site2SiteVpnGateway result = _s2sVpnService.getVpnGateway(getEntityId()); if (result != null) { Site2SiteVpnGatewayResponse response = _responseGenerator.createSite2SiteVpnGatewayResponse(result); diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java index 91e1cd1e56c7..b1fc331f4c3a 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java @@ -76,7 +76,7 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - return "Delete Remote Access VPN for Account " + getEntityOwnerId() + " for ip id=" + publicIpId; + return "Delete Remote Access VPN for Account " + getEntityOwnerId() + " for IP: " + getResourceUuid(ApiConstants.PUBLIC_IP_ID); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnConnectionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnConnectionCmd.java index f66fe237a996..b23e6c163020 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnConnectionCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnConnectionCmd.java @@ -65,7 +65,7 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - return "Delete site-to-site VPN connection for Account " + getEntityOwnerId(); + return "Deleting site-to-site VPN connection for Account " + getEntityOwnerId(); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnCustomerGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnCustomerGatewayCmd.java index 0d43477205ec..9057620e0ddb 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnCustomerGatewayCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnCustomerGatewayCmd.java @@ -72,7 +72,7 @@ public long getEntityOwnerId() { @Override public String getEventDescription() { - return "Delete site-to-site VPN customer gateway for Account " + getEntityOwnerId(); + return "Deleting site-to-site VPN customer gateway for Account " + getEntityOwnerId(); } @Override diff --git a/api/src/main/java/org/apache/cloudstack/context/CallContext.java b/api/src/main/java/org/apache/cloudstack/context/CallContext.java index 4cefd7847fdd..5e0c60184f4f 100644 --- a/api/src/main/java/org/apache/cloudstack/context/CallContext.java +++ b/api/src/main/java/org/apache/cloudstack/context/CallContext.java @@ -63,6 +63,7 @@ protected Stack initialValue() { private User user; private long userId; private final Map context = new HashMap(); + private final Map apiResourcesUuids = new HashMap<>(); private Project project; private String apiName; @@ -388,6 +389,14 @@ public void setEventDisplayEnabled(boolean eventDisplayEnabled) { isEventDisplayEnabled = eventDisplayEnabled; } + public UUID getApiResourceUuid(String paramName) { + return apiResourcesUuids.get(paramName); + } + + public void putApiResourceUuid(String paramName, UUID uuid) { + apiResourcesUuids.put(paramName, uuid); + } + public Map getContextParameters() { return context; } diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmdTest.java index e1393e316993..4039ca6dc948 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmdTest.java @@ -20,6 +20,7 @@ import com.cloud.event.EventTypes; import org.apache.cloudstack.api.response.Ipv4SubnetForGuestNetworkResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.Ipv4GuestSubnetNetworkMap; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; @@ -29,6 +30,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class CreateIpv4SubnetForGuestNetworkCmdTest { @@ -37,6 +40,7 @@ public class CreateIpv4SubnetForGuestNetworkCmdTest { @Test public void testCreateIpv4SubnetForGuestNetworkCmd() { Long parentId = 1L; + UUID parentUuid = UUID.randomUUID(); String subnet = "192.168.1.0/24"; Integer cidrSize = 26; @@ -46,12 +50,14 @@ public void testCreateIpv4SubnetForGuestNetworkCmd() { ReflectionTestUtils.setField(cmd, "cidrSize", cidrSize); ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); + CallContext.current().putApiResourceUuid("parentid", parentUuid); + Assert.assertEquals(parentId, cmd.getParentId()); Assert.assertEquals(subnet, cmd.getSubnet()); Assert.assertEquals(cidrSize, cmd.getCidrSize()); Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_IP4_GUEST_SUBNET_CREATE, cmd.getEventType()); - Assert.assertEquals(String.format("Creating guest IPv4 subnet %s in zone subnet=%s", subnet, parentId), cmd.getEventDescription()); + Assert.assertEquals(String.format("Creating guest IPv4 subnet %s in zone subnet: %s", subnet, parentUuid), cmd.getEventDescription()); Ipv4GuestSubnetNetworkMap ipv4GuestSubnetNetworkMap = Mockito.mock(Ipv4GuestSubnetNetworkMap.class); Mockito.when(routedIpv4Manager.createIpv4SubnetForGuestNetwork(cmd)).thenReturn(ipv4GuestSubnetNetworkMap); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmdTest.java index 51c1eb986c47..bb324aca0e70 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmdTest.java @@ -20,6 +20,7 @@ import com.cloud.event.EventTypes; import org.apache.cloudstack.api.response.DataCenterIpv4SubnetResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.datacenter.DataCenterIpv4GuestSubnet; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; @@ -29,6 +30,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class CreateIpv4SubnetForZoneCmdTest { @@ -37,6 +40,7 @@ public class CreateIpv4SubnetForZoneCmdTest { @Test public void testCreateIpv4SubnetForZoneCmd() { Long zoneId = 1L; + UUID zoneUuid = UUID.randomUUID(); String subnet = "192.168.1.0/24"; String accountName = "user"; Long projectId = 10L; @@ -50,6 +54,8 @@ public void testCreateIpv4SubnetForZoneCmd() { ReflectionTestUtils.setField(cmd,"domainId", domainId); ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); + CallContext.current().putApiResourceUuid("zoneid", zoneUuid); + Assert.assertEquals(zoneId, cmd.getZoneId()); Assert.assertEquals(subnet, cmd.getSubnet()); Assert.assertEquals(accountName, cmd.getAccountName()); @@ -57,7 +63,7 @@ public void testCreateIpv4SubnetForZoneCmd() { Assert.assertEquals(domainId, cmd.getDomainId()); Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_ZONE_IP4_SUBNET_CREATE, cmd.getEventType()); - Assert.assertEquals(String.format("Creating guest IPv4 subnet %s for zone=%s", subnet, zoneId), cmd.getEventDescription()); + Assert.assertEquals(String.format("Creating guest IPv4 subnet %s for zone: %s", subnet, zoneUuid), cmd.getEventDescription()); DataCenterIpv4GuestSubnet zoneSubnet = Mockito.mock(DataCenterIpv4GuestSubnet.class); Mockito.when(routedIpv4Manager.createDataCenterIpv4GuestSubnet(cmd)).thenReturn(zoneSubnet); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmdTest.java index 7db77098b233..31458d2833fa 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmdTest.java @@ -19,6 +19,7 @@ import com.cloud.event.EventTypes; import org.apache.cloudstack.api.response.DataCenterIpv4SubnetResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.datacenter.DataCenterIpv4GuestSubnet; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; @@ -28,6 +29,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class DedicateIpv4SubnetForZoneCmdTest { @@ -36,6 +39,7 @@ public class DedicateIpv4SubnetForZoneCmdTest { @Test public void testDedicateIpv4SubnetForZoneCmd() { Long id = 1L; + UUID uuid = UUID.randomUUID(); String accountName = "user"; Long projectId = 10L; Long domainId = 11L; @@ -47,6 +51,8 @@ public void testDedicateIpv4SubnetForZoneCmd() { ReflectionTestUtils.setField(cmd,"domainId", domainId); ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); + CallContext.current().putApiResourceUuid("id", uuid); + Assert.assertEquals(id, cmd.getId()); Assert.assertEquals(accountName, cmd.getAccountName()); Assert.assertEquals(projectId, cmd.getProjectId()); @@ -54,7 +60,7 @@ public void testDedicateIpv4SubnetForZoneCmd() { Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_ZONE_IP4_SUBNET_DEDICATE, cmd.getEventType()); - Assert.assertEquals(String.format("Dedicating zone IPv4 subnet %s", id), cmd.getEventDescription()); + Assert.assertEquals(String.format("Dedicating zone's IPv4 subnet with ID: %s", uuid), cmd.getEventDescription()); DataCenterIpv4GuestSubnet zoneSubnet = Mockito.mock(DataCenterIpv4GuestSubnet.class); Mockito.when(routedIpv4Manager.dedicateDataCenterIpv4GuestSubnet(cmd)).thenReturn(zoneSubnet); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmdTest.java index a4af5ddf748f..48aceeaaeec1 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmdTest.java @@ -20,6 +20,7 @@ import com.cloud.event.EventTypes; import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; import org.junit.Test; @@ -28,6 +29,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class DeleteIpv4SubnetForGuestNetworkCmdTest { @@ -36,15 +39,18 @@ public class DeleteIpv4SubnetForGuestNetworkCmdTest { @Test public void testDeleteIpv4SubnetForGuestNetworkCmd() { Long id = 1L; + UUID uuid = UUID.randomUUID(); DeleteIpv4SubnetForGuestNetworkCmd cmd = new DeleteIpv4SubnetForGuestNetworkCmd(); ReflectionTestUtils.setField(cmd, "id", id); ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); + CallContext.current().putApiResourceUuid("id", uuid); + Assert.assertEquals(id, cmd.getId()); Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_IP4_GUEST_SUBNET_DELETE, cmd.getEventType()); - Assert.assertEquals(String.format("Deleting guest IPv4 subnet %s", id), cmd.getEventDescription()); + Assert.assertEquals(String.format("Deleting guest IPv4 subnet with ID: %s", uuid), cmd.getEventDescription()); Mockito.when(routedIpv4Manager.deleteIpv4SubnetForGuestNetwork(cmd)).thenReturn(true); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmdTest.java index 7af173f09d96..5c3593a8f1b6 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmdTest.java @@ -20,6 +20,7 @@ import com.cloud.event.EventTypes; import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; import org.junit.Test; @@ -28,6 +29,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class DeleteIpv4SubnetForZoneCmdTest { @@ -36,15 +39,18 @@ public class DeleteIpv4SubnetForZoneCmdTest { @Test public void testDeleteIpv4SubnetForZoneCmd() { Long id = 1L; + UUID uuid = UUID.randomUUID(); DeleteIpv4SubnetForZoneCmd cmd = new DeleteIpv4SubnetForZoneCmd(); ReflectionTestUtils.setField(cmd, "id", id); ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); + CallContext.current().putApiResourceUuid("id", uuid); + Assert.assertEquals(id, cmd.getId()); Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_ZONE_IP4_SUBNET_DELETE, cmd.getEventType()); - Assert.assertEquals(String.format("Deleting zone IPv4 subnet %s", id), cmd.getEventDescription()); + Assert.assertEquals(String.format("Deleting zone IPv4 subnet with ID: %s", uuid), cmd.getEventDescription()); Mockito.when(routedIpv4Manager.deleteDataCenterIpv4GuestSubnet(cmd)).thenReturn(true); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedIpv4SubnetForZoneCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedIpv4SubnetForZoneCmdTest.java index 9ce9a4f9464f..29d6d8e735bb 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedIpv4SubnetForZoneCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedIpv4SubnetForZoneCmdTest.java @@ -19,6 +19,7 @@ import com.cloud.event.EventTypes; import org.apache.cloudstack.api.response.DataCenterIpv4SubnetResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.datacenter.DataCenterIpv4GuestSubnet; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; @@ -28,6 +29,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class ReleaseDedicatedIpv4SubnetForZoneCmdTest { @@ -36,15 +39,18 @@ public class ReleaseDedicatedIpv4SubnetForZoneCmdTest { @Test public void testReleaseDedicatedIpv4SubnetForZoneCmd() { Long id = 1L; + UUID uuid = UUID.randomUUID(); ReleaseDedicatedIpv4SubnetForZoneCmd cmd = new ReleaseDedicatedIpv4SubnetForZoneCmd(); ReflectionTestUtils.setField(cmd, "id", id); ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); + CallContext.current().putApiResourceUuid("id", uuid); + Assert.assertEquals(id, cmd.getId()); Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_ZONE_IP4_SUBNET_RELEASE, cmd.getEventType()); - Assert.assertEquals(String.format("Releasing a dedicated zone IPv4 subnet %s", id), cmd.getEventDescription()); + Assert.assertEquals(String.format("Releasing dedicated zone IPv4 subnet with ID: %s", uuid), cmd.getEventDescription()); DataCenterIpv4GuestSubnet zoneSubnet = Mockito.mock(DataCenterIpv4GuestSubnet.class); Mockito.when(routedIpv4Manager.releaseDedicatedDataCenterIpv4GuestSubnet(cmd)).thenReturn(zoneSubnet); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/UpdateIpv4SubnetForZoneCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/UpdateIpv4SubnetForZoneCmdTest.java index cdb9cce22d83..399b77de6e85 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/UpdateIpv4SubnetForZoneCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/UpdateIpv4SubnetForZoneCmdTest.java @@ -20,6 +20,7 @@ import com.cloud.event.EventTypes; import org.apache.cloudstack.api.response.DataCenterIpv4SubnetResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.datacenter.DataCenterIpv4GuestSubnet; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; @@ -29,6 +30,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class UpdateIpv4SubnetForZoneCmdTest { @@ -37,6 +40,7 @@ public class UpdateIpv4SubnetForZoneCmdTest { @Test public void testUpdateIpv4SubnetForZoneCmd() { Long id = 1L; + UUID uuid = UUID.randomUUID(); String subnet = "192.168.1.0/24"; UpdateIpv4SubnetForZoneCmd cmd = new UpdateIpv4SubnetForZoneCmd(); @@ -44,11 +48,13 @@ public void testUpdateIpv4SubnetForZoneCmd() { ReflectionTestUtils.setField(cmd, "subnet", subnet); ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); + CallContext.current().putApiResourceUuid("id", uuid); + Assert.assertEquals(id, cmd.getId()); Assert.assertEquals(subnet, cmd.getSubnet()); Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_ZONE_IP4_SUBNET_UPDATE, cmd.getEventType()); - Assert.assertEquals(String.format("Updating zone IPv4 subnet %s", id), cmd.getEventDescription()); + Assert.assertEquals(String.format("Updating zone IPv4 subnet with ID: %s", uuid), cmd.getEventDescription()); DataCenterIpv4GuestSubnet zoneSubnet = Mockito.mock(DataCenterIpv4GuestSubnet.class); Mockito.when(routedIpv4Manager.updateDataCenterIpv4GuestSubnet(cmd)).thenReturn(zoneSubnet); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForNetworkCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForNetworkCmdTest.java index 28ddad17afe5..9cd403ddd1de 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForNetworkCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForNetworkCmdTest.java @@ -23,6 +23,7 @@ import org.apache.cloudstack.api.ResponseGenerator; import org.apache.cloudstack.api.ResponseObject; import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; import org.junit.Test; @@ -33,6 +34,7 @@ import java.util.Arrays; import java.util.List; +import java.util.UUID; @RunWith(MockitoJUnitRunner.class) public class ChangeBgpPeersForNetworkCmdTest { @@ -44,6 +46,7 @@ public class ChangeBgpPeersForNetworkCmdTest { @Test public void testChangeBgpPeersForNetworkCmd() { Long networkId = 10L; + UUID networkUuid = UUID.randomUUID(); List bgpPeerIds = Arrays.asList(20L, 21L); ChangeBgpPeersForNetworkCmd cmd = new ChangeBgpPeersForNetworkCmd(); @@ -52,11 +55,13 @@ public void testChangeBgpPeersForNetworkCmd() { ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); ReflectionTestUtils.setField(cmd,"_responseGenerator", _responseGenerator); + CallContext.current().putApiResourceUuid("networkid", networkUuid); + Assert.assertEquals(networkId, cmd.getNetworkId()); Assert.assertEquals(bgpPeerIds, cmd.getBgpPeerIds()); Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_NETWORK_BGP_PEER_UPDATE, cmd.getEventType()); - Assert.assertEquals(String.format("Changing Bgp Peers for network %s", networkId), cmd.getEventDescription()); + Assert.assertEquals(String.format("Changing BGP Peers for Network with ID: %s", networkUuid), cmd.getEventDescription()); Network network = Mockito.mock(Network.class); Mockito.when(routedIpv4Manager.changeBgpPeersForNetwork(cmd)).thenReturn(network); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForVpcCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForVpcCmdTest.java index 96eb1f020de2..545523e3ab97 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForVpcCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/ChangeBgpPeersForVpcCmdTest.java @@ -23,6 +23,7 @@ import org.apache.cloudstack.api.ResponseGenerator; import org.apache.cloudstack.api.ResponseObject; import org.apache.cloudstack.api.response.VpcResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; import org.junit.Test; @@ -33,6 +34,7 @@ import java.util.Arrays; import java.util.List; +import java.util.UUID; @RunWith(MockitoJUnitRunner.class) public class ChangeBgpPeersForVpcCmdTest { @@ -44,6 +46,7 @@ public class ChangeBgpPeersForVpcCmdTest { @Test public void testChangeBgpPeersForVpcCmd() { Long VpcId = 10L; + UUID vpcUuid = UUID.randomUUID(); List bgpPeerIds = Arrays.asList(20L, 21L); ChangeBgpPeersForVpcCmd cmd = new ChangeBgpPeersForVpcCmd(); @@ -52,11 +55,13 @@ public void testChangeBgpPeersForVpcCmd() { ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); ReflectionTestUtils.setField(cmd,"_responseGenerator", _responseGenerator); + CallContext.current().putApiResourceUuid("vpcid", vpcUuid); + Assert.assertEquals(VpcId, cmd.getVpcId()); Assert.assertEquals(bgpPeerIds, cmd.getBgpPeerIds()); Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_VPC_BGP_PEER_UPDATE, cmd.getEventType()); - Assert.assertEquals(String.format("Changing Bgp Peers for VPC %s", VpcId), cmd.getEventDescription()); + Assert.assertEquals(String.format("Changing BGP Peers for VPC with ID: %s", vpcUuid), cmd.getEventDescription()); Vpc Vpc = Mockito.mock(Vpc.class); Mockito.when(routedIpv4Manager.changeBgpPeersForVpc(cmd)).thenReturn(Vpc); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmdTest.java index 0d802bf36199..866824f62936 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/CreateBgpPeerCmdTest.java @@ -20,6 +20,7 @@ import com.cloud.event.EventTypes; import org.apache.cloudstack.api.response.BgpPeerResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.BgpPeer; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; @@ -29,6 +30,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class CreateBgpPeerCmdTest { @@ -37,6 +40,7 @@ public class CreateBgpPeerCmdTest { @Test public void testCreateBgpPeerCmd() { Long zoneId = 1L; + UUID zoneUuid = UUID.randomUUID(); String accountName = "user"; Long projectId = 10L; Long domainId = 11L; @@ -56,6 +60,8 @@ public void testCreateBgpPeerCmd() { ReflectionTestUtils.setField(cmd,"domainId", domainId); ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); + CallContext.current().putApiResourceUuid("zoneid", zoneUuid); + Assert.assertEquals(zoneId, cmd.getZoneId()); Assert.assertEquals(ip4Address, cmd.getIp4Address()); Assert.assertEquals(ip6Address, cmd.getIp6Address()); @@ -67,7 +73,7 @@ public void testCreateBgpPeerCmd() { Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_BGP_PEER_CREATE, cmd.getEventType()); - Assert.assertEquals(String.format("Creating Bgp Peer %s for zone=%s", peerAsNumber, zoneId), cmd.getEventDescription()); + Assert.assertEquals(String.format("Creating BGP Peer %s for zone with ID: %s", peerAsNumber, zoneUuid), cmd.getEventDescription()); BgpPeer bgpPeer = Mockito.mock(BgpPeer.class); Mockito.when(routedIpv4Manager.createBgpPeer(cmd)).thenReturn(bgpPeer); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/DedicateBgpPeerCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/DedicateBgpPeerCmdTest.java index f3ae007da285..a8046d3d745c 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/DedicateBgpPeerCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/DedicateBgpPeerCmdTest.java @@ -19,6 +19,7 @@ import com.cloud.event.EventTypes; import org.apache.cloudstack.api.response.BgpPeerResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.BgpPeer; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; @@ -28,6 +29,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class DedicateBgpPeerCmdTest { @@ -36,6 +39,7 @@ public class DedicateBgpPeerCmdTest { @Test public void testDedicateBgpPeerCmd() { Long id = 1L; + UUID uuid = UUID.randomUUID(); String accountName = "user"; Long projectId = 10L; Long domainId = 11L; @@ -47,6 +51,8 @@ public void testDedicateBgpPeerCmd() { ReflectionTestUtils.setField(cmd,"domainId", domainId); ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); + CallContext.current().putApiResourceUuid("id", uuid); + Assert.assertEquals(id, cmd.getId()); Assert.assertEquals(accountName, cmd.getAccountName()); Assert.assertEquals(projectId, cmd.getProjectId()); @@ -54,7 +60,7 @@ public void testDedicateBgpPeerCmd() { Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_BGP_PEER_DEDICATE, cmd.getEventType()); - Assert.assertEquals(String.format("Dedicating Bgp Peer %s", id), cmd.getEventDescription()); + Assert.assertEquals(String.format("Dedicating BGP Peer with ID: %s", uuid), cmd.getEventDescription()); BgpPeer bgpPeer = Mockito.mock(BgpPeer.class); Mockito.when(routedIpv4Manager.dedicateBgpPeer(cmd)).thenReturn(bgpPeer); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/DeleteBgpPeerCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/DeleteBgpPeerCmdTest.java index 5e747188fda3..d54be9e859e4 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/DeleteBgpPeerCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/DeleteBgpPeerCmdTest.java @@ -20,6 +20,7 @@ import com.cloud.event.EventTypes; import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; import org.junit.Test; @@ -28,6 +29,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class DeleteBgpPeerCmdTest { @@ -36,15 +39,18 @@ public class DeleteBgpPeerCmdTest { @Test public void testDeleteBgpPeerCmd() { Long id = 1L; + UUID uuid = UUID.randomUUID(); DeleteBgpPeerCmd cmd = new DeleteBgpPeerCmd(); ReflectionTestUtils.setField(cmd, "id", id); ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); + CallContext.current().putApiResourceUuid("id", uuid); + Assert.assertEquals(id, cmd.getId()); Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_BGP_PEER_DELETE, cmd.getEventType()); - Assert.assertEquals(String.format("Deleting Bgp Peer %s", id), cmd.getEventDescription()); + Assert.assertEquals(String.format("Deleting BGP Peer with ID: %s", uuid), cmd.getEventDescription()); Mockito.when(routedIpv4Manager.deleteBgpPeer(cmd)).thenReturn(true); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/ReleaseDedicatedBgpPeerCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/ReleaseDedicatedBgpPeerCmdTest.java index 8c55c4a73479..1cf8ead706d1 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/ReleaseDedicatedBgpPeerCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/ReleaseDedicatedBgpPeerCmdTest.java @@ -19,6 +19,7 @@ import com.cloud.event.EventTypes; import org.apache.cloudstack.api.response.BgpPeerResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.BgpPeer; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; @@ -28,6 +29,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class ReleaseDedicatedBgpPeerCmdTest { @@ -36,15 +39,18 @@ public class ReleaseDedicatedBgpPeerCmdTest { @Test public void testReleaseDedicatedBgpPeerCmd() { Long id = 1L; + UUID uuid = UUID.randomUUID(); ReleaseDedicatedBgpPeerCmd cmd = new ReleaseDedicatedBgpPeerCmd(); ReflectionTestUtils.setField(cmd, "id", id); ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); + CallContext.current().putApiResourceUuid("id", uuid); + Assert.assertEquals(id, cmd.getId()); Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_BGP_PEER_RELEASE, cmd.getEventType()); - Assert.assertEquals(String.format("Releasing a dedicated Bgp Peer %s", id), cmd.getEventDescription()); + Assert.assertEquals(String.format("Releasing dedicated BGP Peer with ID: %s", uuid), cmd.getEventDescription()); BgpPeer bgpPeer = Mockito.mock(BgpPeer.class); Mockito.when(routedIpv4Manager.releaseDedicatedBgpPeer(cmd)).thenReturn(bgpPeer); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmdTest.java index 003944c61474..1601fcb4c5a5 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/network/bgp/UpdateBgpPeerCmdTest.java @@ -20,6 +20,7 @@ import com.cloud.event.EventTypes; import org.apache.cloudstack.api.response.BgpPeerResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.BgpPeer; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; @@ -29,6 +30,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class UpdateBgpPeerCmdTest { @@ -37,6 +40,7 @@ public class UpdateBgpPeerCmdTest { @Test public void testUpdateBgpPeerCmd() { Long id = 1L; + UUID uuid = UUID.randomUUID(); String ip4Address = "ip4-address"; String ip6Address = "ip6-address"; Long peerAsNumber = 15000L; @@ -50,6 +54,8 @@ public void testUpdateBgpPeerCmd() { ReflectionTestUtils.setField(cmd, "password", peerPassword); ReflectionTestUtils.setField(cmd,"routedIpv4Manager", routedIpv4Manager); + CallContext.current().putApiResourceUuid("id", uuid); + Assert.assertEquals(id, cmd.getId()); Assert.assertEquals(ip4Address, cmd.getIp4Address()); Assert.assertEquals(ip6Address, cmd.getIp6Address()); @@ -57,7 +63,7 @@ public void testUpdateBgpPeerCmd() { Assert.assertEquals(peerPassword, cmd.getPassword()); Assert.assertEquals(1L, cmd.getEntityOwnerId()); Assert.assertEquals(EventTypes.EVENT_BGP_PEER_UPDATE, cmd.getEventType()); - Assert.assertEquals(String.format("Updating Bgp Peer %s", id), cmd.getEventDescription()); + Assert.assertEquals(String.format("Updating BGP Peer with ID: %s", uuid), cmd.getEventDescription()); BgpPeer bgpPeer = Mockito.mock(BgpPeer.class); Mockito.when(routedIpv4Manager.updateBgpPeer(cmd)).thenReturn(bgpPeer); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/storage/DownloadImageStoreObjectCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/storage/DownloadImageStoreObjectCmdTest.java index ad95ce10bd6c..3b2b49cae4e1 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/storage/DownloadImageStoreObjectCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/storage/DownloadImageStoreObjectCmdTest.java @@ -19,6 +19,7 @@ import com.cloud.utils.Pair; import org.apache.cloudstack.api.response.ExtractResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.storage.browser.StorageBrowser; import org.junit.Assert; import org.junit.Test; @@ -30,6 +31,7 @@ import org.springframework.test.util.ReflectionTestUtils; import java.util.List; +import java.util.UUID; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -95,10 +97,13 @@ public void testGetEventType() { @Test public void testGetEventDescription() { + UUID uuid = UUID.randomUUID(); + ReflectionTestUtils.setField(cmd, "storeId", 1L); ReflectionTestUtils.setField(cmd, "path", "path/to/object"); + CallContext.current().putApiResourceUuid("id", uuid); String eventDescription = cmd.getEventDescription(); - Assert.assertEquals("Downloading object at path path/to/object on image store 1", eventDescription); + Assert.assertEquals(String.format("Downloading object at path path/to/object on image store %s", uuid), eventDescription); } } diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/volume/UnmanageVolumeCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/volume/UnmanageVolumeCmdTest.java index ba7e351a8a8e..ecca507a6b95 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/volume/UnmanageVolumeCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/volume/UnmanageVolumeCmdTest.java @@ -22,6 +22,7 @@ import org.apache.cloudstack.api.ApiCommandResourceType; import org.apache.cloudstack.api.ResponseGenerator; import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.storage.volume.VolumeImportUnmanageService; import org.junit.Assert; import org.junit.Test; @@ -31,6 +32,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class UnmanageVolumeCmdTest { @@ -41,6 +44,7 @@ public class UnmanageVolumeCmdTest { public void testUnmanageVolumeCmd() { long accountId = 2L; Long volumeId = 3L; + UUID volumeUuid = UUID.randomUUID(); Volume volume = Mockito.mock(Volume.class); Mockito.when(responseGenerator.findVolumeById(volumeId)).thenReturn(volume); @@ -51,12 +55,14 @@ public void testUnmanageVolumeCmd() { ReflectionTestUtils.setField(cmd,"volumeImportService", volumeImportService); ReflectionTestUtils.setField(cmd,"_responseGenerator", responseGenerator); + CallContext.current().putApiResourceUuid("id", volumeUuid); + Assert.assertEquals(volumeId, cmd.getVolumeId()); Assert.assertEquals(accountId, cmd.getEntityOwnerId()); Assert.assertEquals(volumeId, cmd.getApiResourceId()); Assert.assertEquals(ApiCommandResourceType.Volume, cmd.getApiResourceType()); Assert.assertEquals(EventTypes.EVENT_VOLUME_UNMANAGE, cmd.getEventType()); - Assert.assertEquals("Unmanaging Volume with ID " + volumeId, cmd.getEventDescription()); + Assert.assertEquals("Unmanaging Volume with ID: " + volumeUuid, cmd.getEventDescription()); Mockito.when(volumeImportService.unmanageVolume(volumeId)).thenReturn(true); try { diff --git a/api/src/test/java/org/apache/cloudstack/api/command/test/CreateSnapshotCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/CreateSnapshotCmdTest.java index 8188a2e0bb05..b70efaf9a6c5 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/test/CreateSnapshotCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/test/CreateSnapshotCmdTest.java @@ -25,11 +25,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; import org.apache.cloudstack.api.ResponseGenerator; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotCmd; import org.apache.cloudstack.api.response.SnapshotResponse; +import org.apache.cloudstack.context.CallContext; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -73,11 +75,6 @@ public Long getVolumeId(){ public long getEntityOwnerId(){ return 1L; } - - @Override - protected String getVolumeUuid() { - return "123"; - } }; } @@ -121,6 +118,9 @@ public void testCreateFailure() { AccountService accountService = Mockito.mock(AccountService.class); Account account = Mockito.mock(Account.class); Mockito.when(accountService.getAccount(anyLong())).thenReturn(account); + UUID volumeUuid = UUID.randomUUID(); + + CallContext.current().putApiResourceUuid("volumeid", volumeUuid); VolumeApiService volumeApiService = Mockito.mock(VolumeApiService.class); @@ -137,7 +137,7 @@ public void testCreateFailure() { try { createSnapshotCmd.execute(); } catch (ServerApiException exception) { - Assert.assertEquals("Failed to create Snapshot due to an internal error creating Snapshot for volume 123", exception.getDescription()); + Assert.assertEquals("Failed to create Snapshot due to an internal error creating Snapshot for volume " + volumeUuid, exception.getDescription()); } } diff --git a/api/src/test/java/org/apache/cloudstack/api/command/test/UpdateAutoScaleVmProfileCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/UpdateAutoScaleVmProfileCmdTest.java index da6ed31eaa2a..3409ce053a9f 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/test/UpdateAutoScaleVmProfileCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/test/UpdateAutoScaleVmProfileCmdTest.java @@ -100,7 +100,7 @@ public void verifyUpdateAutoScaleVmProfileCmd() { Assert.assertEquals("updateautoscalevmprofileresponse", updateAutoScaleVmProfileCmd.getCommandName()); Assert.assertEquals(EventTypes.EVENT_AUTOSCALEVMPROFILE_UPDATE, updateAutoScaleVmProfileCmd.getEventType()); - Assert.assertEquals("Updating AutoScale Instance Profile. Instance Profile Id: " + profileId, updateAutoScaleVmProfileCmd.getEventDescription()); + Assert.assertEquals("Updating AutoScale Instance Profile with ID: " + profileId, updateAutoScaleVmProfileCmd.getEventDescription()); } @Test diff --git a/api/src/test/java/org/apache/cloudstack/api/command/test/UpdateConditionCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/UpdateConditionCmdTest.java index 7d6f8dc35b7e..3dfb29dadd3e 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/test/UpdateConditionCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/test/UpdateConditionCmdTest.java @@ -31,12 +31,15 @@ import org.apache.cloudstack.api.command.user.autoscale.UpdateConditionCmd; import org.apache.cloudstack.api.response.ConditionResponse; +import org.apache.cloudstack.context.CallContext; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + import static org.mockito.Mockito.when; public class UpdateConditionCmdTest { @@ -53,6 +56,7 @@ public class UpdateConditionCmdTest { private static final Long threshold = 100L; private static final long accountId = 5L; + private static final UUID conditionUuid = UUID.randomUUID(); @Before public void setUp() { @@ -71,6 +75,8 @@ public void setUp() { ReflectionTestUtils.setField(updateConditionCmd,"relationalOperator", relationalOperator); ReflectionTestUtils.setField(updateConditionCmd,"threshold", threshold); + CallContext.current().putApiResourceUuid("id", conditionUuid); + condition = Mockito.mock(Condition.class); } @@ -83,7 +89,7 @@ public void verifyUpdateConditionCmd() { Assert.assertEquals(ApiCommandResourceType.Condition, updateConditionCmd.getApiResourceType()); Assert.assertEquals("updateconditionresponse", updateConditionCmd.getCommandName()); Assert.assertEquals(EventTypes.EVENT_CONDITION_UPDATE, updateConditionCmd.getEventType()); - Assert.assertEquals("Updating a condition.", updateConditionCmd.getEventDescription()); + Assert.assertEquals("Updating Instance AutoScale condition with ID: " + conditionUuid, updateConditionCmd.getEventDescription()); when(entityMgr.findById(Condition.class, conditionId)).thenReturn(condition); when(condition.getAccountId()).thenReturn(accountId); diff --git a/api/src/test/java/org/apache/cloudstack/api/command/user/network/routing/DeleteRoutingFirewallRuleCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/user/network/routing/DeleteRoutingFirewallRuleCmdTest.java index 2b55d4c6a58d..d3cf5dd6cd68 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/user/network/routing/DeleteRoutingFirewallRuleCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/user/network/routing/DeleteRoutingFirewallRuleCmdTest.java @@ -23,6 +23,7 @@ import org.apache.cloudstack.api.ApiCommandResourceType; import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.RoutedIpv4Manager; import org.junit.Assert; import org.junit.Test; @@ -31,6 +32,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.test.util.ReflectionTestUtils; +import java.util.UUID; + import static org.junit.Assert.assertEquals; @RunWith(MockitoJUnitRunner.class) @@ -46,6 +49,7 @@ public void testProperties() { ReflectionTestUtils.setField(cmd, "_firewallService", _firewallService); long id = 1L; + UUID uuid = UUID.randomUUID(); long accountId = 2L; long networkId = 3L; @@ -55,12 +59,14 @@ public void testProperties() { Mockito.when(_firewallService.getFirewallRule(id)).thenReturn(firewallRule); ReflectionTestUtils.setField(cmd, "id", id); + CallContext.current().putApiResourceUuid("id", uuid); + assertEquals(id, (long) cmd.getId()); assertEquals(accountId, cmd.getEntityOwnerId()); assertEquals(networkId, (long) cmd.getApiResourceId()); assertEquals(ApiCommandResourceType.Network, cmd.getApiResourceType()); assertEquals(EventTypes.EVENT_ROUTING_IPV4_FIREWALL_RULE_DELETE, cmd.getEventType()); - assertEquals(String.format("Deleting ipv4 routing firewall rule ID=%s", id), cmd.getEventDescription()); + assertEquals(String.format("Deleting IPv4 routing firewall rule with ID: %s", uuid), cmd.getEventDescription()); } diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 31144296f602..b6f31414655a 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -3119,7 +3119,7 @@ public Network doInTransaction(final TransactionStatus status) { } }); - CallContext.current().setEventDetails("Network Id: " + network.getId()); + CallContext.current().setEventDetails("Network ID: " + network.getUuid()); CallContext.current().putContextParameter(Network.class, network.getUuid()); return network; } diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java index a07fd13e1da0..e8c75afa81c5 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -1126,7 +1126,7 @@ private void updateRootDiskVolumeEventDetails(Type type, VirtualMachine vm, List callContext.setEventResourceId(volumeIds.get(0)); } String volumeUuids = volumeIds.stream().map(volumeId -> this._uuidMgr.getUuid(Volume.class, volumeId)).collect(Collectors.joining(", ")); - callContext.setEventDetails("Volume Type: " + type + "Volume Id: " + volumeUuids + " Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, vm.getId())); + callContext.setEventDetails("Volume Type: " + type + "Volume ID: " + volumeUuids + " Instance ID: " + vm.getUuid()); } } @@ -1366,7 +1366,7 @@ private void destroyVolumeInContext(Volume volume) { // Create new context and inject correct event resource type, id and details, // otherwise VOLUME.DESTROY event will be associated with VirtualMachine and contain VM id and other information. CallContext volumeContext = CallContext.register(CallContext.current(), ApiCommandResourceType.Volume); - volumeContext.setEventDetails("Volume Type: " + volume.getVolumeType() + " Volume Id: " + volume.getUuid() + " Vm Id: " + _uuidMgr.getUuid(VirtualMachine.class, volume.getInstanceId())); + volumeContext.setEventDetails("Volume Type: " + volume.getVolumeType() + " Volume ID: " + volume.getUuid() + " Instance ID: " + _uuidMgr.getUuid(VirtualMachine.class, volume.getInstanceId())); volumeContext.setEventResourceType(ApiCommandResourceType.Volume); volumeContext.setEventResourceId(volume.getId()); try { diff --git a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/RunCustomActionCmd.java b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/RunCustomActionCmd.java index dea09cf16833..9e4c2cc27331 100644 --- a/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/RunCustomActionCmd.java +++ b/framework/extensions/src/main/java/org/apache/cloudstack/framework/extensions/api/RunCustomActionCmd.java @@ -116,6 +116,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Running custom action"; + return "Running custom action with ID: " + getResourceUuid(ApiConstants.CUSTOM_ACTION_ID); } } diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffDeleteCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffDeleteCmd.java index 7810760c56e7..a5d588c20c32 100644 --- a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffDeleteCmd.java +++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffDeleteCmd.java @@ -49,7 +49,7 @@ public String getId() { @Override public void execute() { - CallContext.current().setEventDetails(String.format("Tariff id: %s", getId())); + CallContext.current().setEventDetails(String.format("Tariff ID: %s", getResourceUuid(ApiConstants.ID))); boolean result = responseBuilder.deleteQuotaTariff(getId()); SuccessResponse response = new SuccessResponse(getCommandName()); response.setSuccess(result); diff --git a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateClusterCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateClusterCmd.java index f154d6e357fc..049a0227f359 100644 --- a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateClusterCmd.java +++ b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateClusterCmd.java @@ -81,7 +81,13 @@ public String getEventType() { @Override public String getEventDescription() { - return "dedicating a cluster"; + String baseDescription = "Dedicating cluster with ID: " + getResourceUuid(ApiConstants.CLUSTER_ID) + " to domain with ID: " + getResourceUuid(ApiConstants.DOMAIN_ID); + + if (accountName != null) { + baseDescription = baseDescription + " and account " + accountName; + } + + return baseDescription; } ///////////////////////////////////////////////////// diff --git a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateHostCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateHostCmd.java index 63324bcbbe85..0a953357cc1e 100644 --- a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateHostCmd.java +++ b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateHostCmd.java @@ -111,6 +111,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "dedicating a host"; + String baseDescription = "Dedicating host with ID: " + getResourceUuid(ApiConstants.ID) + " to domain with ID: " + getResourceUuid(ApiConstants.DOMAIN_ID); + + if (accountName != null) { + baseDescription += " and to account " + accountName; + } + + return baseDescription; } } diff --git a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicatePodCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicatePodCmd.java index 74cd7f06960e..6cd997a85065 100644 --- a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicatePodCmd.java +++ b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicatePodCmd.java @@ -112,6 +112,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "dedicating a pod"; + String baseDescription = "Dedicating pod with ID:" + getResourceUuid(ApiConstants.POD_ID) + " to domain with ID: " + getResourceUuid(ApiConstants.DOMAIN_ID); + + if (accountName != null) { + baseDescription += baseDescription + " and account " + accountName; + } + + return baseDescription; } } diff --git a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateZoneCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateZoneCmd.java index d8530421c2e7..48e98ac24158 100644 --- a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateZoneCmd.java +++ b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateZoneCmd.java @@ -112,6 +112,12 @@ public String getEventType() { @Override public String getEventDescription() { - return "dedicating a zone"; + String baseDescription = "Dedicating zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID) + " to domain with ID: " + getResourceUuid(ApiConstants.DOMAIN_ID); + + if (accountName != null) { + baseDescription += " and to account " + accountName; + } + + return baseDescription; } } diff --git a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedClusterCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedClusterCmd.java index 69b31c3515b3..2b51f02ea248 100644 --- a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedClusterCmd.java +++ b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedClusterCmd.java @@ -81,6 +81,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "releasing dedicated cluster"; + return "Releasing dedicated cluster with ID: " + getResourceUuid(ApiConstants.CLUSTER_ID); } } diff --git a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedHostCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedHostCmd.java index 0a218302fe2b..199eb65c13c6 100644 --- a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedHostCmd.java +++ b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedHostCmd.java @@ -81,6 +81,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "releasing dedicated host"; + return "Releasing dedicated host with ID: " + getResourceUuid(ApiConstants.HOST_ID); } } diff --git a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedPodCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedPodCmd.java index eeddd9c4eb19..0aad33264170 100644 --- a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedPodCmd.java +++ b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedPodCmd.java @@ -81,6 +81,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "releasing dedicated pod"; + return "Releasing dedicated pod with ID: " + getResourceUuid(ApiConstants.POD_ID); } } diff --git a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedZoneCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedZoneCmd.java index f4dfbcb264a3..ba6902deeb1f 100644 --- a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedZoneCmd.java +++ b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedZoneCmd.java @@ -81,6 +81,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "releasing dedicated zone"; + return "Releasing dedicated zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID); } } diff --git a/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalDhcpCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalDhcpCmd.java index 89467358349d..192b646b150f 100644 --- a/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalDhcpCmd.java +++ b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalDhcpCmd.java @@ -70,7 +70,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Adding an external DHCP server"; + return "Adding an external DHCP server to physical network with ID: " + getResourceUuid(ApiConstants.PHYSICAL_NETWORK_ID); } @Override diff --git a/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalPxeCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalPxeCmd.java index bf97947ecccc..a2c6060a92ff 100644 --- a/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalPxeCmd.java +++ b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalPxeCmd.java @@ -72,7 +72,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Adding an external pxe server"; + return "Adding an external PXE server to physical network with ID: " + getResourceUuid(ApiConstants.PHYSICAL_NETWORK_ID); } @Override diff --git a/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/BaremetalProvisionDoneNotificationCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/BaremetalProvisionDoneNotificationCmd.java index 73752134abc1..a9b166528302 100644 --- a/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/BaremetalProvisionDoneNotificationCmd.java +++ b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/BaremetalProvisionDoneNotificationCmd.java @@ -50,7 +50,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "notify management server that baremetal provision has been done on a host"; + return "Notifying management server that baremetal provision has been done on a host"; } @Override diff --git a/plugins/hypervisors/external/src/main/java/org/apache/cloudstack/agent/manager/ExternalTemplateAdapter.java b/plugins/hypervisors/external/src/main/java/org/apache/cloudstack/agent/manager/ExternalTemplateAdapter.java index aefe9d0d1809..e56b9ce7b633 100644 --- a/plugins/hypervisors/external/src/main/java/org/apache/cloudstack/agent/manager/ExternalTemplateAdapter.java +++ b/plugins/hypervisors/external/src/main/java/org/apache/cloudstack/agent/manager/ExternalTemplateAdapter.java @@ -163,7 +163,7 @@ public List createTemplateForPostUpload(Templ } // Set Event Details for Template/ISO Upload String eventResourceId = template.getUuid(); - CallContext.current().setEventDetails(String.format("Template Id: %s", eventResourceId)); + CallContext.current().setEventDetails(String.format("Template ID: %s", eventResourceId)); CallContext.current().putContextParameter(VirtualMachineTemplate.class, eventResourceId); Long zoneId = zoneIdList.get(0); DataStore imageStore = verifyHeuristicRulesForZone(template, zoneId); diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/AddNodesToKubernetesClusterCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/AddNodesToKubernetesClusterCmd.java index 71cc8ffcde23..f47bc8ee3248 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/AddNodesToKubernetesClusterCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/AddNodesToKubernetesClusterCmd.java @@ -99,7 +99,7 @@ public String getEventType() { @Override public String getEventDescription() { - return String.format("Adding %s nodes to the Kubernetes cluster with ID: %s", nodeIds.size(), clusterId); + return "Adding " + nodeIds.size() + " nodes to Kubernetes cluster with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/DeleteKubernetesClusterCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/DeleteKubernetesClusterCmd.java index da7c803e290a..10a5bcc3cb1d 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/DeleteKubernetesClusterCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/DeleteKubernetesClusterCmd.java @@ -126,14 +126,7 @@ public Long getApiResourceId() { @Override public String getEventDescription() { - String description = "Deleting Kubernetes cluster"; - KubernetesCluster cluster = _entityMgr.findById(KubernetesCluster.class, getId()); - if (cluster != null) { - description += String.format(" ID: %s", cluster.getUuid()); - } else { - description += String.format(" ID: %d", getId()); - } - return description; + return "Deleting Kubernetes cluster with ID: " + getResourceUuid(ApiConstants.ID); } } diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/RemoveNodesFromKubernetesClusterCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/RemoveNodesFromKubernetesClusterCmd.java index 2ca36e83ab47..1eae69377c47 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/RemoveNodesFromKubernetesClusterCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/RemoveNodesFromKubernetesClusterCmd.java @@ -89,7 +89,7 @@ public String getEventType() { @Override public String getEventDescription() { - return String.format("Removing %s nodes from the Kubernetes Cluster with ID: %s", nodeIds.size(), clusterId); + return "Removing " + nodeIds.size() + " nodes from the Kubernetes Cluster with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/UpgradeKubernetesClusterCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/UpgradeKubernetesClusterCmd.java index 28962c9f2892..fb576e9ef825 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/UpgradeKubernetesClusterCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/UpgradeKubernetesClusterCmd.java @@ -82,14 +82,7 @@ public String getEventType() { @Override public String getEventDescription() { - String description = "Upgrading Kubernetes cluster"; - KubernetesCluster cluster = _entityMgr.findById(KubernetesCluster.class, getId()); - if (cluster != null) { - description += String.format(" ID: %s", cluster.getUuid()); - } else { - description += String.format(" ID: %d", getId()); - } - return description; + return "Upgrading Kubernetes cluster with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/AddBigSwitchBcfDeviceCmd.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/AddBigSwitchBcfDeviceCmd.java index 3501030a4cd4..43be31dd46dc 100644 --- a/plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/AddBigSwitchBcfDeviceCmd.java +++ b/plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/AddBigSwitchBcfDeviceCmd.java @@ -131,6 +131,6 @@ public String getEventType() { @Override public String getEventDescription() { - return "Adding a BigSwitch BCF Controller"; + return "Adding a BigSwitch BCF Controller to physical network with ID: " + getResourceUuid(ApiConstants.PHYSICAL_NETWORK_ID); } } diff --git a/plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/DeleteBigSwitchBcfDeviceCmd.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/DeleteBigSwitchBcfDeviceCmd.java index 9c977ffb7aa3..b86adac1b75e 100644 --- a/plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/DeleteBigSwitchBcfDeviceCmd.java +++ b/plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/DeleteBigSwitchBcfDeviceCmd.java @@ -22,6 +22,7 @@ import javax.inject.Inject; 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; @@ -98,7 +99,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting BigSwitch BCF Controller"; + return "Deleting BigSwitch BCF Controller with ID: " + getResourceUuid(ApiConstants.ID); } } diff --git a/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/guru/BigSwitchBcfGuestNetworkGuru.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/guru/BigSwitchBcfGuestNetworkGuru.java index cefae2dcadde..5b764ba129b6 100644 --- a/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/guru/BigSwitchBcfGuestNetworkGuru.java +++ b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/guru/BigSwitchBcfGuestNetworkGuru.java @@ -203,7 +203,7 @@ public Network implement(Network network, NetworkOffering offering, DeployDestin } implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnetId)); ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(), - EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnetId + " Network Id: " + network.getId(), network.getId(), ApiCommandResourceType.Network.toString(), 0); + EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone VLAN: " + vnetId + " Network ID: " + network.getUuid(), network.getId(), ApiCommandResourceType.Network.toString(), 0); } else { implemented.setBroadcastUri(network.getBroadcastUri()); } diff --git a/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/api/AddGloboDnsHostCmd.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/api/AddGloboDnsHostCmd.java index b30c8894f389..3a1ca73f0fab 100644 --- a/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/api/AddGloboDnsHostCmd.java +++ b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/api/AddGloboDnsHostCmd.java @@ -112,7 +112,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Add GloboDNS provider"; + return "Add GloboDNS provider to physical network with ID: " + getResourceUuid(ApiConstants.PHYSICAL_NETWORK_ID); } } diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisGuestNetworkGuru.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisGuestNetworkGuru.java index df566e90b67d..7a4e81175f98 100644 --- a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisGuestNetworkGuru.java +++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisGuestNetworkGuru.java @@ -224,7 +224,7 @@ protected void allocateVnet(Network network, NetworkVO implemented, long dcId, l } implemented.setBroadcastUri(Networks.BroadcastDomainType.Netris.toUri(vnet)); ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VXLAN_ASSIGN, - "Assigned Zone vNet: " + vnet + " Network Id: " + networkId, networkId, ApiCommandResourceType.Network.toString(), 0); + "Assigned Zone vNet: " + vnet + " Network ID: " + network.getUuid(), networkId, ApiCommandResourceType.Network.toString(), 0); } else { implemented.setBroadcastUri(network.getBroadcastUri()); } diff --git a/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java index 7c4fb2cdbe58..2786b1c1c727 100644 --- a/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java +++ b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java @@ -88,7 +88,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE @Override public String getEventDescription() { - return "Deleting a netscaler load balancer device"; + return "Deleting NetScaler load balancer device with ID: " + getResourceUuid(ApiConstants.LOAD_BALANCER_DEVICE_ID); } @Override diff --git a/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeployNetscalerVpxCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeployNetscalerVpxCmd.java index 2b4fc6010470..f37a15a7bad8 100644 --- a/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeployNetscalerVpxCmd.java +++ b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeployNetscalerVpxCmd.java @@ -117,7 +117,7 @@ public Long getTemplateId() { @Override public String getEventDescription() { - return "Adding a netscaler load balancer device"; + return "Adding a NetScaler load balancer device in zone: " + getResourceUuid(ApiConstants.ZONE_ID) ; } @Override diff --git a/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/StopNetScalerVMCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/StopNetScalerVMCmd.java index d97f2f4b6a86..243204a72891 100644 --- a/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/StopNetScalerVMCmd.java +++ b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/StopNetScalerVMCmd.java @@ -91,7 +91,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "stopping Netscaler vm: " + getId(); + return "Stopping NetScaler VM with ID: " + getResourceUuid(ApiConstants.ID); } @Override @@ -110,7 +110,7 @@ public boolean isForced() { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException { - CallContext.current().setEventDetails("NetScaler vm Id: " + getId()); + CallContext.current().setEventDetails("NetScaler Instance ID: " + getResourceUuid(ApiConstants.ID)); VirtualRouter result = null; VirtualRouter vm = _routerService.findRouter(getId()); if (vm == null || vm.getRole() != Role.NETSCALER_VM) { diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java index 47923e762a0d..54b172e96511 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java @@ -100,7 +100,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleting Nicira Nvp Controller"; + return "Deleting Nicira NVP Controller with ID: " + getResourceUuid(ApiConstants.NICIRA_NVP_DEVICE_ID); } } diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/api/commands/AddOpenDaylightControllerCmd.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/api/commands/AddOpenDaylightControllerCmd.java index 44cfded880d9..19129e19ae9b 100644 --- a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/api/commands/AddOpenDaylightControllerCmd.java +++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/api/commands/AddOpenDaylightControllerCmd.java @@ -83,7 +83,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Adding OpenDaylight controller"; + return "Adding OpenDaylight controller to physical network with ID: " + getResourceUuid(ApiConstants.PHYSICAL_NETWORK_ID); } public Long getPhysicalNetworkId() { diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/api/commands/DeleteOpenDaylightControllerCmd.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/api/commands/DeleteOpenDaylightControllerCmd.java index ce02e64fdd14..188830e13249 100644 --- a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/api/commands/DeleteOpenDaylightControllerCmd.java +++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/api/commands/DeleteOpenDaylightControllerCmd.java @@ -68,7 +68,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Deleted OpenDaylight Controller"; + return "Deleting OpenDaylight Controller with ID: " + getResourceUuid(ApiConstants.ID); } @Override diff --git a/plugins/network-elements/ovs/src/main/java/com/cloud/network/guru/OvsGuestNetworkGuru.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/guru/OvsGuestNetworkGuru.java index 0a9eeea496f8..327b4eb42e52 100644 --- a/plugins/network-elements/ovs/src/main/java/com/cloud/network/guru/OvsGuestNetworkGuru.java +++ b/plugins/network-elements/ovs/src/main/java/com/cloud/network/guru/OvsGuestNetworkGuru.java @@ -225,8 +225,8 @@ protected void allocateVnet(Network network, NetworkVO implemented, network.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, - "Assigned Zone Vlan: " + vnet + " Network Id: " - + network.getId(), + "Assigned Zone VLAN: " + vnet + " Network ID: " + + network.getUuid(), network.getId(), ApiCommandResourceType.Network.toString(), 0); } else { implemented.setBroadcastUri(network.getBroadcastUri()); diff --git a/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/AddPaloAltoFirewallCmd.java b/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/AddPaloAltoFirewallCmd.java index 70a35e7f7ed4..c0578c4f1cfa 100644 --- a/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/AddPaloAltoFirewallCmd.java +++ b/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/AddPaloAltoFirewallCmd.java @@ -118,7 +118,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE @Override public String getEventDescription() { - return "Adding a Palo Alto firewall device"; + return "Adding a Palo Alto firewall device to physical network with ID: " + getResourceUuid(ApiConstants.PHYSICAL_NETWORK_ID); } @Override diff --git a/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/ConfigurePaloAltoFirewallCmd.java b/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/ConfigurePaloAltoFirewallCmd.java index 21eb3ccafb9e..c3b4eea36d01 100644 --- a/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/ConfigurePaloAltoFirewallCmd.java +++ b/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/ConfigurePaloAltoFirewallCmd.java @@ -100,7 +100,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE @Override public String getEventDescription() { - return "Configuring a Palo Alto firewall device"; + return "Configuring Palo Alto firewall device with ID: " + getResourceUuid(ApiConstants.FIREWALL_DEVICE_ID); } @Override diff --git a/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/DeletePaloAltoFirewallCmd.java b/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/DeletePaloAltoFirewallCmd.java index 378bad4dad89..732123ac1f47 100644 --- a/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/DeletePaloAltoFirewallCmd.java +++ b/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/DeletePaloAltoFirewallCmd.java @@ -88,7 +88,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE @Override public String getEventDescription() { - return "Deleting Palo Alto firewall device"; + return "Deleting Palo Alto firewall device with ID: " + getResourceUuid(ApiConstants.FIREWALL_DEVICE_ID); } @Override diff --git a/plugins/network-elements/vxlan/src/main/java/com/cloud/network/guru/VxlanGuestNetworkGuru.java b/plugins/network-elements/vxlan/src/main/java/com/cloud/network/guru/VxlanGuestNetworkGuru.java index e2c313d08219..949d343611ed 100644 --- a/plugins/network-elements/vxlan/src/main/java/com/cloud/network/guru/VxlanGuestNetworkGuru.java +++ b/plugins/network-elements/vxlan/src/main/java/com/cloud/network/guru/VxlanGuestNetworkGuru.java @@ -102,7 +102,7 @@ protected void allocateVnet(Network network, NetworkVO implemented, long dcId, l protected void allocateVnetComplete(Network network, NetworkVO implemented, long dcId, long physicalNetworkId, String reservationId, String vnet) { //TODO(VXLAN): Add new event type for vxlan? ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, - "Assigned Zone vNet: " + vnet + " Network Id: " + network.getId(), network.getId(), ApiCommandResourceType.Network.toString(), 0); + "Assigned Zone vNet: " + vnet + " Network ID: " + network.getUuid(), network.getId(), ApiCommandResourceType.Network.toString(), 0); } @Override diff --git a/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java index a33b4e9c87b9..3aa3e0502268 100644 --- a/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java +++ b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java @@ -138,7 +138,7 @@ public void execute() throws ServerApiException { final CallContext callContext = getCurrentContext(); String finalAccountName = getAccountName(); Long finalDomainId = getDomainId(); - callContext.setEventDetails("Account Name: " + finalAccountName + ", Domain Id:" + finalDomainId); + callContext.setEventDetails("Account Name: " + finalAccountName + ", Domain ID:" + finalDomainId); try { final LdapUser user = _ldapManager.getUser(username, domainId); validateUser(user); diff --git a/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/AuthorizeSAMLSSOCmd.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/AuthorizeSAMLSSOCmd.java index c5f48d61c6fb..48cee26a775d 100644 --- a/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/AuthorizeSAMLSSOCmd.java +++ b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/AuthorizeSAMLSSOCmd.java @@ -83,7 +83,7 @@ public void execute() { _accountService.checkAccess(CallContext.current().getCallingAccount(), domain); _accountService.checkAccess(CallContext.current().getCallingAccount(), SecurityChecker.AccessType.OperateEntry, true, account); - CallContext.current().setEventDetails("UserId: " + getId()); + CallContext.current().setEventDetails("User ID: " + getResourceUuid(ApiConstants.USER_ID)); SuccessResponse response = new SuccessResponse(); Boolean status = false; diff --git a/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java b/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java index c4145755b560..5a634cc0ca8d 100644 --- a/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java +++ b/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.StringTokenizer; +import java.util.UUID; import java.util.regex.Matcher; import javax.inject.Inject; @@ -43,6 +44,7 @@ import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.BaseCmd.CommandType; import org.apache.cloudstack.api.EntityReference; +import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; @@ -528,10 +530,16 @@ private Long translateUuidToInternalId(final String uuid, final Parameter annota } catch (final NumberFormatException e) { internalId = null; } - if (internalId != null){ + if (internalId != null) { // Populate CallContext for each of the entity. for (final Class entity : entities) { CallContext.current().putContextParameter(entity, internalId); + final Object objVO = _entityMgr.findByIdIncludingRemoved(entity, internalId); + if (!(objVO instanceof Identity)) { + continue; + } + String entityUuid = ((Identity) objVO).getUuid(); + CallContext.current().putApiResourceUuid(annotation.name(), UUID.fromString(entityUuid)); } validateNaturalNumber(internalId, annotation.name()); return internalId; @@ -556,6 +564,7 @@ private Long translateUuidToInternalId(final String uuid, final Parameter annota } // Return on first non-null Id for the uuid entity if (internalId != null){ + CallContext.current().putApiResourceUuid(annotation.name(), UUID.fromString(uuid)); CallContext.current().putContextParameter(entity, uuid); break; } diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java index 7b171e5f996f..ee397ee2a5b8 100644 --- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java @@ -3650,7 +3650,7 @@ protected ServiceOfferingVO createServiceOffering(final long userId, final boole _serviceOfferingDetailsDao.saveDetails(detailsVOList); } - CallContext.current().setEventDetails("Service offering id=" + serviceOffering.getId()); + CallContext.current().setEventDetails("Service offering ID: " + serviceOffering.getUuid()); CallContext.current().putContextParameter(ServiceOffering.class, serviceOffering.getId()); return serviceOffering; } else { @@ -4050,7 +4050,7 @@ public ServiceOffering updateServiceOffering(final UpdateServiceOfferingCmd cmd) } } offering = _serviceOfferingDao.findById(id); - CallContext.current().setEventDetails("Service offering id=" + offering.getId()); + CallContext.current().setEventDetails("Service offering ID:" + offering.getUuid()); return offering; } @@ -4166,7 +4166,7 @@ protected DiskOfferingVO createDiskOffering(final Long userId, final List newDiskOffering.setHypervisorSnapshotReserve(hypervisorSnapshotReserve); newDiskOffering.setDiskSizeStrictness(diskSizeStrictness); - CallContext.current().setEventDetails("Disk offering id=" + newDiskOffering.getId()); + CallContext.current().setEventDetails("Disk offering ID: " + newDiskOffering.getUuid()); final DiskOfferingVO offering = _diskOfferingDao.persist(newDiskOffering); if (offering != null) { List detailsVO = new ArrayList<>(); @@ -4191,7 +4191,7 @@ protected DiskOfferingVO createDiskOffering(final Long userId, final List if (!detailsVO.isEmpty()) { diskOfferingDetailsDao.saveDetails(detailsVO); } - CallContext.current().setEventDetails("Disk offering id=" + newDiskOffering.getId()); + CallContext.current().setEventDetails("Disk offering ID: " + newDiskOffering.getUuid()); CallContext.current().putContextParameter(DiskOffering.class, newDiskOffering.getId()); return offering; } @@ -4466,7 +4466,7 @@ public DiskOffering updateDiskOffering(final UpdateDiskOfferingCmd cmd) { diskOfferingDetailsDao.persist(detailVO); } } - CallContext.current().setEventDetails("Disk offering id=" + diskOffering.getId()); + CallContext.current().setEventDetails("Disk offering ID: " + diskOffering.getUuid()); return _diskOfferingDao.findById(diskOfferingId); } @@ -4724,7 +4724,7 @@ public boolean deleteDiskOffering(final DeleteDiskOfferingCmd cmd) { annotationDao.removeByEntityType(AnnotationService.EntityType.DISK_OFFERING.name(), offering.getUuid()); offering.setState(DiskOffering.State.Inactive); if (_diskOfferingDao.update(offering.getId(), offering)) { - CallContext.current().setEventDetails("Disk offering id=" + diskOfferingId); + CallContext.current().setEventDetails("Disk offering ID: " + offering.getUuid()); return true; } else { return false; @@ -4804,7 +4804,7 @@ public boolean deleteServiceOffering(final DeleteServiceOfferingCmd cmd) { } offering.setState(ServiceOffering.State.Inactive); if (_serviceOfferingDao.update(offeringId, offering)) { - CallContext.current().setEventDetails("Service offering id=" + offeringId); + CallContext.current().setEventDetails("Service offering ID: " + offering.getUuid()); return true; } else { return false; @@ -6930,7 +6930,7 @@ public NetworkOffering createNetworkOffering(final CreateNetworkOfferingCmd cmd) offering.setPublicLb(false); _networkOfferingDao.update(offering.getId(), offering); } - CallContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name); + CallContext.current().setEventDetails(" ID: " + offering.getUuid() + " Name: " + name); CallContext.current().putContextParameter(NetworkOffering.class, offering.getId()); return offering; } @@ -7785,7 +7785,6 @@ public boolean isOfferingForVpc(final NetworkOffering offering) { @ActionEvent(eventType = EventTypes.EVENT_NETWORK_OFFERING_DELETE, eventDescription = "deleting network offering") public boolean deleteNetworkOffering(final DeleteNetworkOfferingCmd cmd) { final Long offeringId = cmd.getId(); - CallContext.current().setEventDetails(" Id: " + offeringId); // Verify network offering id final NetworkOfferingVO offering = _networkOfferingDao.findById(offeringId); @@ -7795,6 +7794,8 @@ public boolean deleteNetworkOffering(final DeleteNetworkOfferingCmd cmd) { throw new InvalidParameterValueException("unable to find network offering " + offeringId); } + CallContext.current().setEventDetails(" ID: " + offering.getUuid()); + // Don't allow to delete default network offerings if (offering.isDefault() == true) { throw new InvalidParameterValueException("Default network offering can't be deleted"); @@ -7833,7 +7834,6 @@ public NetworkOffering updateNetworkOffering(final UpdateNetworkOfferingCmd cmd) final String tags = cmd.getTags(); final List domainIds = cmd.getDomainIds(); final List zoneIds = cmd.getZoneIds(); - CallContext.current().setEventDetails(" Id: " + id); // Verify input parameters final NetworkOfferingVO offeringToUpdate = _networkOfferingDao.findById(id); @@ -7841,6 +7841,8 @@ public NetworkOffering updateNetworkOffering(final UpdateNetworkOfferingCmd cmd) throw new InvalidParameterValueException("unable to find network offering " + id); } + CallContext.current().setEventDetails(" ID: " + offeringToUpdate.getUuid()); + List existingDomainIds = networkOfferingDetailsDao.findDomainIds(id); Collections.sort(existingDomainIds); @@ -8045,7 +8047,7 @@ public AccountVO markDefaultZone(final String accountName, final long domainId, acctForUpdate.setDefaultZoneId(defaultZoneId); if (_accountDao.update(account.getId(), acctForUpdate)) { - CallContext.current().setEventDetails("Default zone id= " + defaultZoneId); + CallContext.current().setEventDetails("Default zone ID: " + defaultZoneId); return _accountDao.findById(account.getId()); } else { return null; diff --git a/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java b/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java index 8d179735a4d1..20ca189994ef 100644 --- a/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java +++ b/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java @@ -1454,7 +1454,7 @@ public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAdd throw ex; } - CallContext.current().setEventDetails("Ip Id: " + ip.getId()); + CallContext.current().setEventDetails("IP address ID: " + ip.getUuid()); Ip ipAddress = ip.getAddress(); logger.debug("Got {} to assign for account {} in zone {}", ipAddress, ipOwner, zone); diff --git a/server/src/main/java/com/cloud/network/Ipv6ServiceImpl.java b/server/src/main/java/com/cloud/network/Ipv6ServiceImpl.java index 464f8c90ebb6..dcb8ad47a642 100644 --- a/server/src/main/java/com/cloud/network/Ipv6ServiceImpl.java +++ b/server/src/main/java/com/cloud/network/Ipv6ServiceImpl.java @@ -616,7 +616,7 @@ public FirewallRuleVO doInTransaction(TransactionStatus status) throws NetworkRu if (!firewallDao.setStateToAdd(newRule)) { throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } - CallContext.current().setEventDetails("Rule Id: " + newRule.getId()); + CallContext.current().setEventDetails("Rule ID: " + newRule.getUuid()); return newRule; } diff --git a/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java index e080a34e74ec..4e07611ff716 100644 --- a/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java @@ -1486,7 +1486,7 @@ public Counter createCounter(CreateCounterCmd cmd) { logger.debug("Adding Counter " + name); counter = counterDao.persist(new CounterVO(src, name, value, provider)); - CallContext.current().setEventDetails(" Id: " + counter.getId() + " Name: " + name); + CallContext.current().setEventDetails(" ID: " + counter.getUuid() + " Name: " + name); return counter; } @@ -1527,7 +1527,7 @@ public Condition createCondition(CreateConditionCmd cmd) { condition = conditionDao.persist(new ConditionVO(cid, threshold, owner.getAccountId(), owner.getDomainId(), op)); logger.info("Successfully created condition: {}", condition); - CallContext.current().setEventDetails(" Id: " + condition.getId()); + CallContext.current().setEventDetails(" ID: " + condition.getUuid()); return condition; } @@ -2015,7 +2015,7 @@ public void checkAutoScaleVmGroupName(String groupName) { private UserVmVO startNewVM(long vmId) { try { - CallContext.current().setEventDetails("Vm Id: " + vmId); + CallContext.current().setEventDetails("Instance ID: " + vmId); return userVmMgr.startVirtualMachine(vmId, null, new HashMap<>(), null).first(); } catch (final ResourceUnavailableException ex) { logger.warn("Exception: ", ex); diff --git a/server/src/main/java/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/main/java/com/cloud/network/firewall/FirewallManagerImpl.java index 4aee5fef48a6..00863c28dd22 100644 --- a/server/src/main/java/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/main/java/com/cloud/network/firewall/FirewallManagerImpl.java @@ -267,7 +267,7 @@ protected FirewallRule createFirewallRule(final Long ipAddrId, Account caller, f if (!_firewallDao.setStateToAdd(newRule)) { throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } - CallContext.current().setEventDetails("Rule Id: " + newRule.getId()); + CallContext.current().setEventDetails("Rule ID: " + newRule.getUuid()); CallContext.current().putContextParameter(FirewallRule.class, newRule.getId()); return newRule; diff --git a/server/src/main/java/com/cloud/network/guru/ExternalGuestNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/ExternalGuestNetworkGuru.java index 2bb067b8826a..49404068051c 100644 --- a/server/src/main/java/com/cloud/network/guru/ExternalGuestNetworkGuru.java +++ b/server/src/main/java/com/cloud/network/guru/ExternalGuestNetworkGuru.java @@ -162,7 +162,7 @@ public Network implement(Network config, NetworkOffering offering, DeployDestina implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlanTag)); ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), config.getAccountId(), EventVO.LEVEL_INFO, - EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnet + " Network Id: " + config.getId(), config.getId(), ApiCommandResourceType.Network.toString(), 0); + EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone VLAN: " + vnet + " Network ID: " + config.getUuid(), config.getId(), ApiCommandResourceType.Network.toString(), 0); } else { vlanTag = Integer.parseInt(BroadcastDomainType.getValue(config.getBroadcastUri())); implemented.setBroadcastUri(config.getBroadcastUri()); diff --git a/server/src/main/java/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/GuestNetworkGuru.java index 3c677cb19e24..39b9a32e48e3 100644 --- a/server/src/main/java/com/cloud/network/guru/GuestNetworkGuru.java +++ b/server/src/main/java/com/cloud/network/guru/GuestNetworkGuru.java @@ -370,7 +370,7 @@ protected void allocateVnet(final Network network, final NetworkVO implemented, } implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnet)); ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(), EventVO.LEVEL_INFO, - EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnet + " Network Id: " + network.getId(), network.getId(), ApiCommandResourceType.Network.toString(), 0); + EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone VLAN: " + vnet + " Network ID: " + network.getUuid(), network.getId(), ApiCommandResourceType.Network.toString(), 0); } else { implemented.setBroadcastUri(network.getBroadcastUri()); } diff --git a/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index c6aeeaf2db59..ffa22e2fb51e 100644 --- a/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -1896,7 +1896,7 @@ public LoadBalancer createPublicLoadBalancer(final String xId, final String name throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } logger.debug("Load balancer {} for Ip address: {}, public port {}, private port {} is added successfully.", newRule, ipAddr, srcPort, destPort); - CallContext.current().setEventDetails("Load balancer Id: " + newRule.getId()); + CallContext.current().setEventDetails("Load balancer ID: " + newRule.getUuid()); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_CREATE, ipAddr.getAllocatedToAccountId(), ipAddr.getDataCenterId(), newRule.getId(), null, LoadBalancingRule.class.getName(), newRule.getUuid()); diff --git a/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java b/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java index 1f1e294bc53a..bb3ee8d76248 100644 --- a/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java @@ -336,7 +336,7 @@ public PortForwardingRule createPortForwardingRule(final PortForwardingRule rule if (!_firewallDao.setStateToAdd(newRule)) { throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } - CallContext.current().setEventDetails("Rule Id: " + newRule.getId()); + CallContext.current().setEventDetails("Rule ID: " + newRule.getUuid()); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), ipAddressFinal.getDataCenterId(), newRule.getId(), null, PortForwardingRule.class.getName(), newRule.getUuid()); return newRule; @@ -420,7 +420,7 @@ public StaticNatRule createStaticNatRule(final StaticNatRule rule, final boolean if (!_firewallDao.setStateToAdd(newRule)) { throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } - CallContext.current().setEventDetails("Rule Id: " + newRule.getId()); + CallContext.current().setEventDetails("Rule ID: " + newRule.getUuid()); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), 0, newRule.getId(), null, FirewallRule.class.getName(), newRule.getUuid()); @@ -453,7 +453,6 @@ private boolean enableStaticNat(long ipId, long vmId, long networkId, boolean is ResourceUnavailableException { CallContext ctx = CallContext.current(); Account caller = ctx.getCallingAccount(); - CallContext.current().setEventDetails("Ip Id: " + ipId); // Verify input parameters IPAddressVO ipAddress = _ipAddressDao.findById(ipId); @@ -461,6 +460,8 @@ private boolean enableStaticNat(long ipId, long vmId, long networkId, boolean is throw new InvalidParameterValueException("Unable to find ip address by id " + ipId); } + CallContext.current().setEventDetails("IP address ID: " + ipAddress.getUuid()); + // Verify input parameters boolean performedIpAssoc = false; boolean isOneToOneNat = ipAddress.isOneToOneNat(); diff --git a/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java index 5dac69d96da8..b6dfdbac0be2 100644 --- a/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java +++ b/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java @@ -239,7 +239,8 @@ public NetworkACLItemVO doInTransaction(final TransactionStatus status) { if (!_networkACLItemDao.setStateToAdd(networkACLItemVOFromDatabase)) { throw new CloudRuntimeException("Unable to update the state to add for " + networkACLItemVOFromDatabase); } - CallContext.current().setEventDetails("ACL Item Id: " + networkACLItemVOFromDatabase.getId()); + + CallContext.current().setEventDetails("ACL Item ID: " + networkACLItemVOFromDatabase.getUuid()); CallContext.current().putContextParameter(NetworkACLItem.class, networkACLItemVOFromDatabase.getAclId()); return networkACLItemVOFromDatabase; } diff --git a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java index 60b93d409aab..86d1fba038b7 100644 --- a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java @@ -746,7 +746,7 @@ public VpcOffering createVpcOffering(final String name, final String displayText vpcOfferingDetailsDao.saveDetails(detailsVO); } } - CallContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name); + CallContext.current().setEventDetails(" ID: " + offering.getUuid() + " Name: " + name); CallContext.current().putContextParameter(VpcOffering.class, offering.getUuid()); return offering; @@ -1040,13 +1040,12 @@ protected boolean areServicesSupportedByVpcOffering(final long vpcOffId, final S @Override @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_DELETE, eventDescription = "deleting vpc offering") public boolean deleteVpcOffering(final long offId) { - CallContext.current().setEventDetails(" Id: " + offId); - // Verify vpc offering id final VpcOfferingVO offering = _vpcOffDao.findById(offId); if (offering == null) { throw new InvalidParameterValueException("unable to find vpc offering " + offId); } + CallContext.current().setEventDetails(" ID: " + offering.getUuid()); // Don't allow to delete default vpc offerings if (offering.isDefault() == true) { @@ -1105,13 +1104,12 @@ public VpcOffering updateVpcOffering(final UpdateVPCOfferingCmd cmd) { } private VpcOffering updateVpcOfferingInternal(long vpcOffId, String vpcOfferingName, String displayText, String state, Integer sortKey, final List domainIds, final List zoneIds) { - CallContext.current().setEventDetails(" Id: " + vpcOffId); - // Verify input parameters final VpcOfferingVO offeringToUpdate = _vpcOffDao.findById(vpcOffId); if (offeringToUpdate == null) { throw new InvalidParameterValueException("Unable to find vpc offering " + vpcOffId); } + CallContext.current().setEventDetails(" ID: " + offeringToUpdate.getUuid()); List existingDomainIds = vpcOfferingDetailsDao.findDomainIds(vpcOffId); Collections.sort(existingDomainIds); @@ -1515,7 +1513,6 @@ private Map> finalizeServicesAndProvidersForVpc(final long @Override @ActionEvent(eventType = EventTypes.EVENT_VPC_DELETE, eventDescription = "deleting VPC") public boolean deleteVpc(final long vpcId) throws ConcurrentOperationException, ResourceUnavailableException { - CallContext.current().setEventDetails(" Id: " + vpcId); final CallContext ctx = CallContext.current(); // Verify vpc id @@ -1524,6 +1521,8 @@ public boolean deleteVpc(final long vpcId) throws ConcurrentOperationException, throw new InvalidParameterValueException("unable to find VPC id=" + vpcId); } + CallContext.current().setEventDetails(" ID: " + vpc.getUuid()); + // verify permissions _accountMgr.checkAccess(ctx.getCallingAccount(), null, false, vpc); _resourceTagDao.removeByIdAndType(vpcId, ResourceObjectType.Vpc); @@ -1594,7 +1593,6 @@ public Vpc updateVpc(UpdateVPCCmd cmd) throws ResourceUnavailableException, Insu @Override @ActionEvent(eventType = EventTypes.EVENT_VPC_UPDATE, eventDescription = "updating vpc") public Vpc updateVpc(final long vpcId, final String vpcName, final String displayText, final String customId, final Boolean displayVpc, Integer mtu, String sourceNatIp) throws ResourceUnavailableException, InsufficientCapacityException { - CallContext.current().setEventDetails(" Id: " + vpcId); final Account caller = CallContext.current().getCallingAccount(); // Verify input parameters @@ -1603,6 +1601,8 @@ public Vpc updateVpc(final long vpcId, final String vpcName, final String displa throw new InvalidParameterValueException("Unable to find vpc by id " + vpcId); } + CallContext.current().setEventDetails(" ID: " + vpcToUpdate.getUuid()); + _accountMgr.checkAccess(caller, null, false, vpcToUpdate); final VpcVO vpc = vpcDao.createForUpdate(vpcId); @@ -2611,7 +2611,7 @@ private PrivateGateway createVpcPrivateGateway(final long vpcId, Long physicalNe throw new IllegalStateException(e); } - CallContext.current().setEventDetails("Private Gateway Id: " + gatewayVO.getId()); + CallContext.current().setEventDetails("Private Gateway ID: " + gatewayVO.getUuid()); return getVpcPrivateGateway(gatewayVO.getId()); } @@ -2731,7 +2731,7 @@ public PrivateGateway applyVpcPrivateGateway(final long gatewayId, final boolean _vpcGatewayDao.update(vo.getId(), vo); logger.debug("Marke gateway " + gateway + " with state " + VpcGateway.State.Ready); } - CallContext.current().setEventDetails("Private Gateway Id: " + gatewayId); + CallContext.current().setEventDetails("Private Gateway ID: " + gateway.getUuid()); return getVpcPrivateGateway(gatewayId); } else { logger.warn("Private gateway " + gateway + " failed to apply on the backend"); @@ -3128,7 +3128,7 @@ public StaticRouteVO doInTransaction(final TransactionStatus status) throws Netw if (!_staticRouteDao.setStateToAdd(newRoute)) { throw new CloudRuntimeException("Unable to update the state to add for " + newRoute); } - CallContext.current().setEventDetails("Static route Id: " + newRoute.getId()); + CallContext.current().setEventDetails("Static route ID: " + newRoute.getUuid()); return newRoute; } diff --git a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index 09236eb0d6e7..47362feb4d15 100644 --- a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -618,11 +618,11 @@ public Site2SiteCustomerGateway getCustomerGateway(Long customerGatewayId) { @Override @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE, eventDescription = "deleting s2s vpn customer gateway", create = true) public boolean deleteCustomerGateway(DeleteVpnCustomerGatewayCmd cmd) { - CallContext.current().setEventDetails(" Id: " + cmd.getId()); Account caller = CallContext.current().getCallingAccount(); Long id = cmd.getId(); Site2SiteCustomerGateway customerGateway = getAndValidateSite2SiteCustomerGateway(id, caller); + CallContext.current().setEventDetails(" ID: " + customerGateway.getUuid()); return doDeleteCustomerGateway(customerGateway); } @@ -649,11 +649,11 @@ protected void doDeleteVpnGateway(Site2SiteVpnGateway gw) { @Override @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_GATEWAY_DELETE, eventDescription = "deleting s2s vpn gateway", async = true) public boolean deleteVpnGateway(DeleteVpnGatewayCmd cmd) { - CallContext.current().setEventDetails(" Id: " + cmd.getId()); Account caller = CallContext.current().getCallingAccount(); Long id = cmd.getId(); Site2SiteVpnGateway vpnGateway = getAndValidateSite2SiteVpnGateway(id, caller); + CallContext.current().setEventDetails(" ID: " + vpnGateway.getUuid()); doDeleteVpnGateway(vpnGateway); return true; @@ -662,7 +662,6 @@ public boolean deleteVpnGateway(DeleteVpnGatewayCmd cmd) { @Override @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE, eventDescription = "update s2s vpn customer gateway", create = true) public Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCmd cmd) { - CallContext.current().setEventDetails(" Id: " + cmd.getId()); Account caller = CallContext.current().getCallingAccount(); Long id = cmd.getId(); @@ -670,6 +669,7 @@ public Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCm if (gw == null) { throw new InvalidParameterValueException("Find to find customer gateway with id " + id); } + CallContext.current().setEventDetails(" ID: " + gw.getUuid()); _accountMgr.checkAccess(caller, null, false, gw); String name = cmd.getName(); @@ -790,7 +790,6 @@ private void setupVpnConnection(Account caller, Long vpnCustomerGwIp) { @Override @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_CONNECTION_DELETE, eventDescription = "deleting s2s vpn connection", create = true) public boolean deleteVpnConnection(DeleteVpnConnectionCmd cmd) throws ResourceUnavailableException { - CallContext.current().setEventDetails(" Id: " + cmd.getId()); Account caller = CallContext.current().getCallingAccount(); Long id = cmd.getId(); @@ -798,6 +797,7 @@ public boolean deleteVpnConnection(DeleteVpnConnectionCmd cmd) throws ResourceUn if (conn == null) { throw new InvalidParameterValueException("Fail to find site to site VPN connection " + id + " to delete!"); } + CallContext.current().setEventDetails(" ID: " + conn.getUuid()); _accountMgr.checkAccess(caller, null, false, conn); @@ -852,7 +852,6 @@ private void stopVpnConnection(Long id) throws ResourceUnavailableException { @Override @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_CONNECTION_RESET, eventDescription = "reseting s2s vpn connection", create = true) public Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd cmd) throws ResourceUnavailableException { - CallContext.current().setEventDetails(" Id: " + cmd.getId()); Account caller = CallContext.current().getCallingAccount(); Long id = cmd.getId(); @@ -860,6 +859,7 @@ public Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd cmd) thro if (conn == null) { throw new InvalidParameterValueException("Fail to find site to site VPN connection " + id + " to reset!"); } + CallContext.current().setEventDetails(" ID: " + conn.getUuid()); _accountMgr.checkAccess(caller, null, false, conn); // Set vpn state to disconnected diff --git a/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java b/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java index 7a743e3ce767..95fdfa0fde89 100644 --- a/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java @@ -294,7 +294,7 @@ public Project doInTransaction(TransactionStatus status) { Optional.ofNullable(finalUser).map(User::getId).orElse(null), null); if (project != null) { - CallContext.current().setEventDetails("Project id=" + project.getId()); + CallContext.current().setEventDetails("Project ID: " + project.getUuid()); CallContext.current().putContextParameter(Project.class, project.getUuid()); } diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java b/server/src/main/java/com/cloud/server/ManagementServerImpl.java index 9de2af67738f..bd850094c375 100644 --- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java +++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java @@ -5705,7 +5705,7 @@ public HypervisorCapabilities updateHypervisorCapabilities(UpdateHypervisorCapab if (_hypervisorCapabilitiesDao.update(id, hpvCapabilities)) { hpvCapabilities = _hypervisorCapabilitiesDao.findById(id); - CallContext.current().setEventDetails("Hypervisor Capabilities id=" + hpvCapabilities.getId()); + CallContext.current().setEventDetails("Hypervisor Capabilities ID: " + hpvCapabilities.getUuid()); return hpvCapabilities; } else { return null; diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index 31bf80e6459b..17961dbd955f 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -694,7 +694,7 @@ public VolumeVO doInTransaction(TransactionStatus status) { volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId()); volume.setFormat(ImageFormat.valueOf(format)); volume = _volsDao.persist(volume); - CallContext.current().setEventDetails("Volume Id: " + volume.getUuid()); + CallContext.current().setEventDetails("Volume ID: " + volume.getUuid()); CallContext.current().putContextParameter(Volume.class, volume.getUuid()); // Increment resource count during allocation; if actual creation fails, @@ -1023,7 +1023,7 @@ public VolumeVO doInTransaction(TransactionStatus status) { } } - CallContext.current().setEventDetails("Volume Id: " + volume.getUuid()); + CallContext.current().setEventDetails("Volume ID: " + volume.getUuid()); CallContext.current().putContextParameter(Volume.class, volume.getId()); // Increment resource count during allocation; if actual creation fails, // decrement it @@ -4242,7 +4242,7 @@ public String extractVolume(ExtractVolumeCmd cmd) { Optional extractUrl = setExtractVolumeSearchCriteria(sc, volume); if (extractUrl.isPresent()) { String url = extractUrl.get(); - CallContext.current().setEventDetails(String.format("Download URL: %s, volume ID: %s", url, volume.getUuid())); + CallContext.current().setEventDetails(String.format("Download URL: %s, Volume ID: %s", url, volume.getUuid())); return url; } @@ -4261,7 +4261,7 @@ public String extractVolume(ExtractVolumeCmd cmd) { placeHolder = createPlaceHolderWork(vm.getId()); try { String url = orchestrateExtractVolume(volume.getId(), zoneId); - CallContext.current().setEventDetails(String.format("Download URL: %s, volume ID: %s", url, volume.getUuid())); + CallContext.current().setEventDetails(String.format("Download URL: %s, Volume ID: %s", url, volume.getUuid())); return url; } finally { _workJobDao.expunge(placeHolder.getId()); @@ -4292,7 +4292,7 @@ public String extractVolume(ExtractVolumeCmd cmd) { // retrieve the entity url from job result if (jobResult != null && jobResult instanceof String) { String url = (String) jobResult; - CallContext.current().setEventDetails(String.format("Download URL: %s, volume ID: %s", url, volume.getUuid())); + CallContext.current().setEventDetails(String.format("Download URL: %s, Volume ID: %s", url, volume.getUuid())); return url; } return null; @@ -4300,7 +4300,7 @@ public String extractVolume(ExtractVolumeCmd cmd) { } String url = orchestrateExtractVolume(volume.getId(), zoneId); - CallContext.current().setEventDetails(String.format("Download URL: %s, volume ID: %s", url, volume.getUuid())); + CallContext.current().setEventDetails(String.format("Download URL: %s, Volume ID: %s", url, volume.getUuid())); return url; } diff --git a/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java index 2e4deafe576b..a7a6cea7d907 100644 --- a/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java @@ -356,7 +356,7 @@ public List doInTransaction(TransactionStatus // Set Event Details for Template/ISO Upload String eventType = template.getFormat().equals(ImageFormat.ISO) ? "Iso" : "Template"; String eventResourceId = template.getUuid(); - CallContext.current().setEventDetails(String.format("%s Id: %s", eventType, eventResourceId)); + CallContext.current().setEventDetails(String.format("%s ID: %s", eventType, eventResourceId)); CallContext.current().putContextParameter(eventType.equals("Iso") ? eventType : VirtualMachineTemplate.class, eventResourceId); if (template.getFormat().equals(ImageFormat.ISO)) { CallContext.current().setEventResourceType(ApiCommandResourceType.Iso); diff --git a/server/src/main/java/com/cloud/template/TemplateAdapterBase.java b/server/src/main/java/com/cloud/template/TemplateAdapterBase.java index b50acedddc08..97c6e5903592 100644 --- a/server/src/main/java/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/main/java/com/cloud/template/TemplateAdapterBase.java @@ -405,7 +405,7 @@ public TemplateProfile prepare(boolean isIso, long userId, String name, String d } Long id = _tmpltDao.getNextInSequence(Long.class, "id"); - CallContext.current().setEventDetails("Id: " + id + " name: " + name); + CallContext.current().setEventDetails("ID: " + id + " name: " + name); TemplateProfile profile = new TemplateProfile(id, userId, name, displayText, arch, bits, passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, imgfmt, guestOSId, zoneIdList, hypervisorType, templateOwner.getAccountName(), templateOwner.getDomainId(), templateOwner.getAccountId(), chksum, bootable, templateTag, details, sshkeyEnabled, null, isDynamicallyScalable, templateType, directDownload, deployAsIs, extensionId); diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index 0b05a0d9c3db..3566bc994571 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -519,7 +519,7 @@ public String extract(ExtractTemplateCmd cmd) { } String extractUrl = extract(caller, templateId, url, zoneId, mode, eventId, false); - CallContext.current().setEventDetails(String.format("Download URL: %s, template ID: %s", extractUrl, template.getUuid())); + CallContext.current().setEventDetails(String.format("Download URL: %s, Template ID: %s", extractUrl, template.getUuid())); return extractUrl; } @@ -1200,7 +1200,7 @@ public boolean detachIso(long vmId, Long isoParamId, Boolean... extraParams) { if (isoId == null) { throw new InvalidParameterValueException("The specified instance has no ISO attached to it."); } - CallContext.current().setEventDetails("Vm Id: " + virtualMachine.getUuid() + " ISO Id: " + isoId); + CallContext.current().setEventDetails("Vm ID: " + virtualMachine.getUuid() + " ISO ID: " + isoId); State vmState = virtualMachine.getState(); if (vmState != State.Running && vmState != State.Stopped) { diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index b9b6e5a68391..9a052e1d42d8 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -9436,7 +9436,7 @@ private void detachVolumesFromVm(UserVm vm, List volumes) { // Create new context and inject correct event resource type, id and details, // otherwise VOLUME.DETACH event will be associated with VirtualMachine and contain VM id and other information. CallContext volumeContext = CallContext.register(CallContext.current(), ApiCommandResourceType.Volume); - volumeContext.setEventDetails("Volume Type: " + volume.getVolumeType() + " Volume Id: " + this._uuidMgr.getUuid(Volume.class, volume.getId()) + " Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, volume.getInstanceId())); + volumeContext.setEventDetails("Volume Type: " + volume.getVolumeType() + " Volume ID: " + volume.getUuid() + " Instance ID: " + vm.getUuid()); volumeContext.setEventResourceType(ApiCommandResourceType.Volume); volumeContext.setEventResourceId(volume.getId()); @@ -9465,7 +9465,7 @@ private void destroyVolumeInContext(UserVmVO vm, boolean expunge, VolumeVO volum // Create new context and inject correct event resource type, id and details, // otherwise VOLUME.DESTROY event will be associated with VirtualMachine and contain VM id and other information. CallContext volumeContext = CallContext.register(CallContext.current(), ApiCommandResourceType.Volume); - volumeContext.setEventDetails("Volume Type: " + volume.getVolumeType() + " Volume Id: " + this._uuidMgr.getUuid(Volume.class, volume.getId()) + " Vm Id: " + vm.getUuid()); + volumeContext.setEventDetails("Volume Type: " + volume.getVolumeType() + " Volume ID: " + volume.getUuid() + " Instance ID: " + vm.getUuid()); volumeContext.setEventResourceType(ApiCommandResourceType.Volume); volumeContext.setEventResourceId(volume.getId()); try { diff --git a/server/src/main/java/org/apache/cloudstack/ca/CAManagerImpl.java b/server/src/main/java/org/apache/cloudstack/ca/CAManagerImpl.java index 22f8939e7eb7..2b4e7ddc9d41 100644 --- a/server/src/main/java/org/apache/cloudstack/ca/CAManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/ca/CAManagerImpl.java @@ -181,7 +181,7 @@ public boolean provisionCertificate(final Host host, final Boolean reconnect, fi if (host == null) { throw new CloudRuntimeException("Unable to find valid host to renew certificate for"); } - CallContext.current().setEventDetails("host id: " + host.getId()); + CallContext.current().setEventDetails("Host ID: " + host.getUuid()); CallContext.current().putContextParameter(Host.class, host.getUuid()); String csr = null; @@ -206,7 +206,7 @@ public String generateKeyStoreAndCsr(final Host host, final Map if (sshAccessDetails != null && !sshAccessDetails.isEmpty()) { cmd.setAccessDetail(sshAccessDetails); } - CallContext.current().setEventDetails("generating keystore and CSR for host id: " + host.getId()); + CallContext.current().setEventDetails("generating keystore and CSR for Host with ID: " + host.getUuid()); final SetupKeystoreAnswer answer = (SetupKeystoreAnswer)agentManager.send(host.getId(), cmd); return answer.getCsr(); } @@ -223,12 +223,12 @@ public boolean deployCertificate(final Host host, final Certificate certificate, if (sshAccessDetails != null && !sshAccessDetails.isEmpty()) { cmd.setAccessDetail(sshAccessDetails); } - CallContext.current().setEventDetails("deploying certificate for host id: " + host.getId()); + CallContext.current().setEventDetails("deploying certificate for Host with ID: " + host.getUuid()); final SetupCertificateAnswer answer = (SetupCertificateAnswer)agentManager.send(host.getId(), cmd); if (answer.getResult()) { - CallContext.current().setEventDetails("successfully deployed certificate for host id: " + host.getId()); + CallContext.current().setEventDetails("successfully deployed certificate for Host with ID: " + host.getUuid()); } else { - CallContext.current().setEventDetails("failed to deploy certificate for host id: " + host.getId()); + CallContext.current().setEventDetails("failed to deploy certificate for Host with ID: " + host.getUuid()); } if (answer.getResult()) { diff --git a/server/src/main/java/org/apache/cloudstack/gui/theme/GuiThemeServiceImpl.java b/server/src/main/java/org/apache/cloudstack/gui/theme/GuiThemeServiceImpl.java index 78bcb6bbc037..1cb80e3dc8d3 100644 --- a/server/src/main/java/org/apache/cloudstack/gui/theme/GuiThemeServiceImpl.java +++ b/server/src/main/java/org/apache/cloudstack/gui/theme/GuiThemeServiceImpl.java @@ -433,9 +433,9 @@ protected String ifBlankReturnNull(String value) { public void removeGuiTheme(RemoveGuiThemeCmd cmd) { Long guiThemeId = cmd.getId(); GuiThemeVO guiThemeVO = guiThemeDao.findById(guiThemeId); - CallContext.current().setEventDetails(String.format("ID: %s", guiThemeId)); if (guiThemeVO != null) { + CallContext.current().setEventDetails(String.format("ID: %s", guiThemeVO.getUuid())); guiThemeDao.remove(guiThemeId); } else { logger.error("Unable to find a GUI theme with the specified ID [{}].", guiThemeId); diff --git a/server/src/main/java/org/apache/cloudstack/network/RoutedIpv4ManagerImpl.java b/server/src/main/java/org/apache/cloudstack/network/RoutedIpv4ManagerImpl.java index 5e49872c64db..a03db4d4a241 100644 --- a/server/src/main/java/org/apache/cloudstack/network/RoutedIpv4ManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/network/RoutedIpv4ManagerImpl.java @@ -926,7 +926,7 @@ public FirewallRuleVO doInTransaction(TransactionStatus status) throws NetworkRu if (!firewallDao.setStateToAdd(newRule)) { throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } - CallContext.current().setEventDetails("Rule Id: " + newRule.getId()); + CallContext.current().setEventDetails("Rule ID: " + newRule.getUuid()); return newRule; } diff --git a/server/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java b/server/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java index bbfa83dcf434..dc806b9fdd57 100644 --- a/server/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java @@ -181,7 +181,7 @@ public ApplicationLoadBalancerRuleVO doInTransaction(TransactionStatus status) t throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } logger.debug("Load balancer rule {} for Ip address {}, source port {}, instance port {} is added successfully.", newRule, newRule.getSourceIp().addr(), newRule.getSourcePortStart(), newRule.getDefaultPortStart()); - CallContext.current().setEventDetails("Load balancer Id: " + newRule.getId()); + CallContext.current().setEventDetails("Load balancer ID: " + newRule.getUuid()); Network ntwk = _networkModel.getNetwork(newRule.getNetworkId()); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_CREATE, newRule.getAccountId(), ntwk.getDataCenterId(), newRule.getId(), null, LoadBalancingRule.class.getName(), newRule.getUuid()); From b1edfb8d606611ab0e60567a58419f1a4de5313c Mon Sep 17 00:00:00 2001 From: dahn Date: Thu, 12 Feb 2026 08:55:40 +0100 Subject: [PATCH 098/101] Remove and Update collaborators list in .asf.yaml (#12627) --- .asf.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.asf.yaml b/.asf.yaml index 092e06d97168..d13368d9bc55 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -53,13 +53,12 @@ github: - acs-robot - gpordeus - hsato03 - - FelipeM525 - - lucas-a-martins - - nicoschmdt - abh1sar - - rosi-shapeblue + - RosiKyu - sudo87 - erikbocks + - Imvedansh + - Damans227 protected_branches: ~ From c79b33c1fbd4840613fa8a09cbffc9b76ea0b1a1 Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Mon, 16 Feb 2026 16:01:42 +0530 Subject: [PATCH 099/101] Allow enforcing password change for a user after reset by admin (root/domain) (#12294) * API modifications for passwordchangerequired * ui login flow for passwordchangerequired * add passwordchangerequired in listUsers API response, it will be used in UI to render reset password form * cleanup redundant LOGIN_SOURCE and limiting apis for first time login * address copilot comments * allow enforcing password change for all role types and update reset pwd flow for passwordchangerequired * address review comments * add unit tests * cleanup ispasswordchangerequired from user_view * address review comments * 1. Allow enforcing password change while creating user 2. Admin can enforce password change on next login with out resetting password * address review comment, add unit test * improve code coverage * fix pre-commit license issue * 1. allow enter key to submit change password form 2. hide force password reset for disabled/locked user in ui * 1. throw exception when force reset password is done for locked/disabled user/account 2. ui validation on current and new password being same 3. allow enforce change password for add user until saml is not enabled * allow oauth login to skip force password change --- .../java/com/cloud/user/AccountService.java | 3 +- .../apache/cloudstack/api/ApiConstants.java | 1 + .../api/command/admin/user/CreateUserCmd.java | 13 +- .../api/command/admin/user/UpdateUserCmd.java | 14 +- .../api/response/LoginCmdResponse.java | 12 + .../command/admin/user/CreateUserCmdTest.java | 6 +- .../command/admin/user/UpdateUserCmdTest.java | 64 ++++ .../api/response/LoginCmdResponseTest.java | 87 ++++++ .../resourcedetail/UserDetailVO.java | 2 + .../discovery/ApiDiscoveryServiceImpl.java | 22 +- .../discovery/ApiDiscoveryTest.java | 38 +++ .../management/MockAccountManager.java | 2 +- .../OauthLoginAPIAuthenticatorCmd.java | 9 +- .../main/java/com/cloud/api/ApiServer.java | 13 + .../auth/DefaultLoginAPIAuthenticatorCmd.java | 9 +- .../com/cloud/user/AccountManagerImpl.java | 60 +++- .../user/UserPasswordResetManagerImpl.java | 3 + .../java/com/cloud/api/ApiServerTest.java | 124 +++++++- .../cloud/user/AccountManagerImplTest.java | 139 +++++++++ .../UserPasswordResetManagerImplTest.java | 27 ++ ui/public/locales/en.json | 7 + ui/src/config/router.js | 5 + ui/src/config/section/user.js | 18 ++ ui/src/permission.js | 23 ++ ui/src/store/getters.js | 3 +- ui/src/store/modules/user.js | 32 +- ui/src/store/mutation-types.js | 1 + ui/src/views/iam/AddUser.vue | 25 +- ui/src/views/iam/ChangeUserPassword.vue | 14 + ui/src/views/iam/ForceChangePassword.vue | 285 ++++++++++++++++++ 30 files changed, 1023 insertions(+), 38 deletions(-) create mode 100644 api/src/test/java/org/apache/cloudstack/api/command/admin/user/UpdateUserCmdTest.java create mode 100644 api/src/test/java/org/apache/cloudstack/api/response/LoginCmdResponseTest.java create mode 100644 ui/src/views/iam/ForceChangePassword.vue diff --git a/api/src/main/java/com/cloud/user/AccountService.java b/api/src/main/java/com/cloud/user/AccountService.java index b92654bfe174..eb47b75ac5ba 100644 --- a/api/src/main/java/com/cloud/user/AccountService.java +++ b/api/src/main/java/com/cloud/user/AccountService.java @@ -59,7 +59,8 @@ UserAccount createUserAccount(String userName, String password, String firstName User getSystemUser(); - User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID); + User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, + String accountName, Long domainId, String userUUID, boolean isPasswordChangeRequired); User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID, User.Source source); 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 1ab6fba6081f..9a8913da5b04 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -1261,6 +1261,7 @@ public class ApiConstants { public static final String PROVIDER_FOR_2FA = "providerfor2fa"; public static final String ISSUER_FOR_2FA = "issuerfor2fa"; public static final String MANDATE_2FA = "mandate2fa"; + public static final String PASSWORD_CHANGE_REQUIRED = "passwordchangerequired"; public static final String SECRET_CODE = "secretcode"; public static final String LOGIN = "login"; public static final String LOGOUT = "logout"; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java index f03bb1c4ddd3..684103cf8d39 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java @@ -26,6 +26,7 @@ import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.UserResponse; import org.apache.cloudstack.context.CallContext; +import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang3.StringUtils; import com.cloud.user.Account; @@ -78,6 +79,12 @@ public class CreateUserCmd extends BaseCmd { @Parameter(name = ApiConstants.USER_ID, type = CommandType.STRING, description = "User UUID, required for adding account from external provisioning system") private String userUUID; + @Parameter(name = ApiConstants.PASSWORD_CHANGE_REQUIRED, + type = CommandType.BOOLEAN, + description = "Provide true to mandate the User to reset password on next login.", + since = "4.23.0") + private Boolean passwordChangeRequired; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -118,6 +125,10 @@ public String getUserUUID() { return userUUID; } + public Boolean isPasswordChangeRequired() { + return BooleanUtils.isTrue(passwordChangeRequired); + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -147,7 +158,7 @@ public void execute() { CallContext.current().setEventDetails("UserName: " + getUserName() + ", FirstName :" + getFirstName() + ", LastName: " + getLastName()); User user = _accountService.createUser(getUserName(), getPassword(), getFirstName(), getLastName(), getEmail(), getTimezone(), getAccountName(), getDomainId(), - getUserUUID()); + getUserUUID(), isPasswordChangeRequired()); if (user != null) { UserResponse response = _responseGenerator.createUserResponse(user); response.setResponseName(getCommandName()); 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 b61550c70875..628ddb96deb8 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 @@ -29,6 +29,7 @@ import org.apache.cloudstack.api.response.UserResponse; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.region.RegionService; +import org.apache.commons.lang.BooleanUtils; import com.cloud.user.Account; import com.cloud.user.User; @@ -38,6 +39,8 @@ requestHasSensitiveInfo = true, responseHasSensitiveInfo = true) public class UpdateUserCmd extends BaseCmd { + @Inject + private RegionService _regionService; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -85,8 +88,11 @@ public class UpdateUserCmd extends BaseCmd { "This parameter is only used to mandate 2FA, not to disable 2FA", since = "4.18.0.0") private Boolean mandate2FA; - @Inject - private RegionService _regionService; + @Parameter(name = ApiConstants.PASSWORD_CHANGE_REQUIRED, + type = CommandType.BOOLEAN, + description = "Provide true to mandate the User to reset password on next login.", + since = "4.23.0") + private Boolean passwordChangeRequired; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -193,4 +199,8 @@ public Long getApiResourceId() { public ApiCommandResourceType getApiResourceType() { return ApiCommandResourceType.User; } + + public Boolean isPasswordChangeRequired() { + return BooleanUtils.isTrue(passwordChangeRequired); + } } diff --git a/api/src/main/java/org/apache/cloudstack/api/response/LoginCmdResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/LoginCmdResponse.java index c20f700fe08e..6e3ef4678d28 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/LoginCmdResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/LoginCmdResponse.java @@ -90,6 +90,10 @@ public class LoginCmdResponse extends AuthenticationCmdResponse { @Param(description = "Management Server ID that the user logged to", since = "4.21.0.0") private String managementServerId; + @SerializedName(value = ApiConstants.PASSWORD_CHANGE_REQUIRED) + @Param(description = "Indicates whether the User is required to change password on next login.", since = "4.23.0") + private Boolean passwordChangeRequired; + public String getUsername() { return username; } @@ -223,4 +227,12 @@ public String getManagementServerId() { public void setManagementServerId(String managementServerId) { this.managementServerId = managementServerId; } + + public Boolean getPasswordChangeRequired() { + return passwordChangeRequired; + } + + public void setPasswordChangeRequired(Boolean passwordChangeRequired) { + this.passwordChangeRequired = passwordChangeRequired; + } } diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/user/CreateUserCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/user/CreateUserCmdTest.java index 8a57ac3eb22c..397723dd6069 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/user/CreateUserCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/user/CreateUserCmdTest.java @@ -69,7 +69,7 @@ public void testExecuteWithNotBlankPassword() { } catch (ServerApiException e) { Assert.assertTrue("Received exception as the mock accountService createUser returns null user", true); } - Mockito.verify(accountService, Mockito.times(1)).createUser(null, "Test", null, null, null, null, null, null, null); + Mockito.verify(accountService, Mockito.times(1)).createUser(null, "Test", null, null, null, null, null, null, null, false); } @Test @@ -82,7 +82,7 @@ public void testExecuteWithNullPassword() { Assert.assertEquals(ApiErrorCode.PARAM_ERROR,e.getErrorCode()); Assert.assertEquals("Empty passwords are not allowed", e.getMessage()); } - Mockito.verify(accountService, Mockito.never()).createUser(null, null, null, null, null, null, null, null, null); + Mockito.verify(accountService, Mockito.never()).createUser(null, null, null, null, null, null, null, null, null, false); } @Test @@ -95,6 +95,6 @@ public void testExecuteWithEmptyPassword() { Assert.assertEquals(ApiErrorCode.PARAM_ERROR,e.getErrorCode()); Assert.assertEquals("Empty passwords are not allowed", e.getMessage()); } - Mockito.verify(accountService, Mockito.never()).createUser(null, null, null, null, null, null, null, null, null); + Mockito.verify(accountService, Mockito.never()).createUser(null, null, null, null, null, null, null, null, null, true); } } diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/user/UpdateUserCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/user/UpdateUserCmdTest.java new file mode 100644 index 000000000000..f86e51adb5ab --- /dev/null +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/user/UpdateUserCmdTest.java @@ -0,0 +1,64 @@ +/* + * 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.user; + +import org.apache.cloudstack.api.ApiCommandResourceType; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.test.util.ReflectionTestUtils; + +@RunWith(MockitoJUnitRunner.class) +public class UpdateUserCmdTest { + @InjectMocks + private UpdateUserCmd cmd; + + @Test + public void testGetApiResourceId() { + Long userId = 99L; + cmd.setId(userId); + Assert.assertEquals(userId, cmd.getApiResourceId()); + } + + @Test + public void testGetApiResourceType() { + Assert.assertEquals(ApiCommandResourceType.User, cmd.getApiResourceType()); + } + + @Test + public void testIsPasswordChangeRequired_True() { + ReflectionTestUtils.setField(cmd, "passwordChangeRequired", Boolean.TRUE); + Assert.assertTrue(cmd.isPasswordChangeRequired()); + } + + @Test + public void testIsPasswordChangeRequired_False() { + ReflectionTestUtils.setField(cmd, "passwordChangeRequired", Boolean.FALSE); + Assert.assertFalse(cmd.isPasswordChangeRequired()); + } + + @Test + public void testIsPasswordChangeRequired_Null() { + ReflectionTestUtils.setField(cmd, "passwordChangeRequired", null); + Assert.assertFalse(cmd.isPasswordChangeRequired()); + } +} diff --git a/api/src/test/java/org/apache/cloudstack/api/response/LoginCmdResponseTest.java b/api/src/test/java/org/apache/cloudstack/api/response/LoginCmdResponseTest.java new file mode 100644 index 000000000000..7811138fffe1 --- /dev/null +++ b/api/src/test/java/org/apache/cloudstack/api/response/LoginCmdResponseTest.java @@ -0,0 +1,87 @@ +// 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.response; + + +import org.junit.Assert; +import org.junit.Test; + +public class LoginCmdResponseTest { + + @Test + public void testAllGettersAndSetters() { + LoginCmdResponse response = new LoginCmdResponse(); + + response.setUsername("user1"); + response.setUserId("100"); + response.setDomainId("200"); + response.setTimeout(3600); + response.setAccount("account1"); + response.setFirstName("John"); + response.setLastName("Doe"); + response.setType("admin"); + response.setTimeZone("UTC"); + response.setTimeZoneOffset("+00:00"); + response.setRegistered("true"); + response.setSessionKey("session-key"); + response.set2FAenabled("true"); + response.set2FAverfied("false"); + response.setProviderFor2FA("totp"); + response.setIssuerFor2FA("cloudstack"); + response.setManagementServerId("ms-1"); + + Assert.assertEquals("user1", response.getUsername()); + Assert.assertEquals("100", response.getUserId()); + Assert.assertEquals("200", response.getDomainId()); + Assert.assertEquals(Integer.valueOf(3600), response.getTimeout()); + Assert.assertEquals("account1", response.getAccount()); + Assert.assertEquals("John", response.getFirstName()); + Assert.assertEquals("Doe", response.getLastName()); + Assert.assertEquals("admin", response.getType()); + Assert.assertEquals("UTC", response.getTimeZone()); + Assert.assertEquals("+00:00", response.getTimeZoneOffset()); + Assert.assertEquals("true", response.getRegistered()); + Assert.assertEquals("session-key", response.getSessionKey()); + Assert.assertEquals("true", response.is2FAenabled()); + Assert.assertEquals("false", response.is2FAverfied()); + Assert.assertEquals("totp", response.getProviderFor2FA()); + Assert.assertEquals("cloudstack", response.getIssuerFor2FA()); + Assert.assertEquals("ms-1", response.getManagementServerId()); + } + + @Test + public void testPasswordChangeRequired_True() { + LoginCmdResponse response = new LoginCmdResponse(); + response.setPasswordChangeRequired(true); + Assert.assertTrue(response.getPasswordChangeRequired()); + } + + @Test + public void testPasswordChangeRequired_False() { + LoginCmdResponse response = new LoginCmdResponse(); + response.setPasswordChangeRequired(false); + Assert.assertFalse(response.getPasswordChangeRequired()); + } + + @Test + public void testPasswordChangeRequired_Null() { + LoginCmdResponse response = new LoginCmdResponse(); + response.setPasswordChangeRequired(null); + Assert.assertNull("Boolean.parseBoolean(null) should return null", response.getPasswordChangeRequired()); + } +} diff --git a/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/UserDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/UserDetailVO.java index d0cfcc3d4396..93b49bc20a10 100644 --- a/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/UserDetailVO.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/UserDetailVO.java @@ -48,6 +48,8 @@ public class UserDetailVO implements ResourceDetail { public static final String Setup2FADetail = "2FASetupStatus"; public static final String PasswordResetToken = "PasswordResetToken"; public static final String PasswordResetTokenExpiryDate = "PasswordResetTokenExpiryDate"; + public static final String PasswordChangeRequired = "PasswordChangeRequired"; + public static final String OauthLogin = "OauthLogin"; public UserDetailVO() { } diff --git a/plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java b/plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java index d6d235162efb..4493f1e9074e 100644 --- a/plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java +++ b/plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java @@ -44,8 +44,10 @@ import org.apache.cloudstack.api.response.ApiParameterResponse; import org.apache.cloudstack.api.response.ApiResponseResponse; import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.resourcedetail.UserDetailVO; import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.reflections.ReflectionUtils; import org.springframework.stereotype.Component; @@ -56,6 +58,7 @@ import com.cloud.user.Account; import com.cloud.user.AccountService; import com.cloud.user.User; +import com.cloud.user.UserAccount; import com.cloud.utils.ReflectUtil; import com.cloud.utils.component.ComponentLifecycleBase; import com.cloud.utils.component.PluggableService; @@ -67,6 +70,7 @@ public class ApiDiscoveryServiceImpl extends ComponentLifecycleBase implements A List _apiAccessCheckers = null; List _services = null; protected static Map s_apiNameDiscoveryResponseMap = null; + public static final List APIS_ALLOWED_FOR_PASSWORD_CHANGE = Arrays.asList("login", "logout", "updateUser", "listApis"); @Inject AccountService accountService; @@ -287,12 +291,20 @@ public ListResponse listApis(User user, String name) { ReflectionToStringBuilderUtils.reflectOnlySelectedFields(account, "accountName", "uuid"))); } - if (role.getRoleType() == RoleType.Admin && role.getId() == RoleType.Admin.getId()) { - logger.info(String.format("Account [%s] is Root Admin, all APIs are allowed.", - ReflectionToStringBuilderUtils.reflectOnlySelectedFields(account, "accountName", "uuid"))); + // Limit APIs on first login requiring password change + UserAccount userAccount = accountService.getUserAccountById(user.getId()); + Map userAccDetails = userAccount.getDetails(); + if (MapUtils.isNotEmpty(userAccDetails) && !userAccDetails.containsKey(UserDetailVO.OauthLogin) && + "true".equalsIgnoreCase(userAccDetails.get(UserDetailVO.PasswordChangeRequired))) { + apisAllowed = APIS_ALLOWED_FOR_PASSWORD_CHANGE; } else { - for (APIChecker apiChecker : _apiAccessCheckers) { - apisAllowed = apiChecker.getApisAllowedToUser(role, user, apisAllowed); + if (role.getRoleType() == RoleType.Admin && role.getId() == RoleType.Admin.getId()) { + logger.info(String.format("Account [%s] is Root Admin, all APIs are allowed.", + ReflectionToStringBuilderUtils.reflectOnlySelectedFields(account, "accountName", "uuid"))); + } else { + for (APIChecker apiChecker : _apiAccessCheckers) { + apisAllowed = apiChecker.getApisAllowedToUser(role, user, apisAllowed); + } } } diff --git a/plugins/api/discovery/src/test/java/org/apache/cloudstack/discovery/ApiDiscoveryTest.java b/plugins/api/discovery/src/test/java/org/apache/cloudstack/discovery/ApiDiscoveryTest.java index eea78d8abb93..d33774cad031 100644 --- a/plugins/api/discovery/src/test/java/org/apache/cloudstack/discovery/ApiDiscoveryTest.java +++ b/plugins/api/discovery/src/test/java/org/apache/cloudstack/discovery/ApiDiscoveryTest.java @@ -21,6 +21,8 @@ import com.cloud.user.AccountService; import com.cloud.user.AccountVO; import com.cloud.user.User; +import com.cloud.user.UserAccount; +import com.cloud.user.UserAccountVO; import com.cloud.user.UserVO; import org.apache.cloudstack.acl.APIChecker; @@ -29,6 +31,8 @@ import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.RoleVO; import org.apache.cloudstack.api.response.ApiDiscoveryResponse; +import org.apache.cloudstack.api.response.ListResponse; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -39,11 +43,15 @@ import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; +import static org.apache.cloudstack.resourcedetail.UserDetailVO.PasswordChangeRequired; +import static org.apache.cloudstack.resourcedetail.UserDetailVO.Setup2FADetail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.anyLong; @RunWith(MockitoJUnitRunner.class) public class ApiDiscoveryTest { @@ -66,12 +74,17 @@ public class ApiDiscoveryTest { @InjectMocks ApiDiscoveryServiceImpl discoveryServiceSpy; + @Mock + UserAccount mockUserAccount; + @Before public void setup() { discoveryServiceSpy.s_apiNameDiscoveryResponseMap = apiNameDiscoveryResponseMapMock; discoveryServiceSpy._apiAccessCheckers = apiAccessCheckersMock; Mockito.when(discoveryServiceSpy._apiAccessCheckers.iterator()).thenReturn(Arrays.asList(apiCheckerMock).iterator()); + Mockito.when(mockUserAccount.getDetails()).thenReturn(null); + Mockito.when(accountServiceMock.getUserAccountById(anyLong())).thenReturn(mockUserAccount); } private User getTestUser() { @@ -131,4 +144,29 @@ public void listApisTestGetsApisAllowedToUserOnUserRole() throws PermissionDenie Mockito.verify(apiCheckerMock, Mockito.times(1)).getApisAllowedToUser(any(Role.class), any(User.class), anyList()); } + + @Test + public void listApisForUserWithoutEnforcedPwdChange() throws PermissionDeniedException { + RoleVO userRoleVO = new RoleVO(4L, "name", RoleType.User, "description"); + Map userDetails = new HashMap<>(); + userDetails.put(Setup2FADetail, UserAccountVO.Setup2FAstatus.ENABLED.name()); + Mockito.when(mockUserAccount.getDetails()).thenReturn(userDetails); + Mockito.when(accountServiceMock.getAccount(Mockito.anyLong())).thenReturn(getNormalAccount()); + Mockito.when(roleServiceMock.findRole(Mockito.anyLong())).thenReturn(userRoleVO); + discoveryServiceSpy.listApis(getTestUser(), null); + Mockito.verify(apiCheckerMock, Mockito.times(1)).getApisAllowedToUser(any(Role.class), any(User.class), anyList()); + } + + @Test + public void listApisForUserEnforcedPwdChange() throws PermissionDeniedException { + RoleVO userRoleVO = new RoleVO(4L, "name", RoleType.User, "description"); + Map userDetails = new HashMap<>(); + userDetails.put(PasswordChangeRequired, "true"); + Mockito.when(mockUserAccount.getDetails()).thenReturn(userDetails); + Mockito.when(accountServiceMock.getAccount(Mockito.anyLong())).thenReturn(getNormalAccount()); + Mockito.when(roleServiceMock.findRole(Mockito.anyLong())).thenReturn(userRoleVO); + Mockito.when(apiNameDiscoveryResponseMapMock.get(Mockito.anyString())).thenReturn(Mockito.mock(ApiDiscoveryResponse.class)); + ListResponse response = (ListResponse) discoveryServiceSpy.listApis(getTestUser(), null); + Assert.assertEquals(4, response.getResponses().size()); + } } diff --git a/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java index 4dffb405d1a3..d3714f148340 100644 --- a/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java +++ b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java @@ -131,7 +131,7 @@ public String[] createApiKeyAndSecretKey(final long userId) { } @Override - public User createUser(String arg0, String arg1, String arg2, String arg3, String arg4, String arg5, String arg6, Long arg7, String arg8) { + public User createUser(String arg0, String arg1, String arg2, String arg3, String arg4, String arg5, String arg6, Long arg7, String arg8, boolean arg9) { // TODO Auto-generated method stub return null; } diff --git a/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/OauthLoginAPIAuthenticatorCmd.java b/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/OauthLoginAPIAuthenticatorCmd.java index f9a1d10d3526..ced34068bb87 100644 --- a/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/OauthLoginAPIAuthenticatorCmd.java +++ b/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/OauthLoginAPIAuthenticatorCmd.java @@ -34,6 +34,8 @@ import org.apache.cloudstack.api.auth.APIAuthenticator; import org.apache.cloudstack.api.auth.PluggableAPIAuthenticator; import org.apache.cloudstack.api.response.LoginCmdResponse; +import org.apache.cloudstack.resourcedetail.UserDetailVO; +import org.apache.cloudstack.resourcedetail.dao.UserDetailsDao; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.Nullable; @@ -74,6 +76,9 @@ public class OauthLoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent @Inject ApiServerService _apiServer; + @Inject + UserDetailsDao userDetailsDao; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -157,8 +162,10 @@ private String doOauthAuthentication(HttpSession session, Long domainId, String if (userAccount != null && User.Source.SAML2 == userAccount.getSource()) { throw new CloudAuthenticationException("User is not allowed CloudStack login"); } - return ApiResponseSerializer.toSerializedString(_apiServer.loginUser(session, userAccount.getUsername(), null, domainId, domain, remoteAddress, params), + serializedResponse = ApiResponseSerializer.toSerializedString(_apiServer.loginUser(session, userAccount.getUsername(), null, domainId, domain, remoteAddress, params), responseType); + userDetailsDao.addDetail(userAccount.getId(), UserDetailVO.OauthLogin, "true", false); + return serializedResponse; } catch (final CloudAuthenticationException ex) { ApiServlet.invalidateHttpSession(session, "fall through to API key,"); String msg = String.format("%s", ex.getMessage() != null ? diff --git a/server/src/main/java/com/cloud/api/ApiServer.java b/server/src/main/java/com/cloud/api/ApiServer.java index 95aca28b53f2..4a6a11803637 100644 --- a/server/src/main/java/com/cloud/api/ApiServer.java +++ b/server/src/main/java/com/cloud/api/ApiServer.java @@ -116,9 +116,11 @@ import org.apache.cloudstack.framework.messagebus.MessageDispatcher; import org.apache.cloudstack.framework.messagebus.MessageHandler; import org.apache.cloudstack.managed.context.ManagedContextRunnable; +import org.apache.cloudstack.resourcedetail.UserDetailVO; import org.apache.cloudstack.user.UserPasswordResetManager; import org.apache.cloudstack.utils.identity.ManagementServerNode; import org.apache.commons.codec.binary.Base64; +import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.EnumUtils; import org.apache.http.ConnectionClosedException; import org.apache.http.HttpException; @@ -194,6 +196,7 @@ import com.google.gson.reflect.TypeToken; import static com.cloud.user.AccountManagerImpl.apiKeyAccess; +import static org.apache.cloudstack.api.ApiConstants.PASSWORD_CHANGE_REQUIRED; import static org.apache.cloudstack.user.UserPasswordResetManager.UserPasswordResetEnabled; @Component @@ -1227,6 +1230,9 @@ private ResponseObject createLoginResponse(HttpSession session) { if (ApiConstants.MANAGEMENT_SERVER_ID.equalsIgnoreCase(attrName)) { response.setManagementServerId(attrObj.toString()); } + if (PASSWORD_CHANGE_REQUIRED.equalsIgnoreCase(attrName) && attrObj instanceof Boolean) { + response.setPasswordChangeRequired((Boolean) attrObj); + } } } response.setResponseName("loginresponse"); @@ -1327,6 +1333,13 @@ public ResponseObject loginUser(final HttpSession session, final String username final String sessionKey = Base64.encodeBase64URLSafeString(sessionKeyBytes); session.setAttribute(ApiConstants.SESSIONKEY, sessionKey); + Map userAccDetails = userAcct.getDetails(); + if (MapUtils.isNotEmpty(userAccDetails)) { + String needPwdChangeStr = userAccDetails.get(UserDetailVO.PasswordChangeRequired); + if ("true".equalsIgnoreCase(needPwdChangeStr)) { + session.setAttribute(PASSWORD_CHANGE_REQUIRED, true); + } + } return createLoginResponse(session); } throw new CloudAuthenticationException("Failed to authenticate user " + username + " in domain " + domainId + "; please provide valid credentials"); diff --git a/server/src/main/java/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java b/server/src/main/java/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java index c9b03a85f4c7..dc220b1b8369 100644 --- a/server/src/main/java/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java +++ b/server/src/main/java/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java @@ -34,6 +34,8 @@ import org.apache.cloudstack.api.auth.APIAuthenticator; import org.apache.cloudstack.api.auth.PluggableAPIAuthenticator; import org.apache.cloudstack.api.response.LoginCmdResponse; +import org.apache.cloudstack.resourcedetail.UserDetailVO; +import org.apache.cloudstack.resourcedetail.dao.UserDetailsDao; import org.jetbrains.annotations.Nullable; import javax.inject.Inject; @@ -66,6 +68,9 @@ public class DefaultLoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthe @Inject ApiServerService _apiServer; + @Inject + UserDetailsDao userDetailsDao; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -151,8 +156,10 @@ public String authenticate(String command, Map params, HttpSes if (userAccount != null && User.Source.SAML2 == userAccount.getSource()) { throw new CloudAuthenticationException("User is not allowed CloudStack login"); } - return ApiResponseSerializer.toSerializedString(_apiServer.loginUser(session, username[0], pwd, domainId, domain, remoteAddress, params), + serializedResponse = ApiResponseSerializer.toSerializedString(_apiServer.loginUser(session, username[0], pwd, domainId, domain, remoteAddress, params), responseType); + userDetailsDao.removeDetail(userAccount.getId(), UserDetailVO.OauthLogin); + return serializedResponse; } catch (final CloudAuthenticationException ex) { ApiServlet.invalidateHttpSession(session, "fall through to API key,"); // TODO: fall through to API key, or just fail here w/ auth error? (HTTP 401) diff --git a/server/src/main/java/com/cloud/user/AccountManagerImpl.java b/server/src/main/java/com/cloud/user/AccountManagerImpl.java index 53b88690654e..f0be13d858d3 100644 --- a/server/src/main/java/com/cloud/user/AccountManagerImpl.java +++ b/server/src/main/java/com/cloud/user/AccountManagerImpl.java @@ -16,6 +16,8 @@ // under the License. package com.cloud.user; +import static org.apache.cloudstack.resourcedetail.UserDetailVO.PasswordChangeRequired; + import java.net.InetAddress; import java.net.URLEncoder; import java.security.NoSuchAlgorithmException; @@ -1509,12 +1511,24 @@ private List getEnabledApiCheckers() { @Override @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User") public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID, - User.Source source) { + User.Source source) { + return createUser(userName, password, firstName, lastName, email, timeZone, accountName, domainId, userUUID, source, false); + } + + + @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User") + public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID, + User.Source source, boolean isPasswordChangeRequired) { // default domain to ROOT if not specified if (domainId == null) { domainId = Domain.ROOT_DOMAIN; } + if (isPasswordChangeRequired && (source == User.Source.SAML2 || source == User.Source.SAML2DISABLED || source == User.Source.LDAP)) { + logger.warn("Enforcing password change is not permitted for source [{}].", source); + throw new InvalidParameterValueException("CloudStack does not support enforcing password change for SAML or LDAP users."); + } + Domain domain = _domainMgr.getDomain(domainId); if (domain == null) { throw new CloudRuntimeException("The domain " + domainId + " does not exist; unable to create user"); @@ -1545,14 +1559,21 @@ public UserVO createUser(String userName, String password, String firstName, Str verifyCallerPrivilegeForUserOrAccountOperations(account); UserVO user; user = createUser(account.getId(), userName, password, firstName, lastName, email, timeZone, userUUID, source); + if (isPasswordChangeRequired) { + long callerAccountId = CallContext.current().getCallingAccountId(); + if ((isRootAdmin(callerAccountId) || isDomainAdmin(callerAccountId))) { + _userDetailsDao.addDetail(user.getId(), PasswordChangeRequired, "true", false); + } + } return user; } @Override @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User") - public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID) { + public UserVO createUser(String userName, String password, String firstName, String lastName, String email, + String timeZone, String accountName, Long domainId, String userUUID, boolean isPasswordChangeRequired) { - return createUser(userName, password, firstName, lastName, email, timeZone, accountName, domainId, userUUID, User.Source.UNKNOWN); + return createUser(userName, password, firstName, lastName, email, timeZone, accountName, domainId, userUUID, User.Source.UNKNOWN, isPasswordChangeRequired); } @Override @@ -1586,10 +1607,41 @@ public UserAccount updateUser(UpdateUserCmd updateUserCmd) { if (mandate2FA != null && mandate2FA) { user.setUser2faEnabled(true); } + validateAndUpdatePasswordChangeRequired(caller, updateUserCmd, user, account); _userDao.update(user.getId(), user); return _userAccountDao.findById(user.getId()); } + private void validateAndUpdatePasswordChangeRequired(User caller, UpdateUserCmd updateUserCmd, UserVO user, Account account) { + if (updateUserCmd.isPasswordChangeRequired()) { + if (user.getState() != State.ENABLED || account.getState() != State.ENABLED) { + throw new CloudRuntimeException("CloudStack does not support enforcing password change for locked/disabled User or Account."); + } + + User.Source userSource = user.getSource(); + if (userSource == User.Source.SAML2 || userSource == User.Source.SAML2DISABLED || userSource == User.Source.LDAP) { + logger.warn("Enforcing password change is not permitted for source [{}].", user.getSource()); + throw new InvalidParameterValueException("CloudStack does not support enforcing password change for SAML or LDAP users."); + } + } + + boolean isCallerSameAsUser = user.getId() == caller.getId(); + boolean isPasswordResetRequired = updateUserCmd.isPasswordChangeRequired() && !isCallerSameAsUser; + // Admins only can enforce passwordChangeRequired for user + if (isRootAdmin(caller.getAccountId()) || isDomainAdmin(caller.getAccountId())) { + if (isPasswordResetRequired) { + _userDetailsDao.addDetail(user.getId(), PasswordChangeRequired, "true", false); + } + } + + if (StringUtils.isNotBlank(updateUserCmd.getPassword())) { + // Remove passwordChangeRequired if user updating own pwd or admin has not enforced it + if (isCallerSameAsUser || !isPasswordResetRequired) { + _userDetailsDao.removeDetail(user.getId(), PasswordChangeRequired); + } + } + } + @Override public void verifyCallerPrivilegeForUserOrAccountOperations(Account userAccount) { logger.debug(String.format("Verifying whether the caller has the correct privileges based on the user's role type and API permissions: %s", userAccount)); @@ -2848,6 +2900,8 @@ public UserAccount authenticateUser(final String username, final String password logger.debug(String.format("User: %s in domain %d has successfully logged in, auth time duration - %d ms", username, domainId, validUserLastAuthTimeDurationInMs)); } + user.setDetails(_userDetailsDao.listDetailsKeyPairs(user.getId())); + return user; } else { if (logger.isDebugEnabled()) { diff --git a/server/src/main/java/org/apache/cloudstack/user/UserPasswordResetManagerImpl.java b/server/src/main/java/org/apache/cloudstack/user/UserPasswordResetManagerImpl.java index c62bca8eca4b..d6b5dbb18f9f 100644 --- a/server/src/main/java/org/apache/cloudstack/user/UserPasswordResetManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/user/UserPasswordResetManagerImpl.java @@ -50,6 +50,7 @@ import java.util.UUID; import static org.apache.cloudstack.config.ApiServiceConfiguration.ManagementServerAddresses; +import static org.apache.cloudstack.resourcedetail.UserDetailVO.PasswordChangeRequired; import static org.apache.cloudstack.resourcedetail.UserDetailVO.PasswordResetToken; import static org.apache.cloudstack.resourcedetail.UserDetailVO.PasswordResetTokenExpiryDate; @@ -265,6 +266,8 @@ void resetPassword(UserAccount userAccount, String password) { userDetailsDao.removeDetail(userAccount.getId(), PasswordResetToken); userDetailsDao.removeDetail(userAccount.getId(), PasswordResetTokenExpiryDate); + // remove password change required if user reset password + userDetailsDao.removeDetail(userAccount.getId(), PasswordChangeRequired); userDao.persist(user); } diff --git a/server/src/test/java/com/cloud/api/ApiServerTest.java b/server/src/test/java/com/cloud/api/ApiServerTest.java index dedd6e02ec5c..2caf6bf9fae6 100644 --- a/server/src/test/java/com/cloud/api/ApiServerTest.java +++ b/server/src/test/java/com/cloud/api/ApiServerTest.java @@ -17,11 +17,21 @@ package com.cloud.api; import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; +import com.cloud.exception.CloudAuthenticationException; import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.DomainManager; import com.cloud.user.User; import com.cloud.user.UserAccount; +import com.cloud.user.UserVO; import com.cloud.utils.exception.CloudRuntimeException; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ResponseObject; +import org.apache.cloudstack.api.response.LoginCmdResponse; import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.resourcedetail.UserDetailVO; import org.apache.cloudstack.user.UserPasswordResetManager; import org.junit.AfterClass; import org.junit.Assert; @@ -35,10 +45,22 @@ import org.mockito.junit.MockitoJUnitRunner; import java.lang.reflect.Field; +import java.net.InetAddress; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import static org.apache.cloudstack.api.ApiConstants.PASSWORD_CHANGE_REQUIRED; import static org.apache.cloudstack.user.UserPasswordResetManager.UserPasswordResetEnabled; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; + +import javax.servlet.http.HttpSession; @RunWith(MockitoJUnitRunner.class) public class ApiServerTest { @@ -49,6 +71,15 @@ public class ApiServerTest { @Mock UserPasswordResetManager userPasswordResetManager; + @Mock + DomainManager domainManager; + + @Mock + AccountManager accountManager; + + @Mock + HttpSession session; + @BeforeClass public static void beforeClass() throws Exception { overrideDefaultConfigValue(UserPasswordResetEnabled, "_value", true); @@ -96,8 +127,8 @@ public void testSetupIntegrationPortListenerValidPort() { @Test public void testForgotPasswordSuccess() { - UserAccount userAccount = Mockito.mock(UserAccount.class); - Domain domain = Mockito.mock(Domain.class); + UserAccount userAccount = mock(UserAccount.class); + Domain domain = mock(Domain.class); Mockito.when(userAccount.getEmail()).thenReturn("test@test.com"); Mockito.when(userAccount.getState()).thenReturn("ENABLED"); @@ -110,8 +141,8 @@ public void testForgotPasswordSuccess() { @Test(expected = CloudRuntimeException.class) public void testForgotPasswordFailureNoEmail() { - UserAccount userAccount = Mockito.mock(UserAccount.class); - Domain domain = Mockito.mock(Domain.class); + UserAccount userAccount = mock(UserAccount.class); + Domain domain = mock(Domain.class); Mockito.when(userAccount.getEmail()).thenReturn(""); apiServer.forgotPassword(userAccount, domain); @@ -119,8 +150,8 @@ public void testForgotPasswordFailureNoEmail() { @Test(expected = CloudRuntimeException.class) public void testForgotPasswordFailureDisabledUser() { - UserAccount userAccount = Mockito.mock(UserAccount.class); - Domain domain = Mockito.mock(Domain.class); + UserAccount userAccount = mock(UserAccount.class); + Domain domain = mock(Domain.class); Mockito.when(userAccount.getEmail()).thenReturn("test@test.com"); Mockito.when(userAccount.getState()).thenReturn("DISABLED"); @@ -129,8 +160,8 @@ public void testForgotPasswordFailureDisabledUser() { @Test(expected = CloudRuntimeException.class) public void testForgotPasswordFailureDisabledAccount() { - UserAccount userAccount = Mockito.mock(UserAccount.class); - Domain domain = Mockito.mock(Domain.class); + UserAccount userAccount = mock(UserAccount.class); + Domain domain = mock(Domain.class); Mockito.when(userAccount.getEmail()).thenReturn("test@test.com"); Mockito.when(userAccount.getState()).thenReturn("ENABLED"); @@ -140,8 +171,8 @@ public void testForgotPasswordFailureDisabledAccount() { @Test(expected = CloudRuntimeException.class) public void testForgotPasswordFailureInactiveDomain() { - UserAccount userAccount = Mockito.mock(UserAccount.class); - Domain domain = Mockito.mock(Domain.class); + UserAccount userAccount = mock(UserAccount.class); + Domain domain = mock(Domain.class); Mockito.when(userAccount.getEmail()).thenReturn("test@test.com"); Mockito.when(userAccount.getState()).thenReturn("ENABLED"); @@ -153,8 +184,8 @@ public void testForgotPasswordFailureInactiveDomain() { @Test public void testVerifyApiKeyAccessAllowed() { Long domainId = 1L; - User user = Mockito.mock(User.class); - Account account = Mockito.mock(Account.class); + User user = mock(User.class); + Account account = mock(Account.class); Mockito.when(user.getApiKeyAccess()).thenReturn(true); Assert.assertEquals(true, apiServer.verifyApiKeyAccessAllowed(user, account)); @@ -176,4 +207,73 @@ public void testVerifyApiKeyAccessAllowed() { Mockito.when(account.getApiKeyAccess()).thenReturn(null); Assert.assertEquals(true, apiServer.verifyApiKeyAccessAllowed(user, account)); } + + @Test + public void testLoginUserSuccess() throws Exception { + String username = "user"; + String password = "password"; + Long domainId = 1L; + String domainPath = "/"; + InetAddress loginIp = InetAddress.getByName("127.0.0.1"); + Map requestParams = new HashMap<>(); + + DomainVO domain = mock(DomainVO.class); + Mockito.when(domain.getId()).thenReturn(domainId); + Mockito.when(domain.getUuid()).thenReturn("domain-uuid"); + + Mockito.when(domainManager.findDomainByIdOrPath(domainId, domainPath)).thenReturn(domain); + Mockito.when(domainManager.getDomain(domainId)).thenReturn(domain); + + UserAccount userAccount = mock(UserAccount.class); + Mockito.when(userAccount.getId()).thenReturn(100L); + Mockito.when(userAccount.getAccountId()).thenReturn(200L); + Mockito.when(userAccount.getUsername()).thenReturn(username); + Mockito.when(userAccount.getFirstname()).thenReturn("First"); + Mockito.when(userAccount.getLastname()).thenReturn("Last"); + Mockito.when(userAccount.getTimezone()).thenReturn("UTC"); + Mockito.when(userAccount.getRegistrationToken()).thenReturn("token"); + Mockito.when(userAccount.isRegistered()).thenReturn(true); + Mockito.when(userAccount.getDomainId()).thenReturn(domainId); + Map userAccDetails = new HashMap<>(); + userAccDetails.put(UserDetailVO.PasswordChangeRequired, "true"); + Mockito.when(userAccount.getDetails()).thenReturn(userAccDetails); + + Mockito.when(accountManager.authenticateUser(username, password, domainId, loginIp, requestParams)).thenReturn(userAccount); + Mockito.when(accountManager.clearUserTwoFactorAuthenticationInSetupStateOnLogin(userAccount)).thenReturn(userAccount); + + Account account = mock(Account.class); + Mockito.when(account.getAccountName()).thenReturn("account"); + Mockito.when(account.getDomainId()).thenReturn(domainId); + Mockito.when(account.getType()).thenReturn(Account.Type.NORMAL); + Mockito.when(account.getType()).thenReturn(Account.Type.NORMAL); + Mockito.when(accountManager.getAccount(200L)).thenReturn(account); + + UserVO userVO = mock(UserVO.class); + Mockito.when(userVO.getUuid()).thenReturn("user-uuid"); + Mockito.when(accountManager.getActiveUser(100L)).thenReturn(userVO); + + Mockito.when(session.getAttributeNames()).thenReturn(Collections.enumeration(List.of(PASSWORD_CHANGE_REQUIRED))); + Mockito.when(session.getAttribute(PASSWORD_CHANGE_REQUIRED)).thenReturn(Boolean.TRUE); + + ResponseObject response = apiServer.loginUser(session, username, password, domainId, domainPath, loginIp, requestParams); + Assert.assertNotNull(response); + Assert.assertTrue(response instanceof LoginCmdResponse); + Mockito.verify(session).setAttribute(eq("userid"), eq(100L)); + Mockito.verify(session).setAttribute(eq(ApiConstants.SESSIONKEY), anyString()); + } + + @Test(expected = CloudAuthenticationException.class) + public void testLoginUserDomainNotFound() throws Exception { + Mockito.when(domainManager.findDomainByIdOrPath(anyLong(), anyString())).thenReturn(null); + apiServer.loginUser(session, "user", "pass", 1L, "/", null, null); + } + + @Test(expected = CloudAuthenticationException.class) + public void testLoginUserAuthFailed() throws Exception { + DomainVO domain = mock(DomainVO.class); + Mockito.when(domain.getId()).thenReturn(1L); + Mockito.when(domainManager.findDomainByIdOrPath(anyLong(), anyString())).thenReturn(domain); + Mockito.when(accountManager.authenticateUser(anyString(), anyString(), anyLong(), any(), any())).thenReturn(null); + apiServer.loginUser(session, "user", "pass", 1L, "/", null, null); + } } diff --git a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java index c33cb334e77f..d429d7c70768 100644 --- a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java +++ b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java @@ -23,6 +23,7 @@ import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -432,6 +433,44 @@ public void updateUserTestTimeZoneAndEmailNotNull() { prepareMockAndExecuteUpdateUserTest(1); } + @Test(expected = CloudRuntimeException.class) + public void updateUserTestPwdChangeDisabledUser() { + Mockito.when(userVoMock.getState()).thenReturn(State.DISABLED); + updateUserPwdChange(); + } + + @Test(expected = CloudRuntimeException.class) + public void updateUserTestPwdChangeLockedUser() { + Mockito.when(userVoMock.getState()).thenReturn(State.LOCKED); + updateUserPwdChange(); + } + + @Test(expected = CloudRuntimeException.class) + public void updateUserTestPwdChangeDisabledAccount() { + Mockito.when(userVoMock.getState()).thenReturn(State.ENABLED); + Mockito.when(accountMock.getState()).thenReturn(State.LOCKED); + updateUserPwdChange(); + } + + @Test + public void testUpdateUserTestPwdChange() { + Mockito.when(userVoMock.getState()).thenReturn(State.ENABLED); + Mockito.when(accountMock.getState()).thenReturn(State.ENABLED); + updateUserPwdChange(); + } + + private void updateUserPwdChange() { + Mockito.doReturn(true).when(UpdateUserCmdMock).isPasswordChangeRequired(); + Mockito.when(userVoMock.getAccountId()).thenReturn(10L); + Mockito.doReturn(accountMock).when(accountManagerImpl).getAccount(10L); + Mockito.when(accountMock.getAccountId()).thenReturn(10L); + Mockito.doReturn(false).when(accountManagerImpl).isRootAdmin(10L); + Mockito.lenient().when(accountManagerImpl.getRoleType(Mockito.eq(accountMock))).thenReturn(RoleType.User); + Mockito.when(callingUser.getAccountId()).thenReturn(1L); + Mockito.doReturn(true).when(accountManagerImpl).isRootAdmin(1L); + prepareMockAndExecuteUpdateUserTest(0); + } + private void prepareMockAndExecuteUpdateUserTest(int numberOfExpectedCallsForSetEmailAndSetTimeZone) { Mockito.doReturn("password").when(UpdateUserCmdMock).getPassword(); Mockito.doReturn("newpassword").when(UpdateUserCmdMock).getCurrentPassword(); @@ -1592,4 +1631,104 @@ public void testcheckCallerApiPermissionsForUserOperationsNotAllowedApis() { accountManagerImpl.checkCallerApiPermissionsForUserOrAccountOperations(accountMock); } + + @Test(expected = InvalidParameterValueException.class) + public void testPasswordChangeRequiredWithSamlThrowsException() { + accountManagerImpl.createUser( + "user", "pass", "fn", "ln", "e@mail.com", + "UTC", "acct", 1L, null, + User.Source.SAML2, true + ); + } + + @Test(expected = InvalidParameterValueException.class) + public void testPasswordChangeRequiredWithLdapSourceThrows() { + accountManagerImpl.createUser( + "user", "pass", "fn", "ln", "e@mail.com", + "UTC", "acct", 1L, null, + User.Source.LDAP, true); + } + + @Test(expected = CloudRuntimeException.class) + public void testDomainNotFound() { + Mockito.when(_domainMgr.getDomain(1L)).thenReturn(null); + accountManagerImpl.createUser( + "user", "pass", "fn", "ln", "e@mail.com", + "UTC", "acct", 1L, null, + User.Source.UNKNOWN, false); + } + + @Test(expected = CloudRuntimeException.class) + public void testCreateUserInactiveDomain() { + Mockito.when(domainVoMock.getState()).thenReturn(Domain.State.Inactive); + Mockito.when(_domainMgr.getDomain(Mockito.anyLong())).thenReturn(domainVoMock); + accountManagerImpl.createUser( + "user", "pass", "fn", "ln", "e@mail.com", + "UTC", "acct", 1L, null, + User.Source.NATIVE, false); + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateUserCheckAccess() { + Mockito.when(domainVoMock.getState()).thenReturn(Domain.State.Active); + Mockito.when(_domainMgr.getDomain(Mockito.anyLong())).thenReturn(domainVoMock); + Mockito.doNothing().when(accountManagerImpl).checkAccess(Mockito.any(Account.class), Mockito.any(Domain.class)); + accountManagerImpl.createUser( + "user", "pass", "fn", "ln", "e@mail.com", + "UTC", "acct", 1L, null, + User.Source.NATIVE, false); + } + + @Test(expected = InvalidParameterValueException.class) + public void testCreateUserMissingOrProjectAccount() { + Mockito.when(domainVoMock.getState()).thenReturn(Domain.State.Active); + Mockito.when(_accountDao.findEnabledAccount(Mockito.anyString(), Mockito.anyLong())).thenReturn(accountMock); + Mockito.when(accountMock.getType()).thenReturn(Account.Type.PROJECT); + Mockito.when(_domainMgr.getDomain(Mockito.anyLong())).thenReturn(domainVoMock); + Mockito.doNothing().when(accountManagerImpl).checkAccess(Mockito.any(Account.class), Mockito.any(Domain.class)); + accountManagerImpl.createUser( + "user", "pass", "fn", "ln", "e@mail.com", + "UTC", "acct", 1L, null, + User.Source.NATIVE, false); + } + + @Test + public void testCreateUserSuccess() { + Account rootAdminAccount = Mockito.mock(Account.class); + Mockito.when(rootAdminAccount.getId()).thenReturn(1L); + Mockito.when(accountManagerImpl.isRootAdmin(1L)).thenReturn(true); + User callingUser = Mockito.mock(User.class); + CallContext.register(callingUser, rootAdminAccount); + + String newPassword = "newPassword"; + configureUserMockAuthenticators(newPassword); + Mockito.doNothing().when(accountManagerImpl).checkAccess(any(Account.class), any(Domain.class)); + Mockito.doReturn(accountMock).when(accountManagerImpl).getAccount(Mockito.anyLong()); + Mockito.doNothing().when(passwordPolicyMock).verifyIfPasswordCompliesWithPasswordPolicies(Mockito.anyString(), Mockito.anyString(), Mockito.anyLong()); + Mockito.when(_domainMgr.getDomain(Mockito.anyLong())).thenReturn(domainVoMock); + Mockito.when(domainVoMock.getState()).thenReturn(Domain.State.Active); + + Mockito.when(_accountDao.findEnabledAccount(Mockito.anyString(), Mockito.anyLong())).thenReturn(accountMock); + Mockito.when(accountMock.getId()).thenReturn(10L); + Mockito.when(accountMock.getType()).thenReturn(Account.Type.NORMAL); + + Mockito.when(userAccountDaoMock.validateUsernameInDomain(Mockito.anyString(), Mockito.anyLong())).thenReturn(true); + Mockito.when(userDaoMock.findUsersByName(Mockito.anyString())).thenReturn(Collections.emptyList()); + UserVO createdUser = new UserVO(); + String userMockUUID = "userMockUUID"; + createdUser.setUuid(userMockUUID); + Mockito.when(userDaoMock.persist(Mockito.any(UserVO.class))).thenReturn(createdUser); + UserVO userResultVO = accountManagerImpl.createUser( + "user", newPassword, "fn", "ln", "e@mail.com", + "UTC", "acct", 1L, null, + User.Source.NATIVE, false + ); + Assert.assertNotNull(userResultVO); + UserVO userResultPasswordChangeVO = accountManagerImpl.createUser( + "user", newPassword, "fn", "ln", "e@mail.com", + "UTC", "acct", 1L, null, + User.Source.NATIVE, true + ); + Assert.assertNotNull(userResultVO); + } } diff --git a/server/src/test/java/org/apache/cloudstack/user/UserPasswordResetManagerImplTest.java b/server/src/test/java/org/apache/cloudstack/user/UserPasswordResetManagerImplTest.java index 17092e6311dd..5e274b06be28 100644 --- a/server/src/test/java/org/apache/cloudstack/user/UserPasswordResetManagerImplTest.java +++ b/server/src/test/java/org/apache/cloudstack/user/UserPasswordResetManagerImplTest.java @@ -16,7 +16,11 @@ // under the License. package org.apache.cloudstack.user; +import com.cloud.user.AccountManager; import com.cloud.user.UserAccount; +import com.cloud.user.UserVO; +import com.cloud.user.dao.UserDao; + import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.resourcedetail.UserDetailVO; @@ -45,6 +49,12 @@ public class UserPasswordResetManagerImplTest { @Mock private UserDetailsDao userDetailsDao; + @Mock + AccountManager accountManager; + + @Mock + UserDao userDao; + @Test public void testGetMessageBody() { ConfigKey passwordResetMailTemplate = Mockito.mock(ConfigKey.class); @@ -147,4 +157,21 @@ public void testValidateExistingTokenSecondRequestUnexpired() { Assert.assertFalse(passwordReset.validateExistingToken(userAccount)); } + + @Test + public void testResetPassword() { + UserAccount userAccount = Mockito.mock(UserAccount.class); + UserVO userVO = Mockito.mock(UserVO.class); + long userId = 1L; + String newPassword = "newPassword"; + Mockito.when(userAccount.getId()).thenReturn(userId); + Mockito.when(userDao.getUser(userId)).thenReturn(userVO); + passwordReset.resetPassword(userAccount, newPassword); + Mockito.verify(userDao).getUser(userId); + Mockito.verify(accountManager).validateUserPasswordAndUpdateIfNeeded(newPassword, userVO, "", true); + Mockito.verify(userDetailsDao).removeDetail(userId, PasswordResetToken); + Mockito.verify(userDetailsDao).removeDetail(userId, PasswordResetTokenExpiryDate); + Mockito.verify(userDetailsDao).removeDetail(userId, UserDetailVO.PasswordChangeRequired); + Mockito.verify(userDao).persist(userVO); + } } diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 9987d3528336..8bcc5d0a94bf 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -539,6 +539,8 @@ "label.change.ipaddress": "Change IP address for NIC", "label.change.disk.offering": "Change disk offering", "label.change.offering.for.volume": "Change disk offering for the volume", +"label.change.password.onlogin": "User must change password at next login", +"label.change.password.reset": "Force password reset", "label.change.service.offering": "Change service offering", "label.character": "Character", "label.checksum": "Checksum", @@ -3169,6 +3171,8 @@ "message.change.offering.for.volume.failed": "Change offering for the volume failed", "message.change.offering.for.volume.processing": "Changing offering for the volume...", "message.change.password": "Please change your password.", +"message.change.password.required": "You are required to change your password.", +"message.change.password.reset": "Force password reset on next login.", "message.change.scope.failed": "Scope change failed", "message.change.scope.processing": "Scope change in progress", "message.change.service.offering.sharedfs.failed": "Failed to change service offering for the Shared FileSystem.", @@ -3419,6 +3423,7 @@ "message.error.apply.tungsten.tag": "Applying Tag failed", "message.error.binaries.iso.url": "Please enter binaries ISO URL.", "message.error.bucket": "Please enter bucket", +"message.error.change.password": "Failed to change password.", "message.error.cidr": "CIDR is required", "message.error.cidr.or.cidrsize": "CIDR or cidr size is required", "message.error.cloudian.console": "Single-Sign-On failed for Cloudian management console. Please ask your administrator to fix integration issues.", @@ -3482,6 +3487,7 @@ "message.error.netmask": "Please enter Netmask.", "message.error.network.offering": "Please select Network offering.", "message.error.new.password": "Please enter new password.", +"message.error.newpassword.sameascurrent": "New password cannot be the same as the current password.", "message.error.nexus1000v.ipaddress": "Please enter Nexus 1000v IP address.", "message.error.nexus1000v.password": "Please enter Nexus 1000v password.", "message.error.nexus1000v.username": "Please enter Nexus 1000v username.", @@ -3726,6 +3732,7 @@ "message.please.confirm.remove.user.data": "Please confirm that you want to remove this User Data", "message.please.enter.valid.value": "Please enter a valid value.", "message.please.enter.value": "Please enter values.", +"message.please.login.new.password": "Please log in again with your new password", "message.please.wait.while.autoscale.vmgroup.is.being.created": "Please wait while your AutoScaling Group is being created; this may take a while...", "message.please.wait.while.zone.is.being.created": "Please wait while your Zone is being created; this may take a while...", "message.pod.dedicated": "Pod dedicated.", diff --git a/ui/src/config/router.js b/ui/src/config/router.js index 3e5d8677b347..43e8efd7b5d3 100644 --- a/ui/src/config/router.js +++ b/ui/src/config/router.js @@ -318,6 +318,11 @@ export const constantRouterMap = [ path: 'resetPassword', name: 'resetPassword', component: () => import(/* webpackChunkName: "auth" */ '@/views/auth/ResetPassword') + }, + { + path: 'forceChangePassword', + name: 'forceChangePassword', + component: () => import(/* webpackChunkName: "auth" */ '@/views/iam/ForceChangePassword') } ] }, diff --git a/ui/src/config/section/user.js b/ui/src/config/section/user.js index 65c1a17f760b..233f6cf49f77 100644 --- a/ui/src/config/section/user.js +++ b/ui/src/config/section/user.js @@ -82,6 +82,24 @@ export default { popup: true, component: shallowRef(defineAsyncComponent(() => import('@/views/iam/EditUser.vue'))) }, + { + api: 'updateUser', + icon: 'redo-outlined', + label: 'label.change.password.reset', + message: 'message.change.password.reset', + dataView: true, + args: ['passwordchangerequired'], + mapping: { + passwordchangerequired: { + value: (record) => { return true } + } + }, + popup: true, + show: (record, store) => { + return ['Admin', 'DomainAdmin'].includes(store.userInfo.roletype) && !record.isdefault && + store.userInfo.id !== record.id && record.state === 'enabled' && record.usersource === 'native' + } + }, { api: 'updateUser', icon: 'key-outlined', diff --git a/ui/src/permission.js b/ui/src/permission.js index 266dc992c8db..671d6626b931 100644 --- a/ui/src/permission.js +++ b/ui/src/permission.js @@ -94,6 +94,16 @@ router.beforeEach((to, from, next) => { } store.commit('SET_LOGIN_FLAG', true) } + // store already loaded + if (store.getters.passwordChangeRequired) { + if (to.path === '/user/forceChangePassword') { + next() + } else { + next({ path: '/user/forceChangePassword' }) + NProgress.done() + } + return + } if (Object.keys(store.getters.apis).length === 0) { const cachedApis = vueProps.$localStorage.get(APIS, {}) if (Object.keys(cachedApis).length > 0) { @@ -102,6 +112,19 @@ router.beforeEach((to, from, next) => { store .dispatch('GetInfo') .then(apis => { + // Essential for Page Refresh scenarios + if (store.getters.passwordChangeRequired) { + // Only allow the Change Password page + if (to.path === '/user/forceChangePassword') { + next() + } else { + // Redirect everything else (including dashboard, wildcards) to Change Password + next({ path: '/user/forceChangePassword' }) + NProgress.done() + } + return + } + store.dispatch('GenerateRoutes', { apis }).then(() => { store.getters.addRouters.map(route => { router.addRoute(route) diff --git a/ui/src/store/getters.js b/ui/src/store/getters.js index 911234d9b715..c7ab2f0c536b 100644 --- a/ui/src/store/getters.js +++ b/ui/src/store/getters.js @@ -55,7 +55,8 @@ const getters = { loginFlag: state => state.user.loginFlag, allProjects: (state) => state.app.allProjects, customHypervisorName: state => state.user.customHypervisorName, - readyForShutdownPollingJob: state => state.user.readyForShutdownPollingJob + readyForShutdownPollingJob: state => state.user.readyForShutdownPollingJob, + passwordChangeRequired: state => state.user.passwordChangeRequired } export default getters diff --git a/ui/src/store/modules/user.js b/ui/src/store/modules/user.js index 5c78b8a592fa..6a818d587233 100644 --- a/ui/src/store/modules/user.js +++ b/ui/src/store/modules/user.js @@ -44,7 +44,8 @@ import { MS_ID, OAUTH_DOMAIN, OAUTH_PROVIDER, - LATEST_CS_VERSION + LATEST_CS_VERSION, + PASSWORD_CHANGE_REQUIRED } from '@/store/mutation-types' import { @@ -80,7 +81,8 @@ const user = { twoFaProvider: '', twoFaIssuer: '', customHypervisorName: 'Custom', - readyForShutdownPollingJob: '' + readyForShutdownPollingJob: '', + passwordChangeRequired: false }, mutations: { @@ -196,6 +198,14 @@ const user = { vueProps.$localStorage.set(LATEST_CS_VERSION, version) state.latestVersion = version } + }, + SET_PASSWORD_CHANGE_REQUIRED: (state, required) => { + state.passwordChangeRequired = required + if (required) { + vueProps.$localStorage.set(PASSWORD_CHANGE_REQUIRED, true) + } else { + vueProps.$localStorage.remove(PASSWORD_CHANGE_REQUIRED) + } } }, @@ -244,6 +254,13 @@ const user = { if (result && result.managementserverid) { commit('SET_MS_ID', result.managementserverid) } + if (result.passwordchangerequired) { + commit('SET_PASSWORD_CHANGE_REQUIRED', true) + commit('SET_APIS', {}) + vueProps.$localStorage.remove(APIS) + } else { + commit('SET_PASSWORD_CHANGE_REQUIRED', false) + } const latestVersion = vueProps.$localStorage.get(LATEST_CS_VERSION, { version: '', fetchedTs: 0 }) commit('SET_LATEST_VERSION', latestVersion) notification.destroy() @@ -323,6 +340,15 @@ const user = { commit('SET_DOMAIN_STORE', domainStore) commit('SET_DARK_MODE', darkMode) commit('SET_LATEST_VERSION', latestVersion) + + // This block is to enforce password change for first time login after admin resets password + const isPwdChangeRequired = vueProps.$localStorage.get(PASSWORD_CHANGE_REQUIRED) + commit('SET_PASSWORD_CHANGE_REQUIRED', isPwdChangeRequired) + if (isPwdChangeRequired) { + resolve() + return + } + if (hasAuth) { console.log('Login detected, using cached APIs') commit('SET_ZONES', cachedZones) @@ -485,6 +511,8 @@ const user = { vueProps.$localStorage.remove(ACCESS_TOKEN) vueProps.$localStorage.remove(HEADER_NOTICES) + commit('SET_PASSWORD_CHANGE_REQUIRED', false) + logout(state.token).then(() => { message.destroy() if (cloudianUrl) { diff --git a/ui/src/store/mutation-types.js b/ui/src/store/mutation-types.js index 0b1f921ab86e..5fc2cd74d213 100644 --- a/ui/src/store/mutation-types.js +++ b/ui/src/store/mutation-types.js @@ -43,6 +43,7 @@ export const RELOAD_ALL_PROJECTS = 'RELOAD_ALL_PROJECTS' export const MS_ID = 'MS_ID' export const OAUTH_DOMAIN = 'OAUTH_DOMAIN' export const OAUTH_PROVIDER = 'OAUTH_PROVIDER' +export const PASSWORD_CHANGE_REQUIRED = 'PASSWORD_CHANGE_REQUIRED' export const CONTENT_WIDTH_TYPE = { Fluid: 'Fluid', diff --git a/ui/src/views/iam/AddUser.vue b/ui/src/views/iam/AddUser.vue index acde7583887e..704c55c4814a 100644 --- a/ui/src/views/iam/AddUser.vue +++ b/ui/src/views/iam/AddUser.vue @@ -133,11 +133,16 @@ + + + {{ $t('label.change.password.onlogin') }} + +
- - + + - + @@ -198,6 +203,13 @@ export default { this.initForm() this.fetchData() }, + watch: { + samlEnable (newVal) { + if (newVal) { + this.form.passwordChangeRequired = false + } + } + }, computed: { samlAllowed () { return 'authorizeSamlSso' in this.$store.getters.apis @@ -291,9 +303,9 @@ export default { }) const user = userCreationResponse?.createuserresponse?.user - if (values.samlenable && user) { + if (this.samlEnable && user) { await postAPI('authorizeSamlSso', { - enable: values.samlenable, + enable: this.samlEnable, entityid: values.samlentity, userid: user.id }) @@ -347,6 +359,9 @@ export default { if (this.isValidValueForKey(rawParams, 'timezone') && rawParams.timezone.length > 0) { params.timezone = rawParams.timezone } + if (this.isAdminOrDomainAdmin() && rawParams.passwordChangeRequired === true) { + params.passwordchangerequired = rawParams.passwordChangeRequired + } return postAPI('createUser', params) }, diff --git a/ui/src/views/iam/ChangeUserPassword.vue b/ui/src/views/iam/ChangeUserPassword.vue index d5c52b8f637e..f736557289c7 100644 --- a/ui/src/views/iam/ChangeUserPassword.vue +++ b/ui/src/views/iam/ChangeUserPassword.vue @@ -49,6 +49,11 @@ v-model:value="form.confirmpassword" :placeholder="$t('label.confirmpassword.description')"/> + + + {{ $t('label.change.password.onlogin') }} + +
{{ $t('label.cancel') }} @@ -102,6 +107,11 @@ export default { isAdminOrDomainAdmin () { return ['Admin', 'DomainAdmin'].includes(this.$store.getters.userInfo.roletype) }, + isCallerNotSameAsUser () { + const userId = this.$store.getters.userInfo.id + const resourceId = this.resource?.id ?? null + return userId !== resourceId + }, isValidValueForKey (obj, key) { return key in obj && obj[key] != null }, @@ -134,6 +144,10 @@ export default { if (this.isValidValueForKey(values, 'currentpassword') && values.currentpassword.length > 0) { params.currentpassword = values.currentpassword } + + if (this.isAdminOrDomainAdmin() && values.passwordChangeRequired === true) { + params.passwordchangerequired = values.passwordChangeRequired + } postAPI('updateUser', params).then(json => { this.$notification.success({ message: this.$t('label.action.change.password'), diff --git a/ui/src/views/iam/ForceChangePassword.vue b/ui/src/views/iam/ForceChangePassword.vue new file mode 100644 index 000000000000..31a4a2c512b9 --- /dev/null +++ b/ui/src/views/iam/ForceChangePassword.vue @@ -0,0 +1,285 @@ +// 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. + + + + + + From 2244c01fa1779098be6ae9c3dffbde76e9fa00a3 Mon Sep 17 00:00:00 2001 From: dheeraj12347 Date: Sat, 21 Feb 2026 19:20:34 +0000 Subject: [PATCH 100/101] ui: avoid 404 after deleting template zones --- ui/src/views/image/TemplateZones.vue | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/ui/src/views/image/TemplateZones.vue b/ui/src/views/image/TemplateZones.vue index e517aad5167d..bc4674f84b64 100644 --- a/ui/src/views/image/TemplateZones.vue +++ b/ui/src/views/image/TemplateZones.vue @@ -91,7 +91,7 @@ :rowKey="record => record.datastoreId">