From 599023b61b7c89a24d5d851499db05b9338ab922 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Mon, 6 May 2013 20:56:06 +0100 Subject: [PATCH 01/71] CLOUDSTACK-2322: update network.gateway to fix deployVm error on SharedNetwork after ipv6 support Signed-off-by: Chip Childers --- setup/db/db/schema-40to410.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/setup/db/db/schema-40to410.sql b/setup/db/db/schema-40to410.sql index ff1d9085329..a3426e2caaa 100644 --- a/setup/db/db/schema-40to410.sql +++ b/setup/db/db/schema-40to410.sql @@ -443,6 +443,10 @@ ALTER TABLE `cloud`.`vlan` ADD COLUMN `ip6_range` varchar(255); ALTER TABLE `cloud`.`data_center` ADD COLUMN `ip6_dns1` varchar(255); ALTER TABLE `cloud`.`data_center` ADD COLUMN `ip6_dns2` varchar(255); +UPDATE `cloud`.`networks` INNER JOIN `cloud`.`vlan` ON networks.id = vlan.network_id +SET networks.gateway = vlan.vlan_gateway, networks.ip6_gateway = vlan.ip6_gateway, networks.ip6_cidr = vlan.ip6_cidr +WHERE networks.data_center_id = vlan.data_center_id AND networks.physical_network_id = vlan.physical_network_id; + -- DB views for list api DROP VIEW IF EXISTS `cloud`.`user_vm_view`; From af5bf94b431cea91f424ec1b5dc038a22d25a954 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Mon, 6 May 2013 20:57:02 +0100 Subject: [PATCH 02/71] CLOUDSTACK-2319: fix "unable to add egress rules" in SecurityGroup Signed-off-by: Chip Childers --- .../network/security/SecurityGroupRules.java | 2 + .../security/SecurityGroupRulesVO.java | 15 +- .../dao/SecurityGroupRulesDaoImpl.java | 9 + ui/scripts/network.js | 297 +++++++++--------- 4 files changed, 168 insertions(+), 155 deletions(-) diff --git a/api/src/com/cloud/network/security/SecurityGroupRules.java b/api/src/com/cloud/network/security/SecurityGroupRules.java index d255e46fde5..4dbafd62e98 100644 --- a/api/src/com/cloud/network/security/SecurityGroupRules.java +++ b/api/src/com/cloud/network/security/SecurityGroupRules.java @@ -31,6 +31,8 @@ public interface SecurityGroupRules extends InternalIdentity { Long getRuleId(); + String getRuleUuid(); + int getStartPort(); int getEndPort(); diff --git a/core/src/com/cloud/network/security/SecurityGroupRulesVO.java b/core/src/com/cloud/network/security/SecurityGroupRulesVO.java index 82060efce12..c74152e453c 100644 --- a/core/src/com/cloud/network/security/SecurityGroupRulesVO.java +++ b/core/src/com/cloud/network/security/SecurityGroupRulesVO.java @@ -54,6 +54,9 @@ public class SecurityGroupRulesVO implements SecurityGroupRules { @Column(name = "id", table = "security_group_rule", insertable = false, updatable = false) private Long ruleId; + @Column(name = "uuid", table = "security_group_rule", insertable = false, updatable = false) + private String ruleUuid; + @Column(name = "start_port", table = "security_group_rule", insertable = false, updatable = false) private int startPort; @@ -75,7 +78,11 @@ public class SecurityGroupRulesVO implements SecurityGroupRules { public SecurityGroupRulesVO() { } - public SecurityGroupRulesVO(long id, String name, String description, Long domainId, Long accountId, Long ruleId, int startPort, int endPort, String protocol, Long allowedNetworkId, + public SecurityGroupRulesVO(long id) { + this.id = id; + } + + public SecurityGroupRulesVO(long id, String name, String description, Long domainId, Long accountId, Long ruleId, String ruleUuid, int startPort, int endPort, String protocol, Long allowedNetworkId, String allowedSourceIpCidr) { this.id = id; this.name = name; @@ -83,6 +90,7 @@ public class SecurityGroupRulesVO implements SecurityGroupRules { this.domainId = domainId; this.accountId = accountId; this.ruleId = ruleId; + this.ruleUuid = ruleUuid; this.startPort = startPort; this.endPort = endPort; this.protocol = protocol; @@ -120,6 +128,11 @@ public class SecurityGroupRulesVO implements SecurityGroupRules { return ruleId; } + @Override + public String getRuleUuid() { + return ruleUuid; + } + @Override public int getStartPort() { return startPort; diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java b/server/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java index f08ca05cd7a..18ef57fbcd8 100644 --- a/server/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java +++ b/server/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java @@ -84,4 +84,13 @@ public class SecurityGroupRulesDaoImpl extends GenericDaoBase sc = createSearchCriteria(); + sc.addAnd("ruleUuid", SearchCriteria.Op.EQ, uuid); + SecurityGroupRulesVO rule = findOneIncludingRemovedBy(sc); + SecurityGroupRulesVO newRule = new SecurityGroupRulesVO(rule.getRuleId()); + return newRule; + } } diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 9ba725a8574..6b310ce0e83 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -3981,13 +3981,12 @@ account: args.context.securityGroups[0].account }; - // TCP / ICMP if (args.data.icmptype && args.data.icmpcode) { // ICMP $.extend(data, { icmptype: args.data.icmptype, icmpcode: args.data.icmpcode }); - } else { // TCP + } else { // TCP/UDP $.extend(data, { startport: args.data.startport, endport: args.data.endport @@ -4081,121 +4080,142 @@ egressRules: { title: 'label.egress.rule', - custom: function(args) { - var context = args.context; + custom: cloudStack.uiCustom.securityRules({ + noSelect: true, + noHeaderActionsColumn: true, + fields: { + 'protocol': { + label: 'label.protocol', + select: function(args) { + args.$select.change(function() { + var $inputs = args.$form.find('th, td'); + var $icmpFields = $inputs.filter(function() { + var name = $(this).attr('rel'); - return $('
').multiEdit({ - context: context, - noSelect: true, - noHeaderActionsColumn: true, - fields: { - 'cidrlist': { edit: true, label: 'label.cidr' }, - 'protocol': { - label: 'label.protocol', - select: function(args) { - args.$select.change(function() { - var $inputs = args.$form.find('th, td'); - var $icmpFields = $inputs.filter(function() { - var name = $(this).attr('rel'); + return $.inArray(name, [ + 'icmptype', + 'icmpcode' + ]) > -1; + }); + var $otherFields = $inputs.filter(function() { + var name = $(this).attr('rel'); - return $.inArray(name, [ - 'icmptype', - 'icmpcode' - ]) > -1; - }); - var $otherFields = $inputs.filter(function() { - var name = $(this).attr('rel'); - - return name != 'cidrlist' && - name != 'icmptype' && - name != 'icmpcode' && - name != 'protocol' && - name != 'add-rule'; - }); - - if ($(this).val() == 'icmp') { - $icmpFields.show(); - $otherFields.hide(); - } else { - $icmpFields.hide(); - $otherFields.show(); - } + return name != 'icmptype' && + name != 'icmpcode' && + name != 'protocol' && + name != 'add-rule' && + name != 'cidr' && + name != 'accountname' && + name != 'securitygroup'; }); - args.response.success({ - data: [ - { name: 'tcp', description: 'TCP' }, - { name: 'udp', description: 'UDP' }, - { name: 'icmp', description: 'ICMP' } - ] - }); - } - }, - 'startport': { edit: true, label: 'label.start.port' }, - 'endport': { edit: true, label: 'label.end.port' }, - 'icmptype': { edit: true, label: 'ICMP.type', isHidden: true }, - 'icmpcode': { edit: true, label: 'ICMP.code', isHidden: true }, - 'add-rule': { - label: 'label.add', - addButton: true - } - }, - add: { - label: 'label.add', - action: function(args) { - var data = { - protocol: args.data.protocol, - cidrlist: args.data.cidrlist, - trafficType: 'Egress' - }; - - if (args.data.icmptype && args.data.icmpcode) { // ICMP - $.extend(data, { - icmptype: args.data.icmptype, - icmpcode: args.data.icmpcode - }); - } else { // TCP/UDP - $.extend(data, { - startport: args.data.startport, - endport: args.data.endport - }); - } - - // Get Source NAT IP - var sourceNATIP; - - $.ajax({ - url: createURL('listPublicIpAddresses'), - data: { - listAll: true, - associatednetworkid: args.context.networks[0].id - }, - async: false, - success: function(json) { - var ipAddresses = json.listpublicipaddressesresponse.publicipaddress; - - sourceNATIP = $.grep(ipAddresses, function(ipAddress) { - return ipAddress.issourcenat; - })[0]; + if ($(this).val() == 'icmp') { + $icmpFields.show(); + $otherFields.hide(); + } else { + $icmpFields.hide(); + $otherFields.show(); } }); - data.ipaddressid = sourceNATIP.id; + args.response.success({ + data: [ + { name: 'tcp', description: 'TCP' }, + { name: 'udp', description: 'UDP' }, + { name: 'icmp', description: 'ICMP' } + ] + }); + } + }, + 'startport': { edit: true, label: 'label.start.port' }, + 'endport': { edit: true, label: 'label.end.port' }, + 'icmptype': { edit: true, label: 'ICMP.type', isHidden: true }, + 'icmpcode': { edit: true, label: 'ICMP.code', isHidden: true }, + 'cidr': { edit: true, label: 'label.cidr', isHidden: true }, + 'accountname': { + edit: true, + label: 'label.account.and.security.group', + isHidden: true, + range: ['accountname', 'securitygroup'] + }, + 'add-rule': { + label: 'label.add', + addButton: true + } + }, + add: { + label: 'label.add', + action: function(args) { + var data = { + securitygroupid: args.context.securityGroups[0].id, + protocol: args.data.protocol, + domainid: args.context.securityGroups[0].domainid, + account: args.context.securityGroups[0].account + }; + if (args.data.icmptype && args.data.icmpcode) { // ICMP + $.extend(data, { + icmptype: args.data.icmptype, + icmpcode: args.data.icmpcode + }); + } else { // TCP/UDP + $.extend(data, { + startport: args.data.startport, + endport: args.data.endport + }); + } + + // CIDR / account + if (args.data.cidr) { + data.cidrlist = args.data.cidr; + } else { + data['usersecuritygrouplist[0].account'] = args.data.accountname; + data['usersecuritygrouplist[0].group'] = args.data.securitygroup; + } + + $.ajax({ + url: createURL('authorizeSecurityGroupEgress'), + data: data, + dataType: 'json', + async: true, + success: function(data) { + var jobId = data.authorizesecuritygroupegressresponse.jobid; + + args.response.success({ + _custom: { + jobId: jobId + }, + notification: { + label: 'label.add.egress.rule', + poll: pollAsyncJobResult + } + }); + } + }); + } + }, + actions: { + destroy: { + label: 'label.remove.rule', + action: function(args) { $.ajax({ - url: createURL('createFirewallRule'), - data: data, + url: createURL('revokeSecurityGroupEgress'), + data: { + domainid: args.context.securityGroups[0].domainid, + account: args.context.securityGroups[0].account, + id: args.context.multiRule[0].id + }, dataType: 'json', async: true, - success: function(json) { - var jobId = json.createfirewallruleresponse.jobid; + success: function(data) { + var jobID = data.revokesecuritygroupegress.jobid; args.response.success({ _custom: { - jobId: jobId + jobId: jobID }, notification: { - label: 'label.add.egress.rule', + label: 'label.remove.egress.rule', poll: pollAsyncJobResult } }); @@ -4205,60 +4225,29 @@ } }); } - }, - actions: { - destroy: { - label: 'label.remove.rule', - action: function(args) { - $.ajax({ - url: createURL('deleteFirewallRule'), - data: { - id: args.context.multiRule[0].id - }, - dataType: 'json', - async: true, - success: function(data) { - var jobID = data.deletefirewallruleresponse.jobid; - - args.response.success({ - _custom: { - jobId: jobID - }, - notification: { - label: 'label.remove.egress.rule', - poll: pollAsyncJobResult - } - }); - }, - error: function(json) { - args.response.error(parseXMLHttpResponse(json)); - } - }); - } - } - }, - ignoreEmptyFields: true, - dataProvider: function(args) { - $.ajax({ - url: createURL('listFirewallRules'), - data: { - listAll: true, - networkid: args.context.networks[0].id, - trafficType: 'Egress' - }, - dataType: 'json', - async: true, - success: function(json) { - var response = json.listfirewallrulesresponse.firewallrule; - - args.response.success({ - data: response - }); - } - }); } - }); - } + }, + ignoreEmptyFields: true, + dataProvider: function(args) { + $.ajax({ + url: createURL('listSecurityGroups'), + data: { + id: args.context.securityGroups[0].id + }, + dataType: 'json', + async: true, + success: function(data) { + args.response.success({ + data: $.map( + data.listsecuritygroupsresponse.securitygroup[0].egressrule ? + data.listsecuritygroupsresponse.securitygroup[0].egressrule : [], + ingressEgressDataMap + ) + }); + } + }); + } + }) } }, From 5e87b0a38540f85cbbcf5a19d404347b63649c46 Mon Sep 17 00:00:00 2001 From: Dennis Lawler Date: Mon, 29 Apr 2013 15:10:09 -0700 Subject: [PATCH 03/71] Removing filterwin2k option Signed-off-by: Chiradeep Vittal --- patches/systemvm/debian/config/etc/dnsmasq.conf.tmpl | 2 +- patches/systemvm/debian/config/etc/vpcdnsmasq.conf | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/patches/systemvm/debian/config/etc/dnsmasq.conf.tmpl b/patches/systemvm/debian/config/etc/dnsmasq.conf.tmpl index 7d656cb2b77..38e5a8bbc96 100644 --- a/patches/systemvm/debian/config/etc/dnsmasq.conf.tmpl +++ b/patches/systemvm/debian/config/etc/dnsmasq.conf.tmpl @@ -27,7 +27,7 @@ bogus-priv # so don't use it if you use eg Kerberos, SIP, XMMP or Google-talk. # This option only affects forwarding, SRV records originating for # dnsmasq (via srv-host= lines) are not suppressed by it. -filterwin2k +# filterwin2k # Change this line if you want dns to get its upstream servers from # somewhere other that /etc/resolv.conf diff --git a/patches/systemvm/debian/config/etc/vpcdnsmasq.conf b/patches/systemvm/debian/config/etc/vpcdnsmasq.conf index 3717fc8a80c..3622d0e7916 100644 --- a/patches/systemvm/debian/config/etc/vpcdnsmasq.conf +++ b/patches/systemvm/debian/config/etc/vpcdnsmasq.conf @@ -460,6 +460,3 @@ log-facility=/var/log/dnsmasq.log # Include a another lot of configuration options. #conf-file=/etc/dnsmasq.more.conf conf-dir=/etc/dnsmasq.d - -# Don't reply Windows's periodical DNS request -filterwin2k From e0d8f01ecd92a1a7b74558d02a28be3b2f20a10d Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Tue, 30 Apr 2013 19:06:20 -0700 Subject: [PATCH 04/71] Removed framework-api which is completely useless. Changed framework-ipc to reference gson itself. Move VOs into engine-schema. --- .../src/com/cloud/event/UsageEvent.java | 0 .../storage/resource/StoragePoolResource.java | 0 .../storage/snapshot/SnapshotSchedule.java | 11 +-- core/pom.xml | 7 +- .../storage/snapshot/SnapshotSchedule.java | 46 ---------- core/src/com/cloud/vm/VirtualDisk.java | 31 ------- engine/pom.xml | 2 - .../schema}/src/com/cloud/alert/AlertVO.java | 0 .../cloud/configuration/ConfigurationVO.java | 0 .../cloud/configuration/ResourceCountVO.java | 0 .../cloud/configuration/ResourceLimitVO.java | 0 .../schema}/src/com/cloud/event/EventVO.java | 0 .../src/com/cloud/event/UsageEventVO.java | 0 .../src/com/cloud/event/dao/EventDao.java | 0 .../src/com/cloud/event/dao/EventDaoImpl.java | 0 .../com/cloud/event/dao/UsageEventDao.java | 7 +- .../cloud/event/dao/UsageEventDaoImpl.java | 26 +++--- .../schema}/src/com/cloud/user/AccountVO.java | 0 .../src/com/cloud/user/SSHKeyPairVO.java | 0 .../src/com/cloud/user/UserAccountVO.java | 0 .../src/com/cloud/user/UserStatisticsVO.java | 0 .../src/com/cloud/user/UserStatsLogVO.java | 0 .../schema}/src/com/cloud/user/UserVO.java | 0 .../src/com/cloud/vm/VMInstanceVO.java | 0 .../com/cloud/vm/snapshot/VMSnapshotVO.java | 0 framework/api/pom.xml | 42 --------- framework/ipc/pom.xml | 20 ++-- .../framework/async/AsyncCallFuture.java | 0 .../async/AsyncCompletionCallback.java | 0 .../client/ClientTransportProvider.java | 2 +- framework/pom.xml | 1 - pom.xml | 13 ++- server/pom.xml | 92 ++++++++----------- utils/pom.xml | 9 -- 34 files changed, 86 insertions(+), 223 deletions(-) rename {core => api}/src/com/cloud/event/UsageEvent.java (100%) rename {core => api}/src/com/cloud/storage/resource/StoragePoolResource.java (100%) delete mode 100644 core/src/com/cloud/storage/snapshot/SnapshotSchedule.java delete mode 100644 core/src/com/cloud/vm/VirtualDisk.java rename {core => engine/schema}/src/com/cloud/alert/AlertVO.java (100%) rename {core => engine/schema}/src/com/cloud/configuration/ConfigurationVO.java (100%) rename {core => engine/schema}/src/com/cloud/configuration/ResourceCountVO.java (100%) rename {core => engine/schema}/src/com/cloud/configuration/ResourceLimitVO.java (100%) rename {core => engine/schema}/src/com/cloud/event/EventVO.java (100%) rename {core => engine/schema}/src/com/cloud/event/UsageEventVO.java (100%) rename {core => engine/schema}/src/com/cloud/event/dao/EventDao.java (100%) rename {core => engine/schema}/src/com/cloud/event/dao/EventDaoImpl.java (100%) rename {core => engine/schema}/src/com/cloud/event/dao/UsageEventDao.java (89%) rename {core => engine/schema}/src/com/cloud/event/dao/UsageEventDaoImpl.java (92%) rename {core => engine/schema}/src/com/cloud/user/AccountVO.java (100%) rename {core => engine/schema}/src/com/cloud/user/SSHKeyPairVO.java (100%) rename {core => engine/schema}/src/com/cloud/user/UserAccountVO.java (100%) rename {core => engine/schema}/src/com/cloud/user/UserStatisticsVO.java (100%) rename {core => engine/schema}/src/com/cloud/user/UserStatsLogVO.java (100%) rename {core => engine/schema}/src/com/cloud/user/UserVO.java (100%) rename {core => engine/schema}/src/com/cloud/vm/VMInstanceVO.java (100%) rename {core => engine/schema}/src/com/cloud/vm/snapshot/VMSnapshotVO.java (100%) delete mode 100644 framework/api/pom.xml rename framework/{api => ipc}/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java (100%) rename framework/{api => ipc}/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java (100%) diff --git a/core/src/com/cloud/event/UsageEvent.java b/api/src/com/cloud/event/UsageEvent.java similarity index 100% rename from core/src/com/cloud/event/UsageEvent.java rename to api/src/com/cloud/event/UsageEvent.java diff --git a/core/src/com/cloud/storage/resource/StoragePoolResource.java b/api/src/com/cloud/storage/resource/StoragePoolResource.java similarity index 100% rename from core/src/com/cloud/storage/resource/StoragePoolResource.java rename to api/src/com/cloud/storage/resource/StoragePoolResource.java diff --git a/api/src/com/cloud/storage/snapshot/SnapshotSchedule.java b/api/src/com/cloud/storage/snapshot/SnapshotSchedule.java index 12c1445f0ad..6f3d2ce5468 100644 --- a/api/src/com/cloud/storage/snapshot/SnapshotSchedule.java +++ b/api/src/com/cloud/storage/snapshot/SnapshotSchedule.java @@ -16,12 +16,12 @@ // under the License. package com.cloud.storage.snapshot; +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + import java.util.Date; -public interface SnapshotSchedule { - long getId(); - - String getUuid(); +public interface SnapshotSchedule extends InternalIdentity, Identity { Long getVolumeId(); @@ -38,10 +38,9 @@ public interface SnapshotSchedule { Long getAsyncJobId(); - void setAsyncJobId(long asyncJobId); + void setAsyncJobId(Long asyncJobId); Long getSnapshotId(); void setSnapshotId(Long snapshotId); - } diff --git a/core/pom.xml b/core/pom.xml index 0da69529400..a2d487e531c 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -36,6 +36,11 @@ cloud-engine-api ${project.version} + + org.apache.cloudstack + cloud-engine-schema + ${project.version} + commons-httpclient commons-httpclient @@ -55,7 +60,5 @@ install - src - test diff --git a/core/src/com/cloud/storage/snapshot/SnapshotSchedule.java b/core/src/com/cloud/storage/snapshot/SnapshotSchedule.java deleted file mode 100644 index 6f3d2ce5468..00000000000 --- a/core/src/com/cloud/storage/snapshot/SnapshotSchedule.java +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.storage.snapshot; - -import org.apache.cloudstack.api.Identity; -import org.apache.cloudstack.api.InternalIdentity; - -import java.util.Date; - -public interface SnapshotSchedule extends InternalIdentity, Identity { - - Long getVolumeId(); - - Long getPolicyId(); - - void setPolicyId(long policyId); - - /** - * @return the scheduledTimestamp - */ - Date getScheduledTimestamp(); - - void setScheduledTimestamp(Date scheduledTimestamp); - - Long getAsyncJobId(); - - void setAsyncJobId(Long asyncJobId); - - Long getSnapshotId(); - - void setSnapshotId(Long snapshotId); -} diff --git a/core/src/com/cloud/vm/VirtualDisk.java b/core/src/com/cloud/vm/VirtualDisk.java deleted file mode 100644 index ad7bb43d40b..00000000000 --- a/core/src/com/cloud/vm/VirtualDisk.java +++ /dev/null @@ -1,31 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.vm; - -import com.cloud.storage.Storage; - -/** - * VirtualDisk describes the disks that are plugged into - * the virtual machine. - * - */ -public class VirtualDisk { - public Storage.ImageFormat format; - public String url; - public boolean bootable; - public long size; -} diff --git a/engine/pom.xml b/engine/pom.xml index 1a3d896d50d..169425ae14e 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -29,8 +29,6 @@ install - src - test api diff --git a/core/src/com/cloud/alert/AlertVO.java b/engine/schema/src/com/cloud/alert/AlertVO.java similarity index 100% rename from core/src/com/cloud/alert/AlertVO.java rename to engine/schema/src/com/cloud/alert/AlertVO.java diff --git a/core/src/com/cloud/configuration/ConfigurationVO.java b/engine/schema/src/com/cloud/configuration/ConfigurationVO.java similarity index 100% rename from core/src/com/cloud/configuration/ConfigurationVO.java rename to engine/schema/src/com/cloud/configuration/ConfigurationVO.java diff --git a/core/src/com/cloud/configuration/ResourceCountVO.java b/engine/schema/src/com/cloud/configuration/ResourceCountVO.java similarity index 100% rename from core/src/com/cloud/configuration/ResourceCountVO.java rename to engine/schema/src/com/cloud/configuration/ResourceCountVO.java diff --git a/core/src/com/cloud/configuration/ResourceLimitVO.java b/engine/schema/src/com/cloud/configuration/ResourceLimitVO.java similarity index 100% rename from core/src/com/cloud/configuration/ResourceLimitVO.java rename to engine/schema/src/com/cloud/configuration/ResourceLimitVO.java diff --git a/core/src/com/cloud/event/EventVO.java b/engine/schema/src/com/cloud/event/EventVO.java similarity index 100% rename from core/src/com/cloud/event/EventVO.java rename to engine/schema/src/com/cloud/event/EventVO.java diff --git a/core/src/com/cloud/event/UsageEventVO.java b/engine/schema/src/com/cloud/event/UsageEventVO.java similarity index 100% rename from core/src/com/cloud/event/UsageEventVO.java rename to engine/schema/src/com/cloud/event/UsageEventVO.java diff --git a/core/src/com/cloud/event/dao/EventDao.java b/engine/schema/src/com/cloud/event/dao/EventDao.java similarity index 100% rename from core/src/com/cloud/event/dao/EventDao.java rename to engine/schema/src/com/cloud/event/dao/EventDao.java diff --git a/core/src/com/cloud/event/dao/EventDaoImpl.java b/engine/schema/src/com/cloud/event/dao/EventDaoImpl.java similarity index 100% rename from core/src/com/cloud/event/dao/EventDaoImpl.java rename to engine/schema/src/com/cloud/event/dao/EventDaoImpl.java diff --git a/core/src/com/cloud/event/dao/UsageEventDao.java b/engine/schema/src/com/cloud/event/dao/UsageEventDao.java similarity index 89% rename from core/src/com/cloud/event/dao/UsageEventDao.java rename to engine/schema/src/com/cloud/event/dao/UsageEventDao.java index 52fa01d0924..01979e18ea3 100644 --- a/core/src/com/cloud/event/dao/UsageEventDao.java +++ b/engine/schema/src/com/cloud/event/dao/UsageEventDao.java @@ -20,16 +20,15 @@ import java.util.Date; import java.util.List; import com.cloud.event.UsageEventVO; -import com.cloud.exception.UsageServerException; import com.cloud.utils.db.GenericDao; public interface UsageEventDao extends GenericDao { - + public List listLatestEvents(Date endDate); public List getLatestEvent(); - - List getRecentEvents(Date endDate) throws UsageServerException; + + List getRecentEvents(Date endDate); List listDirectIpEvents(Date startDate, Date endDate, long zoneId); diff --git a/core/src/com/cloud/event/dao/UsageEventDaoImpl.java b/engine/schema/src/com/cloud/event/dao/UsageEventDaoImpl.java similarity index 92% rename from core/src/com/cloud/event/dao/UsageEventDaoImpl.java rename to engine/schema/src/com/cloud/event/dao/UsageEventDaoImpl.java index dafc8d4d5ec..004ab7c381f 100644 --- a/core/src/com/cloud/event/dao/UsageEventDaoImpl.java +++ b/engine/schema/src/com/cloud/event/dao/UsageEventDaoImpl.java @@ -30,7 +30,6 @@ import org.springframework.stereotype.Component; import com.cloud.dc.Vlan; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventVO; -import com.cloud.exception.UsageServerException; import com.cloud.utils.DateUtil; import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; @@ -38,6 +37,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; @Component @Local(value={UsageEventDao.class}) @@ -58,8 +58,8 @@ public class UsageEventDaoImpl extends GenericDaoBase implem latestEventsSearch.and("processed", latestEventsSearch.entity().isProcessed(), SearchCriteria.Op.EQ); latestEventsSearch.and("enddate", latestEventsSearch.entity().getCreateDate(), SearchCriteria.Op.LTEQ); latestEventsSearch.done(); - - IpeventsSearch = createSearchBuilder(); + + IpeventsSearch = createSearchBuilder(); IpeventsSearch.and("startdate", IpeventsSearch.entity().getCreateDate(), SearchCriteria.Op.GTEQ); IpeventsSearch.and("enddate", IpeventsSearch.entity().getCreateDate(), SearchCriteria.Op.LTEQ); IpeventsSearch.and("zoneid", IpeventsSearch.entity().getZoneId(), SearchCriteria.Op.EQ); @@ -84,10 +84,10 @@ public class UsageEventDaoImpl extends GenericDaoBase implem Filter filter = new Filter(UsageEventVO.class, "id", Boolean.FALSE, Long.valueOf(0), Long.valueOf(1)); return listAll(filter); } - + @Override @DB - public synchronized List getRecentEvents(Date endDate) throws UsageServerException { + public synchronized List getRecentEvents(Date endDate) { long recentEventId = getMostRecentEventId(); long maxEventId = getMaxEventId(endDate); Transaction txn = Transaction.open(Transaction.USAGE_DB); @@ -114,12 +114,12 @@ public class UsageEventDaoImpl extends GenericDaoBase implem } catch (Exception ex) { txn.rollback(); s_logger.error("error copying events from cloud db to usage db", ex); - throw new UsageServerException(ex.getMessage()); + throw new CloudRuntimeException(ex.getMessage()); } } @DB - private long getMostRecentEventId() throws UsageServerException { + private long getMostRecentEventId() { Transaction txn = Transaction.open(Transaction.USAGE_DB); try { List latestEvents = getLatestEvent(); @@ -133,25 +133,25 @@ public class UsageEventDaoImpl extends GenericDaoBase implem return 0; } catch (Exception ex) { s_logger.error("error getting most recent event id", ex); - throw new UsageServerException(ex.getMessage()); + throw new CloudRuntimeException(ex.getMessage()); } finally { txn.close(); } } - private List findRecentEvents(Date endDate) throws UsageServerException { + private List findRecentEvents(Date endDate) { Transaction txn = Transaction.open(Transaction.USAGE_DB); try { return listLatestEvents(endDate); } catch (Exception ex) { s_logger.error("error getting most recent event date", ex); - throw new UsageServerException(ex.getMessage()); + throw new CloudRuntimeException(ex.getMessage()); } finally { txn.close(); } } - - private long getMaxEventId(Date endDate) throws UsageServerException { + + private long getMaxEventId(Date endDate) { Transaction txn = Transaction.currentTxn(); PreparedStatement pstmt = null; try { @@ -165,7 +165,7 @@ public class UsageEventDaoImpl extends GenericDaoBase implem return 0; } catch (Exception ex) { s_logger.error("error getting max event id", ex); - throw new UsageServerException(ex.getMessage()); + throw new CloudRuntimeException(ex.getMessage()); } finally { txn.close(); } diff --git a/core/src/com/cloud/user/AccountVO.java b/engine/schema/src/com/cloud/user/AccountVO.java similarity index 100% rename from core/src/com/cloud/user/AccountVO.java rename to engine/schema/src/com/cloud/user/AccountVO.java diff --git a/core/src/com/cloud/user/SSHKeyPairVO.java b/engine/schema/src/com/cloud/user/SSHKeyPairVO.java similarity index 100% rename from core/src/com/cloud/user/SSHKeyPairVO.java rename to engine/schema/src/com/cloud/user/SSHKeyPairVO.java diff --git a/core/src/com/cloud/user/UserAccountVO.java b/engine/schema/src/com/cloud/user/UserAccountVO.java similarity index 100% rename from core/src/com/cloud/user/UserAccountVO.java rename to engine/schema/src/com/cloud/user/UserAccountVO.java diff --git a/core/src/com/cloud/user/UserStatisticsVO.java b/engine/schema/src/com/cloud/user/UserStatisticsVO.java similarity index 100% rename from core/src/com/cloud/user/UserStatisticsVO.java rename to engine/schema/src/com/cloud/user/UserStatisticsVO.java diff --git a/core/src/com/cloud/user/UserStatsLogVO.java b/engine/schema/src/com/cloud/user/UserStatsLogVO.java similarity index 100% rename from core/src/com/cloud/user/UserStatsLogVO.java rename to engine/schema/src/com/cloud/user/UserStatsLogVO.java diff --git a/core/src/com/cloud/user/UserVO.java b/engine/schema/src/com/cloud/user/UserVO.java similarity index 100% rename from core/src/com/cloud/user/UserVO.java rename to engine/schema/src/com/cloud/user/UserVO.java diff --git a/core/src/com/cloud/vm/VMInstanceVO.java b/engine/schema/src/com/cloud/vm/VMInstanceVO.java similarity index 100% rename from core/src/com/cloud/vm/VMInstanceVO.java rename to engine/schema/src/com/cloud/vm/VMInstanceVO.java diff --git a/core/src/com/cloud/vm/snapshot/VMSnapshotVO.java b/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotVO.java similarity index 100% rename from core/src/com/cloud/vm/snapshot/VMSnapshotVO.java rename to engine/schema/src/com/cloud/vm/snapshot/VMSnapshotVO.java diff --git a/framework/api/pom.xml b/framework/api/pom.xml deleted file mode 100644 index 5260ebc4bf6..00000000000 --- a/framework/api/pom.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - 4.0.0 - cloud-framework-api - - org.apache.cloudstack - cloudstack-framework - 4.2.0-SNAPSHOT - ../pom.xml - - - - - org.apache.cloudstack - cloud-utils - 4.2.0-SNAPSHOT - - - - - - install - src - ${project.basedir}/test - - - ${project.basedir}/test/resources - - - - diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml index b7f4fcc78ce..2c2131f01c1 100644 --- a/framework/ipc/pom.xml +++ b/framework/ipc/pom.xml @@ -20,26 +20,24 @@ ../pom.xml - - org.apache.cloudstack - cloud-core - 4.2.0-SNAPSHOT + cglib + cglib-nodep + ${cs.cglib.version} + + + com.google.code.gson + gson + ${cs.gson.version} - org.apache.cloudstack cloud-utils - 4.2.0-SNAPSHOT + ${project.version} - - install - src - ${project.basedir}/test ${project.basedir}/test/resources diff --git a/framework/api/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java similarity index 100% rename from framework/api/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java rename to framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java diff --git a/framework/api/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java similarity index 100% rename from framework/api/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java rename to framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java diff --git a/framework/ipc/src/org/apache/cloudstack/framework/client/ClientTransportProvider.java b/framework/ipc/src/org/apache/cloudstack/framework/client/ClientTransportProvider.java index bd93824ea85..023b3181b20 100644 --- a/framework/ipc/src/org/apache/cloudstack/framework/client/ClientTransportProvider.java +++ b/framework/ipc/src/org/apache/cloudstack/framework/client/ClientTransportProvider.java @@ -28,7 +28,7 @@ import org.apache.cloudstack.framework.transport.TransportEndpoint; import org.apache.cloudstack.framework.transport.TransportEndpointSite; import org.apache.cloudstack.framework.transport.TransportProvider; -import com.cloud.utils.concurrency.NamedThreadFactory; +import com.cloud.utils.concurrency.NamedThreadFactory; public class ClientTransportProvider implements TransportProvider { public static final int DEFAULT_WORKER_POOL_SIZE = 5; diff --git a/framework/pom.xml b/framework/pom.xml index 4633dab2b30..4dfb409f04e 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -33,6 +33,5 @@ ipc rest events - api diff --git a/pom.xml b/pom.xml index 57073e3b19a..7f4a74664e0 100644 --- a/pom.xml +++ b/pom.xml @@ -255,6 +255,13 @@ install + src + test + + + test/resources + + ${basedir}/${cs.target.dir}/classes ${basedir}/${cs.target.dir}/test-classes @@ -275,8 +282,8 @@ - + org.eclipse.m2e lifecycle-mapping @@ -298,7 +305,7 @@ - + diff --git a/server/pom.xml b/server/pom.xml index 8b64335d50f..2d960bef303 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -1,22 +1,14 @@ - - + + 4.0.0 cloud-server Apache CloudStack Server @@ -110,35 +102,35 @@ **/*.xml - + test/resources - - %regex[.*[0-9]*To[0-9]*.*Test.*] - + + %regex[.*[0-9]*To[0-9]*.*Test.*] + - - org.apache.maven.plugins - maven-compiler-plugin - - - default-testCompile - test-compile - - - **/com/cloud/upgrade/*.java - **/com/cloud/async/*.java - - - - testCompile - - - - + + org.apache.maven.plugins + maven-compiler-plugin + + + default-testCompile + test-compile + + + **/com/cloud/upgrade/*.java + **/com/cloud/async/*.java + + + + testCompile + + + + org.apache.maven.plugins maven-surefire-plugin @@ -146,8 +138,8 @@ -Xmx1024m %regex[.*[0-9]*To[0-9]*.*Test.*] - com/cloud/upgrade/AdvanceZone223To224UpgradeTest - com/cloud/upgrade/AdvanceZone217To224UpgradeTest + com/cloud/upgrade/AdvanceZone223To224UpgradeTest + com/cloud/upgrade/AdvanceZone217To224UpgradeTest com/cloud/async/* com/cloud/cluster/* com/cloud/snapshot/* @@ -173,22 +165,18 @@ - + - - + + - + diff --git a/utils/pom.xml b/utils/pom.xml index d4bafbdcaf0..27430267cfe 100644 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -172,15 +172,6 @@ ${project.basedir}/test/resources - org.apache.maven.plugins From ad2777c54774854d54f6ce6e361b418a23e8888f Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Wed, 1 May 2013 05:46:15 -0700 Subject: [PATCH 05/71] Moved agent commands to core and out of api --- .../AgentControlChannelException.java | 0 .../resource/UnableDeleteHostException.java | 0 .../cloud/storage/StoragePoolDiscoverer.java | 8 +- core/src/com/cloud/agent/RecoveryHandler.java | 31 ------ .../cloud/agent/api/AgentControlAnswer.java | 0 .../cloud/agent/api/AgentControlCommand.java | 0 .../com/cloud/agent/api/AttachIsoCommand.java | 0 .../cloud/agent/api/AttachVolumeAnswer.java | 0 .../cloud/agent/api/AttachVolumeCommand.java | 0 .../cloud/agent/api/BackupSnapshotAnswer.java | 0 .../agent/api/BackupSnapshotCommand.java | 0 .../agent/api/BumpUpPriorityCommand.java | 0 .../com/cloud/agent/api/CancelCommand.java | 0 .../cloud/agent/api/ChangeAgentAnswer.java | 0 .../cloud/agent/api/ChangeAgentCommand.java | 0 .../cloud/agent/api/CheckHealthAnswer.java | 0 .../cloud/agent/api/CheckHealthCommand.java | 0 .../cloud/agent/api/CheckNetworkAnswer.java | 0 .../cloud/agent/api/CheckNetworkCommand.java | 0 .../cloud/agent/api/CheckOnHostAnswer.java | 0 .../cloud/agent/api/CheckOnHostCommand.java | 0 .../cloud/agent/api/CheckRouterAnswer.java | 0 .../cloud/agent/api/CheckRouterCommand.java | 0 .../api/CheckS2SVpnConnectionsAnswer.java | 0 .../api/CheckS2SVpnConnectionsCommand.java | 0 .../com/cloud/agent/api/CheckStateAnswer.java | 0 .../cloud/agent/api/CheckStateCommand.java | 0 .../agent/api/CheckVirtualMachineAnswer.java | 0 .../agent/api/CheckVirtualMachineCommand.java | 0 .../agent/api/CleanupNetworkRulesCmd.java | 0 .../api/CleanupSnapshotBackupCommand.java | 0 .../cloud/agent/api/ClusterSyncAnswer.java | 0 .../cloud/agent/api/ClusterSyncCommand.java | 0 .../agent/api/ComputeChecksumCommand.java | 0 .../ConsoleAccessAuthenticationAnswer.java | 0 .../ConsoleAccessAuthenticationCommand.java | 0 .../api/ConsoleProxyLoadReportCommand.java | 0 ...atePrivateTemplateFromSnapshotCommand.java | 0 ...reatePrivateTemplateFromVolumeCommand.java | 0 .../agent/api/CreateStoragePoolCommand.java | 0 .../agent/api/CreateVMSnapshotAnswer.java | 0 .../agent/api/CreateVMSnapshotCommand.java | 0 .../api/CreateVolumeFromSnapshotAnswer.java | 0 .../api/CreateVolumeFromSnapshotCommand.java | 0 .../api/CreateVolumeFromVMSnapshotAnswer.java | 0 .../CreateVolumeFromVMSnapshotCommand.java | 0 .../src/com/cloud/agent/api/CronCommand.java | 0 .../api/DeleteObjectFromSwiftCommand.java | 0 .../agent/api/DeleteSnapshotBackupAnswer.java | 0 .../api/DeleteSnapshotBackupCommand.java | 0 .../agent/api/DeleteSnapshotsDirCommand.java | 0 .../agent/api/DeleteStoragePoolCommand.java | 0 .../api/DeleteTemplateFromS3Command.java | 0 .../agent/api/DeleteVMSnapshotAnswer.java | 0 .../agent/api/DeleteVMSnapshotCommand.java | 0 .../api/DownloadSnapshotFromS3Command.java | 0 ...mplateFromS3ToSecondaryStorageCommand.java | 0 .../src/com/cloud/agent/api/FenceAnswer.java | 0 .../src/com/cloud/agent/api/FenceCommand.java | 0 .../cloud/agent/api/GetDomRVersionAnswer.java | 0 .../cloud/agent/api/GetDomRVersionCmd.java | 0 .../cloud/agent/api/GetFileStatsAnswer.java | 0 .../cloud/agent/api/GetFileStatsCommand.java | 0 .../cloud/agent/api/GetHostStatsAnswer.java | 0 .../cloud/agent/api/GetHostStatsCommand.java | 0 .../agent/api/GetStorageStatsAnswer.java | 0 .../agent/api/GetStorageStatsCommand.java | 0 .../com/cloud/agent/api/GetVmStatsAnswer.java | 0 .../cloud/agent/api/GetVmStatsCommand.java | 0 .../com/cloud/agent/api/GetVncPortAnswer.java | 0 .../cloud/agent/api/GetVncPortCommand.java | 0 .../com/cloud/agent/api/HostStatsEntry.java | 0 .../com/cloud/agent/api/MaintainAnswer.java | 0 .../com/cloud/agent/api/MaintainCommand.java | 0 .../cloud/agent/api/ManageSnapshotAnswer.java | 0 .../agent/api/ManageSnapshotCommand.java | 0 .../com/cloud/agent/api/MigrateAnswer.java | 0 .../com/cloud/agent/api/MigrateCommand.java | 0 .../agent/api/MigrateWithStorageAnswer.java | 0 .../agent/api/MigrateWithStorageCommand.java | 0 .../api/MigrateWithStorageCompleteAnswer.java | 0 .../MigrateWithStorageCompleteCommand.java | 0 .../api/MigrateWithStorageReceiveAnswer.java | 0 .../api/MigrateWithStorageReceiveCommand.java | 0 .../api/MigrateWithStorageSendAnswer.java | 0 .../api/MigrateWithStorageSendCommand.java | 0 .../cloud/agent/api/ModifySshKeysCommand.java | 0 .../agent/api/ModifyStoragePoolAnswer.java | 0 .../agent/api/ModifyStoragePoolCommand.java | 0 .../cloud/agent/api/NetworkUsageAnswer.java | 0 .../cloud/agent/api/NetworkUsageCommand.java | 0 .../src/com/cloud/agent/api/PingAnswer.java | 0 .../src/com/cloud/agent/api/PingCommand.java | 0 .../cloud/agent/api/PingRoutingCommand.java | 0 .../api/PingRoutingWithNwGroupsCommand.java | 0 .../agent/api/PingRoutingWithOvsCommand.java | 0 .../cloud/agent/api/PingStorageCommand.java | 0 .../com/cloud/agent/api/PingTestCommand.java | 0 .../com/cloud/agent/api/PlugNicAnswer.java | 0 .../com/cloud/agent/api/PlugNicCommand.java | 0 .../com/cloud/agent/api/PoolEjectCommand.java | 0 .../agent/api/PrepareForMigrationAnswer.java | 0 .../agent/api/PrepareForMigrationCommand.java | 0 .../agent/api/PrepareOCFS2NodesCommand.java | 0 .../api/PropagateResourceEventCommand.java | 0 .../src/com/cloud/agent/api/ReadyAnswer.java | 0 .../src/com/cloud/agent/api/ReadyCommand.java | 0 .../src/com/cloud/agent/api/RebootAnswer.java | 0 .../com/cloud/agent/api/RebootCommand.java | 0 .../cloud/agent/api/RebootRouterCommand.java | 0 .../agent/api/RevertToVMSnapshotAnswer.java | 0 .../agent/api/RevertToVMSnapshotCommand.java | 0 .../com/cloud/agent/api/ScaleVmAnswer.java | 0 .../com/cloud/agent/api/ScaleVmCommand.java | 0 .../api/ScheduleHostScanTaskCommand.java | 0 .../api/SecStorageFirewallCfgCommand.java | 0 .../agent/api/SecStorageSetupAnswer.java | 0 .../agent/api/SecStorageSetupCommand.java | 0 .../agent/api/SecStorageVMSetupCommand.java | 0 .../agent/api/SecurityGroupRuleAnswer.java | 0 .../agent/api/SecurityGroupRulesCmd.java | 0 .../src/com/cloud/agent/api/SetupAnswer.java | 0 .../src/com/cloud/agent/api/SetupCommand.java | 0 .../agent/api/SetupGuestNetworkAnswer.java | 0 .../agent/api/SetupGuestNetworkCommand.java | 0 .../com/cloud/agent/api/ShutdownCommand.java | 0 .../com/cloud/agent/api/SnapshotCommand.java | 0 .../src/com/cloud/agent/api/StartAnswer.java | 0 .../src/com/cloud/agent/api/StartCommand.java | 0 .../com/cloud/agent/api/StartupAnswer.java | 0 .../com/cloud/agent/api/StartupCommand.java | 0 .../agent/api/StartupExternalDhcpCommand.java | 0 .../api/StartupExternalFirewallCommand.java | 0 .../StartupExternalLoadBalancerCommand.java | 0 .../cloud/agent/api/StartupProxyCommand.java | 0 .../agent/api/StartupPxeServerCommand.java | 0 .../agent/api/StartupRoutingCommand.java | 0 .../api/StartupSecondaryStorageCommand.java | 0 .../agent/api/StartupStorageCommand.java | 0 .../api/StartupTrafficMonitorCommand.java | 0 .../src/com/cloud/agent/api/StopAnswer.java | 0 .../src/com/cloud/agent/api/StopCommand.java | 0 .../cloud/agent/api/TransferAgentCommand.java | 0 .../com/cloud/agent/api/UnPlugNicAnswer.java | 0 .../com/cloud/agent/api/UnPlugNicCommand.java | 0 .../cloud/agent/api/UnregisterVMCommand.java | 0 .../agent/api/UpdateHostPasswordCommand.java | 0 .../com/cloud/agent/api/UpgradeAnswer.java | 0 .../com/cloud/agent/api/UpgradeCommand.java | 0 .../agent/api/UpgradeSnapshotCommand.java | 0 ...mplateToS3FromSecondaryStorageCommand.java | 0 .../agent/api/VMSnapshotBaseCommand.java | 0 .../src/com/cloud/agent/api/VMSnapshotTO.java | 0 .../agent/api/ValidateSnapshotAnswer.java | 0 .../agent/api/ValidateSnapshotCommand.java | 0 .../src/com/cloud/agent/api/VmStatsEntry.java | 0 .../api/baremetal/IpmISetBootDevCommand.java | 0 .../api/baremetal/IpmiBootorResetCommand.java | 0 .../api/baremetal/PreparePxeServerAnswer.java | 0 .../baremetal/PreparePxeServerCommand.java | 0 .../prepareCreateTemplateCommand.java | 0 .../cloud/agent/api/check/CheckSshAnswer.java | 0 .../agent/api/check/CheckSshCommand.java | 0 .../api/downloadSnapshotFromSwiftCommand.java | 0 ...ateFromSwiftToSecondaryStorageCommand.java | 0 .../proxy/CheckConsoleProxyLoadCommand.java | 0 .../api/proxy/ConsoleProxyLoadAnswer.java | 0 .../cloud/agent/api/proxy/ProxyCommand.java | 0 ...rtConsoleProxyAgentHttpHandlerCommand.java | 0 .../proxy/WatchConsoleProxyLoadCommand.java | 0 .../CreateLoadBalancerApplianceCommand.java | 0 .../DestroyLoadBalancerApplianceCommand.java | 0 .../agent/api/routing/DhcpEntryCommand.java | 0 .../GlobalLoadBalancerConfigAnswer.java | 0 .../GlobalLoadBalancerConfigCommand.java | 0 .../routing/HealthCheckLBConfigAnswer.java | 0 .../routing/HealthCheckLBConfigCommand.java | 0 .../agent/api/routing/IpAssocAnswer.java | 0 .../agent/api/routing/IpAssocCommand.java | 0 .../agent/api/routing/IpAssocVpcCommand.java | 0 .../routing/LoadBalancerConfigCommand.java | 0 .../api/routing/NetworkElementCommand.java | 0 .../routing/RemoteAccessVpnCfgCommand.java | 0 .../api/routing/SavePasswordCommand.java | 0 .../api/routing/SetFirewallRulesAnswer.java | 0 .../api/routing/SetFirewallRulesCommand.java | 0 .../api/routing/SetNetworkACLAnswer.java | 0 .../api/routing/SetNetworkACLCommand.java | 0 .../routing/SetPortForwardingRulesAnswer.java | 0 .../SetPortForwardingRulesCommand.java | 0 .../SetPortForwardingRulesVpcCommand.java | 0 .../agent/api/routing/SetSourceNatAnswer.java | 0 .../api/routing/SetSourceNatCommand.java | 0 .../api/routing/SetStaticNatRulesAnswer.java | 0 .../api/routing/SetStaticNatRulesCommand.java | 0 .../api/routing/SetStaticRouteAnswer.java | 0 .../api/routing/SetStaticRouteCommand.java | 0 .../api/routing/Site2SiteVpnCfgCommand.java | 0 .../api/routing/SiteLoadBalancerConfig.java | 0 .../agent/api/routing/UserDataCommand.java | 0 .../agent/api/routing/VmDataCommand.java | 0 .../agent/api/routing/VpnUsersCfgCommand.java | 0 .../api/storage/AbstractDownloadCommand.java | 0 .../api/storage/AbstractUploadCommand.java | 0 .../agent/api/storage/CopyVolumeAnswer.java | 0 .../agent/api/storage/CopyVolumeCommand.java | 0 .../cloud/agent/api/storage/CreateAnswer.java | 0 .../agent/api/storage/CreateCommand.java | 0 .../CreateEntityDownloadURLAnswer.java | 0 .../CreateEntityDownloadURLCommand.java | 0 .../storage/CreatePrivateTemplateAnswer.java | 0 .../storage/CreatePrivateTemplateCommand.java | 0 .../DeleteEntityDownloadURLAnswer.java | 0 .../DeleteEntityDownloadURLCommand.java | 0 .../api/storage/DeleteTemplateCommand.java | 0 .../api/storage/DeleteVolumeCommand.java | 0 .../agent/api/storage/DestroyAnswer.java | 0 .../agent/api/storage/DestroyCommand.java | 0 .../agent/api/storage/DownloadAnswer.java | 0 .../agent/api/storage/DownloadCommand.java | 0 .../api/storage/DownloadProgressCommand.java | 0 .../agent/api/storage/ListTemplateAnswer.java | 0 .../api/storage/ListTemplateCommand.java | 0 .../agent/api/storage/ListVolumeAnswer.java | 0 .../agent/api/storage/ListVolumeCommand.java | 0 .../ManageVolumeAvailabilityAnswer.java | 0 .../ManageVolumeAvailabilityCommand.java | 0 .../api/storage/MigrateVolumeAnswer.java | 0 .../api/storage/MigrateVolumeCommand.java | 0 .../storage/PrimaryStorageDownloadAnswer.java | 0 .../PrimaryStorageDownloadCommand.java | 0 .../agent/api/storage/ResizeVolumeAnswer.java | 0 .../api/storage/ResizeVolumeCommand.java | 0 .../agent/api/storage/StorageCommand.java | 0 .../agent/api/storage/UpgradeDiskAnswer.java | 0 .../agent/api/storage/UpgradeDiskCommand.java | 0 .../cloud/agent/api/storage/UploadAnswer.java | 0 .../agent/api/storage/UploadCommand.java | 0 .../api/storage/UploadProgressCommand.java | 0 .../cloud/agent/api/storage/ssCommand.java | 0 ...ateToSwiftFromSecondaryStorageCommand.java | 0 .../com/cloud/resource/ResourceListener.java | 40 ++++---- .../storage/resource/StoragePoolResource.java | 0 .../agent/test/AgentControlAnswerTest.java | 0 .../agent/test/AgentControlCommandTest.java | 0 .../cloudstack/api/agent/test/AnswerTest.java | 0 .../api/agent/test/AttachIsoCommandTest.java | 0 .../agent/test/AttachVolumeAnswerTest.java | 0 .../agent/test/AttachVolumeCommandTest.java | 0 .../agent/test/BackupSnapshotAnswerTest.java | 0 .../agent/test/BackupSnapshotCommandTest.java | 0 .../agent/test/BumpUpPriorityCommandTest.java | 0 .../api/agent/test/CancelCommandTest.java | 0 .../api/agent/test/ChangeAgentAnswerTest.java | 0 .../agent/test/ChangeAgentCommandTest.java | 0 .../api/agent/test/CheckHealthAnswerTest.java | 0 .../agent/test/CheckHealthCommandTest.java | 0 .../agent/test/CheckNetworkAnswerTest.java | 0 .../agent/test/CheckNetworkCommandTest.java | 0 .../agent/test/CheckOnHostCommandTest.java | 0 .../api/agent/test/SnapshotCommandTest.java | 0 .../api/test/ResizeVolumeCommandTest.java | 0 .../src/com/cloud/capacity/CapacityVO.java | 0 .../com/cloud/certificate/CertificateVO.java | 0 .../schema}/src/com/cloud/host/DetailVO.java | 0 .../schema}/src/com/cloud/host/HostTagVO.java | 0 .../schema}/src/com/cloud/host/HostVO.java | 0 .../hypervisor/HypervisorCapabilitiesVO.java | 0 .../src/com/cloud/network/VpnUserVO.java | 0 .../network/security/SecurityGroupRuleVO.java | 0 .../security/SecurityGroupRulesVO.java | 0 .../security/SecurityGroupVMMapVO.java | 0 .../network/security/SecurityGroupVO.java | 0 .../network/security/SecurityGroupWork.java | 0 .../network/security/SecurityGroupWorkVO.java | 0 .../network/security/VmRulesetLogVO.java | 0 .../src/com/cloud/storage/DiskOfferingVO.java | 0 .../com/cloud/storage/GuestOSCategoryVO.java | 0 .../src/com/cloud/storage/GuestOSVO.java | 0 .../com/cloud/storage/LaunchPermissionVO.java | 0 .../schema}/src/com/cloud/storage/S3VO.java | 0 .../com/cloud/storage/SnapshotPolicyVO.java | 0 .../com/cloud/storage/SnapshotScheduleVO.java | 0 .../src/com/cloud/storage/SnapshotVO.java | 0 .../cloud/storage/StoragePoolHostAssoc.java | 0 .../com/cloud/storage/StoragePoolHostVO.java | 20 ++-- .../com/cloud/storage/StoragePoolWorkVO.java | 0 .../src/com/cloud/storage/SwiftVO.java | 0 .../src/com/cloud/storage/UploadVO.java | 0 .../com/cloud/storage/VMTemplateDetailVO.java | 0 .../com/cloud/storage/VMTemplateHostVO.java | 0 .../src/com/cloud/storage/VMTemplateS3VO.java | 0 .../storage/VMTemplateStoragePoolVO.java | 0 .../com/cloud/storage/VMTemplateSwiftVO.java | 0 .../src/com/cloud/storage/VMTemplateVO.java | 0 .../com/cloud/storage/VMTemplateZoneVO.java | 0 .../src/com/cloud/storage/VolumeHostVO.java | 0 .../src/com/cloud/storage/VolumeVO.java | 0 framework/jobs/pom.xml | 33 +++++-- framework/pom.xml | 1 + ...oudStackPrimaryDataStoreLifeCycleImpl.java | 44 +++------ server/pom.xml | 5 + .../src/com/cloud/alert/AlertManager.java | 0 .../src/com/cloud/async/AsyncJobVO.java | 0 .../src/com/cloud/async/SyncQueueItemVO.java | 0 .../src/com/cloud/async/SyncQueueVO.java | 0 .../cloud/capacity/CapacityManagerImpl.java | 99 +++++++++---------- .../com/cloud/storage/OCFS2ManagerImpl.java | 48 ++++----- 308 files changed, 148 insertions(+), 181 deletions(-) rename {core => api}/src/com/cloud/exception/AgentControlChannelException.java (100%) rename {core => api}/src/com/cloud/resource/UnableDeleteHostException.java (100%) rename {core => api}/src/com/cloud/storage/StoragePoolDiscoverer.java (73%) delete mode 100644 core/src/com/cloud/agent/RecoveryHandler.java rename {api => core}/src/com/cloud/agent/api/AgentControlAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/AgentControlCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/AttachIsoCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/AttachVolumeAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/AttachVolumeCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/BackupSnapshotAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/BackupSnapshotCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/BumpUpPriorityCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CancelCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/ChangeAgentAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/ChangeAgentCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckHealthAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckHealthCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckNetworkAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckNetworkCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckOnHostAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckOnHostCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckRouterAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckRouterCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckS2SVpnConnectionsCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckStateAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckStateCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckVirtualMachineAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/CheckVirtualMachineCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CleanupNetworkRulesCmd.java (100%) rename {api => core}/src/com/cloud/agent/api/CleanupSnapshotBackupCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/ClusterSyncAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/ClusterSyncCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/ComputeChecksumCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/ConsoleAccessAuthenticationAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/ConsoleAccessAuthenticationCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/ConsoleProxyLoadReportCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CreateStoragePoolCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/CreateVMSnapshotCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CreateVolumeFromSnapshotAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/CronCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/DeleteObjectFromSwiftCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/DeleteSnapshotBackupAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/DeleteStoragePoolCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/DeleteTemplateFromS3Command.java (100%) rename {api => core}/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/DownloadSnapshotFromS3Command.java (100%) rename {api => core}/src/com/cloud/agent/api/DownloadTemplateFromS3ToSecondaryStorageCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/FenceAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/FenceCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/GetDomRVersionAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/GetDomRVersionCmd.java (100%) rename {api => core}/src/com/cloud/agent/api/GetFileStatsAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/GetFileStatsCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/GetHostStatsAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/GetHostStatsCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/GetStorageStatsAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/GetStorageStatsCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/GetVmStatsAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/GetVmStatsCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/GetVncPortAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/GetVncPortCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/HostStatsEntry.java (100%) rename {api => core}/src/com/cloud/agent/api/MaintainAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/MaintainCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/ManageSnapshotAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/ManageSnapshotCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/MigrateAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/MigrateCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/MigrateWithStorageAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/MigrateWithStorageCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/MigrateWithStorageCompleteAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/MigrateWithStorageCompleteCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/MigrateWithStorageReceiveAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/MigrateWithStorageReceiveCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/MigrateWithStorageSendAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/MigrateWithStorageSendCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/ModifySshKeysCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/ModifyStoragePoolCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/NetworkUsageAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/NetworkUsageCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/PingAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/PingCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/PingRoutingCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/PingRoutingWithNwGroupsCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/PingRoutingWithOvsCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/PingStorageCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/PingTestCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/PlugNicAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/PlugNicCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/PoolEjectCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/PrepareForMigrationAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/PrepareForMigrationCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/PrepareOCFS2NodesCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/PropagateResourceEventCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/ReadyAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/ReadyCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/RebootAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/RebootCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/RebootRouterCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/ScaleVmAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/ScaleVmCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/ScheduleHostScanTaskCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/SecStorageFirewallCfgCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/SecStorageSetupAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/SecStorageSetupCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/SecStorageVMSetupCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/SecurityGroupRuleAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/SecurityGroupRulesCmd.java (100%) rename {api => core}/src/com/cloud/agent/api/SetupAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/SetupCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/SetupGuestNetworkAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/SetupGuestNetworkCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/ShutdownCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/SnapshotCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/StartAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/StartCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/StartupAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/StartupCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/StartupExternalDhcpCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/StartupExternalFirewallCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/StartupProxyCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/StartupPxeServerCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/StartupRoutingCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/StartupSecondaryStorageCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/StartupStorageCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/StartupTrafficMonitorCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/StopAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/StopCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/TransferAgentCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/UnPlugNicAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/UnPlugNicCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/UnregisterVMCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/UpdateHostPasswordCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/UpgradeAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/UpgradeCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/UpgradeSnapshotCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/UploadTemplateToS3FromSecondaryStorageCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/VMSnapshotBaseCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/VMSnapshotTO.java (100%) rename {api => core}/src/com/cloud/agent/api/ValidateSnapshotAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/ValidateSnapshotCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/VmStatsEntry.java (100%) rename {api => core}/src/com/cloud/agent/api/baremetal/IpmISetBootDevCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/baremetal/IpmiBootorResetCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/baremetal/PreparePxeServerAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/baremetal/PreparePxeServerCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/baremetal/prepareCreateTemplateCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/check/CheckSshAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/check/CheckSshCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/downloadSnapshotFromSwiftCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/downloadTemplateFromSwiftToSecondaryStorageCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/proxy/CheckConsoleProxyLoadCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/proxy/ConsoleProxyLoadAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/proxy/ProxyCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/proxy/StartConsoleProxyAgentHttpHandlerCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/proxy/WatchConsoleProxyLoadCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/CreateLoadBalancerApplianceCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/DestroyLoadBalancerApplianceCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/DhcpEntryCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/HealthCheckLBConfigAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/IpAssocAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/IpAssocCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/IpAssocVpcCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/NetworkElementCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/RemoteAccessVpnCfgCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SavePasswordCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SetFirewallRulesAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SetPortForwardingRulesAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SetPortForwardingRulesCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SetSourceNatAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SetSourceNatCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SetStaticNatRulesAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SetStaticNatRulesCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SetStaticRouteAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/SiteLoadBalancerConfig.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/UserDataCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/VmDataCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/routing/VpnUsersCfgCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/AbstractUploadCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/CopyVolumeAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/CopyVolumeCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/CreateAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/CreateCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/CreateEntityDownloadURLAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/CreatePrivateTemplateCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/DestroyAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/DestroyCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/DownloadAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/DownloadCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/DownloadProgressCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/ListTemplateAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/ListTemplateCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/ListVolumeAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/ListVolumeCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/MigrateVolumeAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/ResizeVolumeAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/ResizeVolumeCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/StorageCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/UpgradeDiskAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/UpgradeDiskCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/UploadAnswer.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/UploadCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/UploadProgressCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/storage/ssCommand.java (100%) rename {api => core}/src/com/cloud/agent/api/uploadTemplateToSwiftFromSecondaryStorageCommand.java (100%) rename {api => core}/src/com/cloud/storage/resource/StoragePoolResource.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/AgentControlAnswerTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/AgentControlCommandTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/AnswerTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/AttachIsoCommandTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/AttachVolumeAnswerTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/AttachVolumeCommandTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/BumpUpPriorityCommandTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/CancelCommandTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/ChangeAgentAnswerTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/ChangeAgentCommandTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/CheckHealthAnswerTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/CheckHealthCommandTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/CheckNetworkCommandTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/CheckOnHostCommandTest.java (100%) rename {api => core}/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java (100%) rename {api => core}/test/src/com/cloud/agent/api/test/ResizeVolumeCommandTest.java (100%) rename {core => engine/schema}/src/com/cloud/capacity/CapacityVO.java (100%) rename {core => engine/schema}/src/com/cloud/certificate/CertificateVO.java (100%) rename {core => engine/schema}/src/com/cloud/host/DetailVO.java (100%) rename {core => engine/schema}/src/com/cloud/host/HostTagVO.java (100%) rename {core => engine/schema}/src/com/cloud/host/HostVO.java (100%) rename {core => engine/schema}/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java (100%) rename {core => engine/schema}/src/com/cloud/network/VpnUserVO.java (100%) rename {core => engine/schema}/src/com/cloud/network/security/SecurityGroupRuleVO.java (100%) rename {core => engine/schema}/src/com/cloud/network/security/SecurityGroupRulesVO.java (100%) rename {core => engine/schema}/src/com/cloud/network/security/SecurityGroupVMMapVO.java (100%) rename {core => engine/schema}/src/com/cloud/network/security/SecurityGroupVO.java (100%) rename {core => engine/schema}/src/com/cloud/network/security/SecurityGroupWork.java (100%) rename {core => engine/schema}/src/com/cloud/network/security/SecurityGroupWorkVO.java (100%) rename {core => engine/schema}/src/com/cloud/network/security/VmRulesetLogVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/DiskOfferingVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/GuestOSCategoryVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/GuestOSVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/LaunchPermissionVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/S3VO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/SnapshotPolicyVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/SnapshotScheduleVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/SnapshotVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/StoragePoolHostAssoc.java (100%) rename {core => engine/schema}/src/com/cloud/storage/StoragePoolHostVO.java (94%) rename {core => engine/schema}/src/com/cloud/storage/StoragePoolWorkVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/SwiftVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/UploadVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/VMTemplateDetailVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/VMTemplateHostVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/VMTemplateS3VO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/VMTemplateStoragePoolVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/VMTemplateSwiftVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/VMTemplateVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/VMTemplateZoneVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/VolumeHostVO.java (100%) rename {core => engine/schema}/src/com/cloud/storage/VolumeVO.java (100%) rename {core => server}/src/com/cloud/alert/AlertManager.java (100%) rename {core => server}/src/com/cloud/async/AsyncJobVO.java (100%) rename {core => server}/src/com/cloud/async/SyncQueueItemVO.java (100%) rename {core => server}/src/com/cloud/async/SyncQueueVO.java (100%) diff --git a/core/src/com/cloud/exception/AgentControlChannelException.java b/api/src/com/cloud/exception/AgentControlChannelException.java similarity index 100% rename from core/src/com/cloud/exception/AgentControlChannelException.java rename to api/src/com/cloud/exception/AgentControlChannelException.java diff --git a/core/src/com/cloud/resource/UnableDeleteHostException.java b/api/src/com/cloud/resource/UnableDeleteHostException.java similarity index 100% rename from core/src/com/cloud/resource/UnableDeleteHostException.java rename to api/src/com/cloud/resource/UnableDeleteHostException.java diff --git a/core/src/com/cloud/storage/StoragePoolDiscoverer.java b/api/src/com/cloud/storage/StoragePoolDiscoverer.java similarity index 73% rename from core/src/com/cloud/storage/StoragePoolDiscoverer.java rename to api/src/com/cloud/storage/StoragePoolDiscoverer.java index c7dd362a5c3..40a925dc73e 100644 --- a/core/src/com/cloud/storage/StoragePoolDiscoverer.java +++ b/api/src/com/cloud/storage/StoragePoolDiscoverer.java @@ -19,8 +19,6 @@ package com.cloud.storage; import java.net.URI; import java.util.Map; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; - import com.cloud.exception.DiscoveryException; import com.cloud.utils.component.Adapter; @@ -29,7 +27,7 @@ import com.cloud.utils.component.Adapter; */ public interface StoragePoolDiscoverer extends Adapter { - Map> find(long dcId, Long podId, URI uri, Map details) throws DiscoveryException; - - Map> find(long dcId, Long podId, URI uri, Map details, String username, String password) throws DiscoveryException; + Map> find(long dcId, Long podId, URI uri, Map details) throws DiscoveryException; + + Map> find(long dcId, Long podId, URI uri, Map details, String username, String password) throws DiscoveryException; } diff --git a/core/src/com/cloud/agent/RecoveryHandler.java b/core/src/com/cloud/agent/RecoveryHandler.java deleted file mode 100644 index 418c7b1034f..00000000000 --- a/core/src/com/cloud/agent/RecoveryHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.agent; - -import com.cloud.agent.api.Command; - -public interface RecoveryHandler { - /** - * Perform the necessary recovery because the success of this command - * is not known. - * - * @param agentId agent the commands were sent to. - * @param seq sequence number. - * @param cmds commands that failed. - */ - public void handle(long agentId, long seq, Command[] cmds); -} diff --git a/api/src/com/cloud/agent/api/AgentControlAnswer.java b/core/src/com/cloud/agent/api/AgentControlAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/AgentControlAnswer.java rename to core/src/com/cloud/agent/api/AgentControlAnswer.java diff --git a/api/src/com/cloud/agent/api/AgentControlCommand.java b/core/src/com/cloud/agent/api/AgentControlCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/AgentControlCommand.java rename to core/src/com/cloud/agent/api/AgentControlCommand.java diff --git a/api/src/com/cloud/agent/api/AttachIsoCommand.java b/core/src/com/cloud/agent/api/AttachIsoCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/AttachIsoCommand.java rename to core/src/com/cloud/agent/api/AttachIsoCommand.java diff --git a/api/src/com/cloud/agent/api/AttachVolumeAnswer.java b/core/src/com/cloud/agent/api/AttachVolumeAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/AttachVolumeAnswer.java rename to core/src/com/cloud/agent/api/AttachVolumeAnswer.java diff --git a/api/src/com/cloud/agent/api/AttachVolumeCommand.java b/core/src/com/cloud/agent/api/AttachVolumeCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/AttachVolumeCommand.java rename to core/src/com/cloud/agent/api/AttachVolumeCommand.java diff --git a/api/src/com/cloud/agent/api/BackupSnapshotAnswer.java b/core/src/com/cloud/agent/api/BackupSnapshotAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/BackupSnapshotAnswer.java rename to core/src/com/cloud/agent/api/BackupSnapshotAnswer.java diff --git a/api/src/com/cloud/agent/api/BackupSnapshotCommand.java b/core/src/com/cloud/agent/api/BackupSnapshotCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/BackupSnapshotCommand.java rename to core/src/com/cloud/agent/api/BackupSnapshotCommand.java diff --git a/api/src/com/cloud/agent/api/BumpUpPriorityCommand.java b/core/src/com/cloud/agent/api/BumpUpPriorityCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/BumpUpPriorityCommand.java rename to core/src/com/cloud/agent/api/BumpUpPriorityCommand.java diff --git a/api/src/com/cloud/agent/api/CancelCommand.java b/core/src/com/cloud/agent/api/CancelCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CancelCommand.java rename to core/src/com/cloud/agent/api/CancelCommand.java diff --git a/api/src/com/cloud/agent/api/ChangeAgentAnswer.java b/core/src/com/cloud/agent/api/ChangeAgentAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/ChangeAgentAnswer.java rename to core/src/com/cloud/agent/api/ChangeAgentAnswer.java diff --git a/api/src/com/cloud/agent/api/ChangeAgentCommand.java b/core/src/com/cloud/agent/api/ChangeAgentCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/ChangeAgentCommand.java rename to core/src/com/cloud/agent/api/ChangeAgentCommand.java diff --git a/api/src/com/cloud/agent/api/CheckHealthAnswer.java b/core/src/com/cloud/agent/api/CheckHealthAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckHealthAnswer.java rename to core/src/com/cloud/agent/api/CheckHealthAnswer.java diff --git a/api/src/com/cloud/agent/api/CheckHealthCommand.java b/core/src/com/cloud/agent/api/CheckHealthCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckHealthCommand.java rename to core/src/com/cloud/agent/api/CheckHealthCommand.java diff --git a/api/src/com/cloud/agent/api/CheckNetworkAnswer.java b/core/src/com/cloud/agent/api/CheckNetworkAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckNetworkAnswer.java rename to core/src/com/cloud/agent/api/CheckNetworkAnswer.java diff --git a/api/src/com/cloud/agent/api/CheckNetworkCommand.java b/core/src/com/cloud/agent/api/CheckNetworkCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckNetworkCommand.java rename to core/src/com/cloud/agent/api/CheckNetworkCommand.java diff --git a/api/src/com/cloud/agent/api/CheckOnHostAnswer.java b/core/src/com/cloud/agent/api/CheckOnHostAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckOnHostAnswer.java rename to core/src/com/cloud/agent/api/CheckOnHostAnswer.java diff --git a/api/src/com/cloud/agent/api/CheckOnHostCommand.java b/core/src/com/cloud/agent/api/CheckOnHostCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckOnHostCommand.java rename to core/src/com/cloud/agent/api/CheckOnHostCommand.java diff --git a/api/src/com/cloud/agent/api/CheckRouterAnswer.java b/core/src/com/cloud/agent/api/CheckRouterAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckRouterAnswer.java rename to core/src/com/cloud/agent/api/CheckRouterAnswer.java diff --git a/api/src/com/cloud/agent/api/CheckRouterCommand.java b/core/src/com/cloud/agent/api/CheckRouterCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckRouterCommand.java rename to core/src/com/cloud/agent/api/CheckRouterCommand.java diff --git a/api/src/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java b/core/src/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java rename to core/src/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java diff --git a/api/src/com/cloud/agent/api/CheckS2SVpnConnectionsCommand.java b/core/src/com/cloud/agent/api/CheckS2SVpnConnectionsCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckS2SVpnConnectionsCommand.java rename to core/src/com/cloud/agent/api/CheckS2SVpnConnectionsCommand.java diff --git a/api/src/com/cloud/agent/api/CheckStateAnswer.java b/core/src/com/cloud/agent/api/CheckStateAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckStateAnswer.java rename to core/src/com/cloud/agent/api/CheckStateAnswer.java diff --git a/api/src/com/cloud/agent/api/CheckStateCommand.java b/core/src/com/cloud/agent/api/CheckStateCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckStateCommand.java rename to core/src/com/cloud/agent/api/CheckStateCommand.java diff --git a/api/src/com/cloud/agent/api/CheckVirtualMachineAnswer.java b/core/src/com/cloud/agent/api/CheckVirtualMachineAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckVirtualMachineAnswer.java rename to core/src/com/cloud/agent/api/CheckVirtualMachineAnswer.java diff --git a/api/src/com/cloud/agent/api/CheckVirtualMachineCommand.java b/core/src/com/cloud/agent/api/CheckVirtualMachineCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CheckVirtualMachineCommand.java rename to core/src/com/cloud/agent/api/CheckVirtualMachineCommand.java diff --git a/api/src/com/cloud/agent/api/CleanupNetworkRulesCmd.java b/core/src/com/cloud/agent/api/CleanupNetworkRulesCmd.java similarity index 100% rename from api/src/com/cloud/agent/api/CleanupNetworkRulesCmd.java rename to core/src/com/cloud/agent/api/CleanupNetworkRulesCmd.java diff --git a/api/src/com/cloud/agent/api/CleanupSnapshotBackupCommand.java b/core/src/com/cloud/agent/api/CleanupSnapshotBackupCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CleanupSnapshotBackupCommand.java rename to core/src/com/cloud/agent/api/CleanupSnapshotBackupCommand.java diff --git a/api/src/com/cloud/agent/api/ClusterSyncAnswer.java b/core/src/com/cloud/agent/api/ClusterSyncAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/ClusterSyncAnswer.java rename to core/src/com/cloud/agent/api/ClusterSyncAnswer.java diff --git a/api/src/com/cloud/agent/api/ClusterSyncCommand.java b/core/src/com/cloud/agent/api/ClusterSyncCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/ClusterSyncCommand.java rename to core/src/com/cloud/agent/api/ClusterSyncCommand.java diff --git a/api/src/com/cloud/agent/api/ComputeChecksumCommand.java b/core/src/com/cloud/agent/api/ComputeChecksumCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/ComputeChecksumCommand.java rename to core/src/com/cloud/agent/api/ComputeChecksumCommand.java diff --git a/api/src/com/cloud/agent/api/ConsoleAccessAuthenticationAnswer.java b/core/src/com/cloud/agent/api/ConsoleAccessAuthenticationAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/ConsoleAccessAuthenticationAnswer.java rename to core/src/com/cloud/agent/api/ConsoleAccessAuthenticationAnswer.java diff --git a/api/src/com/cloud/agent/api/ConsoleAccessAuthenticationCommand.java b/core/src/com/cloud/agent/api/ConsoleAccessAuthenticationCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/ConsoleAccessAuthenticationCommand.java rename to core/src/com/cloud/agent/api/ConsoleAccessAuthenticationCommand.java diff --git a/api/src/com/cloud/agent/api/ConsoleProxyLoadReportCommand.java b/core/src/com/cloud/agent/api/ConsoleProxyLoadReportCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/ConsoleProxyLoadReportCommand.java rename to core/src/com/cloud/agent/api/ConsoleProxyLoadReportCommand.java diff --git a/api/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java b/core/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java rename to core/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java diff --git a/api/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java b/core/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java rename to core/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java diff --git a/api/src/com/cloud/agent/api/CreateStoragePoolCommand.java b/core/src/com/cloud/agent/api/CreateStoragePoolCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CreateStoragePoolCommand.java rename to core/src/com/cloud/agent/api/CreateStoragePoolCommand.java diff --git a/api/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java b/core/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java rename to core/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java diff --git a/api/src/com/cloud/agent/api/CreateVMSnapshotCommand.java b/core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CreateVMSnapshotCommand.java rename to core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java diff --git a/api/src/com/cloud/agent/api/CreateVolumeFromSnapshotAnswer.java b/core/src/com/cloud/agent/api/CreateVolumeFromSnapshotAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/CreateVolumeFromSnapshotAnswer.java rename to core/src/com/cloud/agent/api/CreateVolumeFromSnapshotAnswer.java diff --git a/api/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java b/core/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java rename to core/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java diff --git a/api/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotAnswer.java b/core/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotAnswer.java rename to core/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotAnswer.java diff --git a/api/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotCommand.java b/core/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotCommand.java rename to core/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotCommand.java diff --git a/api/src/com/cloud/agent/api/CronCommand.java b/core/src/com/cloud/agent/api/CronCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/CronCommand.java rename to core/src/com/cloud/agent/api/CronCommand.java diff --git a/api/src/com/cloud/agent/api/DeleteObjectFromSwiftCommand.java b/core/src/com/cloud/agent/api/DeleteObjectFromSwiftCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/DeleteObjectFromSwiftCommand.java rename to core/src/com/cloud/agent/api/DeleteObjectFromSwiftCommand.java diff --git a/api/src/com/cloud/agent/api/DeleteSnapshotBackupAnswer.java b/core/src/com/cloud/agent/api/DeleteSnapshotBackupAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/DeleteSnapshotBackupAnswer.java rename to core/src/com/cloud/agent/api/DeleteSnapshotBackupAnswer.java diff --git a/api/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java b/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java rename to core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java diff --git a/api/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java b/core/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java rename to core/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java diff --git a/api/src/com/cloud/agent/api/DeleteStoragePoolCommand.java b/core/src/com/cloud/agent/api/DeleteStoragePoolCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/DeleteStoragePoolCommand.java rename to core/src/com/cloud/agent/api/DeleteStoragePoolCommand.java diff --git a/api/src/com/cloud/agent/api/DeleteTemplateFromS3Command.java b/core/src/com/cloud/agent/api/DeleteTemplateFromS3Command.java similarity index 100% rename from api/src/com/cloud/agent/api/DeleteTemplateFromS3Command.java rename to core/src/com/cloud/agent/api/DeleteTemplateFromS3Command.java diff --git a/api/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java b/core/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java rename to core/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java diff --git a/api/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java b/core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java rename to core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java diff --git a/api/src/com/cloud/agent/api/DownloadSnapshotFromS3Command.java b/core/src/com/cloud/agent/api/DownloadSnapshotFromS3Command.java similarity index 100% rename from api/src/com/cloud/agent/api/DownloadSnapshotFromS3Command.java rename to core/src/com/cloud/agent/api/DownloadSnapshotFromS3Command.java diff --git a/api/src/com/cloud/agent/api/DownloadTemplateFromS3ToSecondaryStorageCommand.java b/core/src/com/cloud/agent/api/DownloadTemplateFromS3ToSecondaryStorageCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/DownloadTemplateFromS3ToSecondaryStorageCommand.java rename to core/src/com/cloud/agent/api/DownloadTemplateFromS3ToSecondaryStorageCommand.java diff --git a/api/src/com/cloud/agent/api/FenceAnswer.java b/core/src/com/cloud/agent/api/FenceAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/FenceAnswer.java rename to core/src/com/cloud/agent/api/FenceAnswer.java diff --git a/api/src/com/cloud/agent/api/FenceCommand.java b/core/src/com/cloud/agent/api/FenceCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/FenceCommand.java rename to core/src/com/cloud/agent/api/FenceCommand.java diff --git a/api/src/com/cloud/agent/api/GetDomRVersionAnswer.java b/core/src/com/cloud/agent/api/GetDomRVersionAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/GetDomRVersionAnswer.java rename to core/src/com/cloud/agent/api/GetDomRVersionAnswer.java diff --git a/api/src/com/cloud/agent/api/GetDomRVersionCmd.java b/core/src/com/cloud/agent/api/GetDomRVersionCmd.java similarity index 100% rename from api/src/com/cloud/agent/api/GetDomRVersionCmd.java rename to core/src/com/cloud/agent/api/GetDomRVersionCmd.java diff --git a/api/src/com/cloud/agent/api/GetFileStatsAnswer.java b/core/src/com/cloud/agent/api/GetFileStatsAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/GetFileStatsAnswer.java rename to core/src/com/cloud/agent/api/GetFileStatsAnswer.java diff --git a/api/src/com/cloud/agent/api/GetFileStatsCommand.java b/core/src/com/cloud/agent/api/GetFileStatsCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/GetFileStatsCommand.java rename to core/src/com/cloud/agent/api/GetFileStatsCommand.java diff --git a/api/src/com/cloud/agent/api/GetHostStatsAnswer.java b/core/src/com/cloud/agent/api/GetHostStatsAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/GetHostStatsAnswer.java rename to core/src/com/cloud/agent/api/GetHostStatsAnswer.java diff --git a/api/src/com/cloud/agent/api/GetHostStatsCommand.java b/core/src/com/cloud/agent/api/GetHostStatsCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/GetHostStatsCommand.java rename to core/src/com/cloud/agent/api/GetHostStatsCommand.java diff --git a/api/src/com/cloud/agent/api/GetStorageStatsAnswer.java b/core/src/com/cloud/agent/api/GetStorageStatsAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/GetStorageStatsAnswer.java rename to core/src/com/cloud/agent/api/GetStorageStatsAnswer.java diff --git a/api/src/com/cloud/agent/api/GetStorageStatsCommand.java b/core/src/com/cloud/agent/api/GetStorageStatsCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/GetStorageStatsCommand.java rename to core/src/com/cloud/agent/api/GetStorageStatsCommand.java diff --git a/api/src/com/cloud/agent/api/GetVmStatsAnswer.java b/core/src/com/cloud/agent/api/GetVmStatsAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/GetVmStatsAnswer.java rename to core/src/com/cloud/agent/api/GetVmStatsAnswer.java diff --git a/api/src/com/cloud/agent/api/GetVmStatsCommand.java b/core/src/com/cloud/agent/api/GetVmStatsCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/GetVmStatsCommand.java rename to core/src/com/cloud/agent/api/GetVmStatsCommand.java diff --git a/api/src/com/cloud/agent/api/GetVncPortAnswer.java b/core/src/com/cloud/agent/api/GetVncPortAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/GetVncPortAnswer.java rename to core/src/com/cloud/agent/api/GetVncPortAnswer.java diff --git a/api/src/com/cloud/agent/api/GetVncPortCommand.java b/core/src/com/cloud/agent/api/GetVncPortCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/GetVncPortCommand.java rename to core/src/com/cloud/agent/api/GetVncPortCommand.java diff --git a/api/src/com/cloud/agent/api/HostStatsEntry.java b/core/src/com/cloud/agent/api/HostStatsEntry.java similarity index 100% rename from api/src/com/cloud/agent/api/HostStatsEntry.java rename to core/src/com/cloud/agent/api/HostStatsEntry.java diff --git a/api/src/com/cloud/agent/api/MaintainAnswer.java b/core/src/com/cloud/agent/api/MaintainAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/MaintainAnswer.java rename to core/src/com/cloud/agent/api/MaintainAnswer.java diff --git a/api/src/com/cloud/agent/api/MaintainCommand.java b/core/src/com/cloud/agent/api/MaintainCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/MaintainCommand.java rename to core/src/com/cloud/agent/api/MaintainCommand.java diff --git a/api/src/com/cloud/agent/api/ManageSnapshotAnswer.java b/core/src/com/cloud/agent/api/ManageSnapshotAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/ManageSnapshotAnswer.java rename to core/src/com/cloud/agent/api/ManageSnapshotAnswer.java diff --git a/api/src/com/cloud/agent/api/ManageSnapshotCommand.java b/core/src/com/cloud/agent/api/ManageSnapshotCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/ManageSnapshotCommand.java rename to core/src/com/cloud/agent/api/ManageSnapshotCommand.java diff --git a/api/src/com/cloud/agent/api/MigrateAnswer.java b/core/src/com/cloud/agent/api/MigrateAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/MigrateAnswer.java rename to core/src/com/cloud/agent/api/MigrateAnswer.java diff --git a/api/src/com/cloud/agent/api/MigrateCommand.java b/core/src/com/cloud/agent/api/MigrateCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/MigrateCommand.java rename to core/src/com/cloud/agent/api/MigrateCommand.java diff --git a/api/src/com/cloud/agent/api/MigrateWithStorageAnswer.java b/core/src/com/cloud/agent/api/MigrateWithStorageAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/MigrateWithStorageAnswer.java rename to core/src/com/cloud/agent/api/MigrateWithStorageAnswer.java diff --git a/api/src/com/cloud/agent/api/MigrateWithStorageCommand.java b/core/src/com/cloud/agent/api/MigrateWithStorageCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/MigrateWithStorageCommand.java rename to core/src/com/cloud/agent/api/MigrateWithStorageCommand.java diff --git a/api/src/com/cloud/agent/api/MigrateWithStorageCompleteAnswer.java b/core/src/com/cloud/agent/api/MigrateWithStorageCompleteAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/MigrateWithStorageCompleteAnswer.java rename to core/src/com/cloud/agent/api/MigrateWithStorageCompleteAnswer.java diff --git a/api/src/com/cloud/agent/api/MigrateWithStorageCompleteCommand.java b/core/src/com/cloud/agent/api/MigrateWithStorageCompleteCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/MigrateWithStorageCompleteCommand.java rename to core/src/com/cloud/agent/api/MigrateWithStorageCompleteCommand.java diff --git a/api/src/com/cloud/agent/api/MigrateWithStorageReceiveAnswer.java b/core/src/com/cloud/agent/api/MigrateWithStorageReceiveAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/MigrateWithStorageReceiveAnswer.java rename to core/src/com/cloud/agent/api/MigrateWithStorageReceiveAnswer.java diff --git a/api/src/com/cloud/agent/api/MigrateWithStorageReceiveCommand.java b/core/src/com/cloud/agent/api/MigrateWithStorageReceiveCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/MigrateWithStorageReceiveCommand.java rename to core/src/com/cloud/agent/api/MigrateWithStorageReceiveCommand.java diff --git a/api/src/com/cloud/agent/api/MigrateWithStorageSendAnswer.java b/core/src/com/cloud/agent/api/MigrateWithStorageSendAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/MigrateWithStorageSendAnswer.java rename to core/src/com/cloud/agent/api/MigrateWithStorageSendAnswer.java diff --git a/api/src/com/cloud/agent/api/MigrateWithStorageSendCommand.java b/core/src/com/cloud/agent/api/MigrateWithStorageSendCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/MigrateWithStorageSendCommand.java rename to core/src/com/cloud/agent/api/MigrateWithStorageSendCommand.java diff --git a/api/src/com/cloud/agent/api/ModifySshKeysCommand.java b/core/src/com/cloud/agent/api/ModifySshKeysCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/ModifySshKeysCommand.java rename to core/src/com/cloud/agent/api/ModifySshKeysCommand.java diff --git a/api/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java b/core/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java rename to core/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java diff --git a/api/src/com/cloud/agent/api/ModifyStoragePoolCommand.java b/core/src/com/cloud/agent/api/ModifyStoragePoolCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/ModifyStoragePoolCommand.java rename to core/src/com/cloud/agent/api/ModifyStoragePoolCommand.java diff --git a/api/src/com/cloud/agent/api/NetworkUsageAnswer.java b/core/src/com/cloud/agent/api/NetworkUsageAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/NetworkUsageAnswer.java rename to core/src/com/cloud/agent/api/NetworkUsageAnswer.java diff --git a/api/src/com/cloud/agent/api/NetworkUsageCommand.java b/core/src/com/cloud/agent/api/NetworkUsageCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/NetworkUsageCommand.java rename to core/src/com/cloud/agent/api/NetworkUsageCommand.java diff --git a/api/src/com/cloud/agent/api/PingAnswer.java b/core/src/com/cloud/agent/api/PingAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/PingAnswer.java rename to core/src/com/cloud/agent/api/PingAnswer.java diff --git a/api/src/com/cloud/agent/api/PingCommand.java b/core/src/com/cloud/agent/api/PingCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/PingCommand.java rename to core/src/com/cloud/agent/api/PingCommand.java diff --git a/api/src/com/cloud/agent/api/PingRoutingCommand.java b/core/src/com/cloud/agent/api/PingRoutingCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/PingRoutingCommand.java rename to core/src/com/cloud/agent/api/PingRoutingCommand.java diff --git a/api/src/com/cloud/agent/api/PingRoutingWithNwGroupsCommand.java b/core/src/com/cloud/agent/api/PingRoutingWithNwGroupsCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/PingRoutingWithNwGroupsCommand.java rename to core/src/com/cloud/agent/api/PingRoutingWithNwGroupsCommand.java diff --git a/api/src/com/cloud/agent/api/PingRoutingWithOvsCommand.java b/core/src/com/cloud/agent/api/PingRoutingWithOvsCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/PingRoutingWithOvsCommand.java rename to core/src/com/cloud/agent/api/PingRoutingWithOvsCommand.java diff --git a/api/src/com/cloud/agent/api/PingStorageCommand.java b/core/src/com/cloud/agent/api/PingStorageCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/PingStorageCommand.java rename to core/src/com/cloud/agent/api/PingStorageCommand.java diff --git a/api/src/com/cloud/agent/api/PingTestCommand.java b/core/src/com/cloud/agent/api/PingTestCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/PingTestCommand.java rename to core/src/com/cloud/agent/api/PingTestCommand.java diff --git a/api/src/com/cloud/agent/api/PlugNicAnswer.java b/core/src/com/cloud/agent/api/PlugNicAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/PlugNicAnswer.java rename to core/src/com/cloud/agent/api/PlugNicAnswer.java diff --git a/api/src/com/cloud/agent/api/PlugNicCommand.java b/core/src/com/cloud/agent/api/PlugNicCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/PlugNicCommand.java rename to core/src/com/cloud/agent/api/PlugNicCommand.java diff --git a/api/src/com/cloud/agent/api/PoolEjectCommand.java b/core/src/com/cloud/agent/api/PoolEjectCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/PoolEjectCommand.java rename to core/src/com/cloud/agent/api/PoolEjectCommand.java diff --git a/api/src/com/cloud/agent/api/PrepareForMigrationAnswer.java b/core/src/com/cloud/agent/api/PrepareForMigrationAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/PrepareForMigrationAnswer.java rename to core/src/com/cloud/agent/api/PrepareForMigrationAnswer.java diff --git a/api/src/com/cloud/agent/api/PrepareForMigrationCommand.java b/core/src/com/cloud/agent/api/PrepareForMigrationCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/PrepareForMigrationCommand.java rename to core/src/com/cloud/agent/api/PrepareForMigrationCommand.java diff --git a/api/src/com/cloud/agent/api/PrepareOCFS2NodesCommand.java b/core/src/com/cloud/agent/api/PrepareOCFS2NodesCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/PrepareOCFS2NodesCommand.java rename to core/src/com/cloud/agent/api/PrepareOCFS2NodesCommand.java diff --git a/api/src/com/cloud/agent/api/PropagateResourceEventCommand.java b/core/src/com/cloud/agent/api/PropagateResourceEventCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/PropagateResourceEventCommand.java rename to core/src/com/cloud/agent/api/PropagateResourceEventCommand.java diff --git a/api/src/com/cloud/agent/api/ReadyAnswer.java b/core/src/com/cloud/agent/api/ReadyAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/ReadyAnswer.java rename to core/src/com/cloud/agent/api/ReadyAnswer.java diff --git a/api/src/com/cloud/agent/api/ReadyCommand.java b/core/src/com/cloud/agent/api/ReadyCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/ReadyCommand.java rename to core/src/com/cloud/agent/api/ReadyCommand.java diff --git a/api/src/com/cloud/agent/api/RebootAnswer.java b/core/src/com/cloud/agent/api/RebootAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/RebootAnswer.java rename to core/src/com/cloud/agent/api/RebootAnswer.java diff --git a/api/src/com/cloud/agent/api/RebootCommand.java b/core/src/com/cloud/agent/api/RebootCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/RebootCommand.java rename to core/src/com/cloud/agent/api/RebootCommand.java diff --git a/api/src/com/cloud/agent/api/RebootRouterCommand.java b/core/src/com/cloud/agent/api/RebootRouterCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/RebootRouterCommand.java rename to core/src/com/cloud/agent/api/RebootRouterCommand.java diff --git a/api/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java b/core/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java rename to core/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java diff --git a/api/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java b/core/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java rename to core/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java diff --git a/api/src/com/cloud/agent/api/ScaleVmAnswer.java b/core/src/com/cloud/agent/api/ScaleVmAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/ScaleVmAnswer.java rename to core/src/com/cloud/agent/api/ScaleVmAnswer.java diff --git a/api/src/com/cloud/agent/api/ScaleVmCommand.java b/core/src/com/cloud/agent/api/ScaleVmCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/ScaleVmCommand.java rename to core/src/com/cloud/agent/api/ScaleVmCommand.java diff --git a/api/src/com/cloud/agent/api/ScheduleHostScanTaskCommand.java b/core/src/com/cloud/agent/api/ScheduleHostScanTaskCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/ScheduleHostScanTaskCommand.java rename to core/src/com/cloud/agent/api/ScheduleHostScanTaskCommand.java diff --git a/api/src/com/cloud/agent/api/SecStorageFirewallCfgCommand.java b/core/src/com/cloud/agent/api/SecStorageFirewallCfgCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/SecStorageFirewallCfgCommand.java rename to core/src/com/cloud/agent/api/SecStorageFirewallCfgCommand.java diff --git a/api/src/com/cloud/agent/api/SecStorageSetupAnswer.java b/core/src/com/cloud/agent/api/SecStorageSetupAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/SecStorageSetupAnswer.java rename to core/src/com/cloud/agent/api/SecStorageSetupAnswer.java diff --git a/api/src/com/cloud/agent/api/SecStorageSetupCommand.java b/core/src/com/cloud/agent/api/SecStorageSetupCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/SecStorageSetupCommand.java rename to core/src/com/cloud/agent/api/SecStorageSetupCommand.java diff --git a/api/src/com/cloud/agent/api/SecStorageVMSetupCommand.java b/core/src/com/cloud/agent/api/SecStorageVMSetupCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/SecStorageVMSetupCommand.java rename to core/src/com/cloud/agent/api/SecStorageVMSetupCommand.java diff --git a/api/src/com/cloud/agent/api/SecurityGroupRuleAnswer.java b/core/src/com/cloud/agent/api/SecurityGroupRuleAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/SecurityGroupRuleAnswer.java rename to core/src/com/cloud/agent/api/SecurityGroupRuleAnswer.java diff --git a/api/src/com/cloud/agent/api/SecurityGroupRulesCmd.java b/core/src/com/cloud/agent/api/SecurityGroupRulesCmd.java similarity index 100% rename from api/src/com/cloud/agent/api/SecurityGroupRulesCmd.java rename to core/src/com/cloud/agent/api/SecurityGroupRulesCmd.java diff --git a/api/src/com/cloud/agent/api/SetupAnswer.java b/core/src/com/cloud/agent/api/SetupAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/SetupAnswer.java rename to core/src/com/cloud/agent/api/SetupAnswer.java diff --git a/api/src/com/cloud/agent/api/SetupCommand.java b/core/src/com/cloud/agent/api/SetupCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/SetupCommand.java rename to core/src/com/cloud/agent/api/SetupCommand.java diff --git a/api/src/com/cloud/agent/api/SetupGuestNetworkAnswer.java b/core/src/com/cloud/agent/api/SetupGuestNetworkAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/SetupGuestNetworkAnswer.java rename to core/src/com/cloud/agent/api/SetupGuestNetworkAnswer.java diff --git a/api/src/com/cloud/agent/api/SetupGuestNetworkCommand.java b/core/src/com/cloud/agent/api/SetupGuestNetworkCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/SetupGuestNetworkCommand.java rename to core/src/com/cloud/agent/api/SetupGuestNetworkCommand.java diff --git a/api/src/com/cloud/agent/api/ShutdownCommand.java b/core/src/com/cloud/agent/api/ShutdownCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/ShutdownCommand.java rename to core/src/com/cloud/agent/api/ShutdownCommand.java diff --git a/api/src/com/cloud/agent/api/SnapshotCommand.java b/core/src/com/cloud/agent/api/SnapshotCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/SnapshotCommand.java rename to core/src/com/cloud/agent/api/SnapshotCommand.java diff --git a/api/src/com/cloud/agent/api/StartAnswer.java b/core/src/com/cloud/agent/api/StartAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/StartAnswer.java rename to core/src/com/cloud/agent/api/StartAnswer.java diff --git a/api/src/com/cloud/agent/api/StartCommand.java b/core/src/com/cloud/agent/api/StartCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/StartCommand.java rename to core/src/com/cloud/agent/api/StartCommand.java diff --git a/api/src/com/cloud/agent/api/StartupAnswer.java b/core/src/com/cloud/agent/api/StartupAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/StartupAnswer.java rename to core/src/com/cloud/agent/api/StartupAnswer.java diff --git a/api/src/com/cloud/agent/api/StartupCommand.java b/core/src/com/cloud/agent/api/StartupCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/StartupCommand.java rename to core/src/com/cloud/agent/api/StartupCommand.java diff --git a/api/src/com/cloud/agent/api/StartupExternalDhcpCommand.java b/core/src/com/cloud/agent/api/StartupExternalDhcpCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/StartupExternalDhcpCommand.java rename to core/src/com/cloud/agent/api/StartupExternalDhcpCommand.java diff --git a/api/src/com/cloud/agent/api/StartupExternalFirewallCommand.java b/core/src/com/cloud/agent/api/StartupExternalFirewallCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/StartupExternalFirewallCommand.java rename to core/src/com/cloud/agent/api/StartupExternalFirewallCommand.java diff --git a/api/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java b/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java rename to core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java diff --git a/api/src/com/cloud/agent/api/StartupProxyCommand.java b/core/src/com/cloud/agent/api/StartupProxyCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/StartupProxyCommand.java rename to core/src/com/cloud/agent/api/StartupProxyCommand.java diff --git a/api/src/com/cloud/agent/api/StartupPxeServerCommand.java b/core/src/com/cloud/agent/api/StartupPxeServerCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/StartupPxeServerCommand.java rename to core/src/com/cloud/agent/api/StartupPxeServerCommand.java diff --git a/api/src/com/cloud/agent/api/StartupRoutingCommand.java b/core/src/com/cloud/agent/api/StartupRoutingCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/StartupRoutingCommand.java rename to core/src/com/cloud/agent/api/StartupRoutingCommand.java diff --git a/api/src/com/cloud/agent/api/StartupSecondaryStorageCommand.java b/core/src/com/cloud/agent/api/StartupSecondaryStorageCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/StartupSecondaryStorageCommand.java rename to core/src/com/cloud/agent/api/StartupSecondaryStorageCommand.java diff --git a/api/src/com/cloud/agent/api/StartupStorageCommand.java b/core/src/com/cloud/agent/api/StartupStorageCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/StartupStorageCommand.java rename to core/src/com/cloud/agent/api/StartupStorageCommand.java diff --git a/api/src/com/cloud/agent/api/StartupTrafficMonitorCommand.java b/core/src/com/cloud/agent/api/StartupTrafficMonitorCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/StartupTrafficMonitorCommand.java rename to core/src/com/cloud/agent/api/StartupTrafficMonitorCommand.java diff --git a/api/src/com/cloud/agent/api/StopAnswer.java b/core/src/com/cloud/agent/api/StopAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/StopAnswer.java rename to core/src/com/cloud/agent/api/StopAnswer.java diff --git a/api/src/com/cloud/agent/api/StopCommand.java b/core/src/com/cloud/agent/api/StopCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/StopCommand.java rename to core/src/com/cloud/agent/api/StopCommand.java diff --git a/api/src/com/cloud/agent/api/TransferAgentCommand.java b/core/src/com/cloud/agent/api/TransferAgentCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/TransferAgentCommand.java rename to core/src/com/cloud/agent/api/TransferAgentCommand.java diff --git a/api/src/com/cloud/agent/api/UnPlugNicAnswer.java b/core/src/com/cloud/agent/api/UnPlugNicAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/UnPlugNicAnswer.java rename to core/src/com/cloud/agent/api/UnPlugNicAnswer.java diff --git a/api/src/com/cloud/agent/api/UnPlugNicCommand.java b/core/src/com/cloud/agent/api/UnPlugNicCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/UnPlugNicCommand.java rename to core/src/com/cloud/agent/api/UnPlugNicCommand.java diff --git a/api/src/com/cloud/agent/api/UnregisterVMCommand.java b/core/src/com/cloud/agent/api/UnregisterVMCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/UnregisterVMCommand.java rename to core/src/com/cloud/agent/api/UnregisterVMCommand.java diff --git a/api/src/com/cloud/agent/api/UpdateHostPasswordCommand.java b/core/src/com/cloud/agent/api/UpdateHostPasswordCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/UpdateHostPasswordCommand.java rename to core/src/com/cloud/agent/api/UpdateHostPasswordCommand.java diff --git a/api/src/com/cloud/agent/api/UpgradeAnswer.java b/core/src/com/cloud/agent/api/UpgradeAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/UpgradeAnswer.java rename to core/src/com/cloud/agent/api/UpgradeAnswer.java diff --git a/api/src/com/cloud/agent/api/UpgradeCommand.java b/core/src/com/cloud/agent/api/UpgradeCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/UpgradeCommand.java rename to core/src/com/cloud/agent/api/UpgradeCommand.java diff --git a/api/src/com/cloud/agent/api/UpgradeSnapshotCommand.java b/core/src/com/cloud/agent/api/UpgradeSnapshotCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/UpgradeSnapshotCommand.java rename to core/src/com/cloud/agent/api/UpgradeSnapshotCommand.java diff --git a/api/src/com/cloud/agent/api/UploadTemplateToS3FromSecondaryStorageCommand.java b/core/src/com/cloud/agent/api/UploadTemplateToS3FromSecondaryStorageCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/UploadTemplateToS3FromSecondaryStorageCommand.java rename to core/src/com/cloud/agent/api/UploadTemplateToS3FromSecondaryStorageCommand.java diff --git a/api/src/com/cloud/agent/api/VMSnapshotBaseCommand.java b/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/VMSnapshotBaseCommand.java rename to core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java diff --git a/api/src/com/cloud/agent/api/VMSnapshotTO.java b/core/src/com/cloud/agent/api/VMSnapshotTO.java similarity index 100% rename from api/src/com/cloud/agent/api/VMSnapshotTO.java rename to core/src/com/cloud/agent/api/VMSnapshotTO.java diff --git a/api/src/com/cloud/agent/api/ValidateSnapshotAnswer.java b/core/src/com/cloud/agent/api/ValidateSnapshotAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/ValidateSnapshotAnswer.java rename to core/src/com/cloud/agent/api/ValidateSnapshotAnswer.java diff --git a/api/src/com/cloud/agent/api/ValidateSnapshotCommand.java b/core/src/com/cloud/agent/api/ValidateSnapshotCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/ValidateSnapshotCommand.java rename to core/src/com/cloud/agent/api/ValidateSnapshotCommand.java diff --git a/api/src/com/cloud/agent/api/VmStatsEntry.java b/core/src/com/cloud/agent/api/VmStatsEntry.java similarity index 100% rename from api/src/com/cloud/agent/api/VmStatsEntry.java rename to core/src/com/cloud/agent/api/VmStatsEntry.java diff --git a/api/src/com/cloud/agent/api/baremetal/IpmISetBootDevCommand.java b/core/src/com/cloud/agent/api/baremetal/IpmISetBootDevCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/baremetal/IpmISetBootDevCommand.java rename to core/src/com/cloud/agent/api/baremetal/IpmISetBootDevCommand.java diff --git a/api/src/com/cloud/agent/api/baremetal/IpmiBootorResetCommand.java b/core/src/com/cloud/agent/api/baremetal/IpmiBootorResetCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/baremetal/IpmiBootorResetCommand.java rename to core/src/com/cloud/agent/api/baremetal/IpmiBootorResetCommand.java diff --git a/api/src/com/cloud/agent/api/baremetal/PreparePxeServerAnswer.java b/core/src/com/cloud/agent/api/baremetal/PreparePxeServerAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/baremetal/PreparePxeServerAnswer.java rename to core/src/com/cloud/agent/api/baremetal/PreparePxeServerAnswer.java diff --git a/api/src/com/cloud/agent/api/baremetal/PreparePxeServerCommand.java b/core/src/com/cloud/agent/api/baremetal/PreparePxeServerCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/baremetal/PreparePxeServerCommand.java rename to core/src/com/cloud/agent/api/baremetal/PreparePxeServerCommand.java diff --git a/api/src/com/cloud/agent/api/baremetal/prepareCreateTemplateCommand.java b/core/src/com/cloud/agent/api/baremetal/prepareCreateTemplateCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/baremetal/prepareCreateTemplateCommand.java rename to core/src/com/cloud/agent/api/baremetal/prepareCreateTemplateCommand.java diff --git a/api/src/com/cloud/agent/api/check/CheckSshAnswer.java b/core/src/com/cloud/agent/api/check/CheckSshAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/check/CheckSshAnswer.java rename to core/src/com/cloud/agent/api/check/CheckSshAnswer.java diff --git a/api/src/com/cloud/agent/api/check/CheckSshCommand.java b/core/src/com/cloud/agent/api/check/CheckSshCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/check/CheckSshCommand.java rename to core/src/com/cloud/agent/api/check/CheckSshCommand.java diff --git a/api/src/com/cloud/agent/api/downloadSnapshotFromSwiftCommand.java b/core/src/com/cloud/agent/api/downloadSnapshotFromSwiftCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/downloadSnapshotFromSwiftCommand.java rename to core/src/com/cloud/agent/api/downloadSnapshotFromSwiftCommand.java diff --git a/api/src/com/cloud/agent/api/downloadTemplateFromSwiftToSecondaryStorageCommand.java b/core/src/com/cloud/agent/api/downloadTemplateFromSwiftToSecondaryStorageCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/downloadTemplateFromSwiftToSecondaryStorageCommand.java rename to core/src/com/cloud/agent/api/downloadTemplateFromSwiftToSecondaryStorageCommand.java diff --git a/api/src/com/cloud/agent/api/proxy/CheckConsoleProxyLoadCommand.java b/core/src/com/cloud/agent/api/proxy/CheckConsoleProxyLoadCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/proxy/CheckConsoleProxyLoadCommand.java rename to core/src/com/cloud/agent/api/proxy/CheckConsoleProxyLoadCommand.java diff --git a/api/src/com/cloud/agent/api/proxy/ConsoleProxyLoadAnswer.java b/core/src/com/cloud/agent/api/proxy/ConsoleProxyLoadAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/proxy/ConsoleProxyLoadAnswer.java rename to core/src/com/cloud/agent/api/proxy/ConsoleProxyLoadAnswer.java diff --git a/api/src/com/cloud/agent/api/proxy/ProxyCommand.java b/core/src/com/cloud/agent/api/proxy/ProxyCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/proxy/ProxyCommand.java rename to core/src/com/cloud/agent/api/proxy/ProxyCommand.java diff --git a/api/src/com/cloud/agent/api/proxy/StartConsoleProxyAgentHttpHandlerCommand.java b/core/src/com/cloud/agent/api/proxy/StartConsoleProxyAgentHttpHandlerCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/proxy/StartConsoleProxyAgentHttpHandlerCommand.java rename to core/src/com/cloud/agent/api/proxy/StartConsoleProxyAgentHttpHandlerCommand.java diff --git a/api/src/com/cloud/agent/api/proxy/WatchConsoleProxyLoadCommand.java b/core/src/com/cloud/agent/api/proxy/WatchConsoleProxyLoadCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/proxy/WatchConsoleProxyLoadCommand.java rename to core/src/com/cloud/agent/api/proxy/WatchConsoleProxyLoadCommand.java diff --git a/api/src/com/cloud/agent/api/routing/CreateLoadBalancerApplianceCommand.java b/core/src/com/cloud/agent/api/routing/CreateLoadBalancerApplianceCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/CreateLoadBalancerApplianceCommand.java rename to core/src/com/cloud/agent/api/routing/CreateLoadBalancerApplianceCommand.java diff --git a/api/src/com/cloud/agent/api/routing/DestroyLoadBalancerApplianceCommand.java b/core/src/com/cloud/agent/api/routing/DestroyLoadBalancerApplianceCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/DestroyLoadBalancerApplianceCommand.java rename to core/src/com/cloud/agent/api/routing/DestroyLoadBalancerApplianceCommand.java diff --git a/api/src/com/cloud/agent/api/routing/DhcpEntryCommand.java b/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/DhcpEntryCommand.java rename to core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java diff --git a/api/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigAnswer.java b/core/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigAnswer.java rename to core/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigAnswer.java diff --git a/api/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigCommand.java b/core/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigCommand.java rename to core/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigCommand.java diff --git a/api/src/com/cloud/agent/api/routing/HealthCheckLBConfigAnswer.java b/core/src/com/cloud/agent/api/routing/HealthCheckLBConfigAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/HealthCheckLBConfigAnswer.java rename to core/src/com/cloud/agent/api/routing/HealthCheckLBConfigAnswer.java diff --git a/api/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java b/core/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java rename to core/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java diff --git a/api/src/com/cloud/agent/api/routing/IpAssocAnswer.java b/core/src/com/cloud/agent/api/routing/IpAssocAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/IpAssocAnswer.java rename to core/src/com/cloud/agent/api/routing/IpAssocAnswer.java diff --git a/api/src/com/cloud/agent/api/routing/IpAssocCommand.java b/core/src/com/cloud/agent/api/routing/IpAssocCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/IpAssocCommand.java rename to core/src/com/cloud/agent/api/routing/IpAssocCommand.java diff --git a/api/src/com/cloud/agent/api/routing/IpAssocVpcCommand.java b/core/src/com/cloud/agent/api/routing/IpAssocVpcCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/IpAssocVpcCommand.java rename to core/src/com/cloud/agent/api/routing/IpAssocVpcCommand.java diff --git a/api/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java b/core/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java rename to core/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java diff --git a/api/src/com/cloud/agent/api/routing/NetworkElementCommand.java b/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/NetworkElementCommand.java rename to core/src/com/cloud/agent/api/routing/NetworkElementCommand.java diff --git a/api/src/com/cloud/agent/api/routing/RemoteAccessVpnCfgCommand.java b/core/src/com/cloud/agent/api/routing/RemoteAccessVpnCfgCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/RemoteAccessVpnCfgCommand.java rename to core/src/com/cloud/agent/api/routing/RemoteAccessVpnCfgCommand.java diff --git a/api/src/com/cloud/agent/api/routing/SavePasswordCommand.java b/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SavePasswordCommand.java rename to core/src/com/cloud/agent/api/routing/SavePasswordCommand.java diff --git a/api/src/com/cloud/agent/api/routing/SetFirewallRulesAnswer.java b/core/src/com/cloud/agent/api/routing/SetFirewallRulesAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SetFirewallRulesAnswer.java rename to core/src/com/cloud/agent/api/routing/SetFirewallRulesAnswer.java diff --git a/api/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java b/core/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java rename to core/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java diff --git a/api/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java b/core/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java rename to core/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java diff --git a/api/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java b/core/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java rename to core/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java diff --git a/api/src/com/cloud/agent/api/routing/SetPortForwardingRulesAnswer.java b/core/src/com/cloud/agent/api/routing/SetPortForwardingRulesAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SetPortForwardingRulesAnswer.java rename to core/src/com/cloud/agent/api/routing/SetPortForwardingRulesAnswer.java diff --git a/api/src/com/cloud/agent/api/routing/SetPortForwardingRulesCommand.java b/core/src/com/cloud/agent/api/routing/SetPortForwardingRulesCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SetPortForwardingRulesCommand.java rename to core/src/com/cloud/agent/api/routing/SetPortForwardingRulesCommand.java diff --git a/api/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java b/core/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java rename to core/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java diff --git a/api/src/com/cloud/agent/api/routing/SetSourceNatAnswer.java b/core/src/com/cloud/agent/api/routing/SetSourceNatAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SetSourceNatAnswer.java rename to core/src/com/cloud/agent/api/routing/SetSourceNatAnswer.java diff --git a/api/src/com/cloud/agent/api/routing/SetSourceNatCommand.java b/core/src/com/cloud/agent/api/routing/SetSourceNatCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SetSourceNatCommand.java rename to core/src/com/cloud/agent/api/routing/SetSourceNatCommand.java diff --git a/api/src/com/cloud/agent/api/routing/SetStaticNatRulesAnswer.java b/core/src/com/cloud/agent/api/routing/SetStaticNatRulesAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SetStaticNatRulesAnswer.java rename to core/src/com/cloud/agent/api/routing/SetStaticNatRulesAnswer.java diff --git a/api/src/com/cloud/agent/api/routing/SetStaticNatRulesCommand.java b/core/src/com/cloud/agent/api/routing/SetStaticNatRulesCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SetStaticNatRulesCommand.java rename to core/src/com/cloud/agent/api/routing/SetStaticNatRulesCommand.java diff --git a/api/src/com/cloud/agent/api/routing/SetStaticRouteAnswer.java b/core/src/com/cloud/agent/api/routing/SetStaticRouteAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SetStaticRouteAnswer.java rename to core/src/com/cloud/agent/api/routing/SetStaticRouteAnswer.java diff --git a/api/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java b/core/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java rename to core/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java diff --git a/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java b/core/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java rename to core/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java diff --git a/api/src/com/cloud/agent/api/routing/SiteLoadBalancerConfig.java b/core/src/com/cloud/agent/api/routing/SiteLoadBalancerConfig.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/SiteLoadBalancerConfig.java rename to core/src/com/cloud/agent/api/routing/SiteLoadBalancerConfig.java diff --git a/api/src/com/cloud/agent/api/routing/UserDataCommand.java b/core/src/com/cloud/agent/api/routing/UserDataCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/UserDataCommand.java rename to core/src/com/cloud/agent/api/routing/UserDataCommand.java diff --git a/api/src/com/cloud/agent/api/routing/VmDataCommand.java b/core/src/com/cloud/agent/api/routing/VmDataCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/VmDataCommand.java rename to core/src/com/cloud/agent/api/routing/VmDataCommand.java diff --git a/api/src/com/cloud/agent/api/routing/VpnUsersCfgCommand.java b/core/src/com/cloud/agent/api/routing/VpnUsersCfgCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/routing/VpnUsersCfgCommand.java rename to core/src/com/cloud/agent/api/routing/VpnUsersCfgCommand.java diff --git a/api/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java b/core/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java rename to core/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java diff --git a/api/src/com/cloud/agent/api/storage/AbstractUploadCommand.java b/core/src/com/cloud/agent/api/storage/AbstractUploadCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/AbstractUploadCommand.java rename to core/src/com/cloud/agent/api/storage/AbstractUploadCommand.java diff --git a/api/src/com/cloud/agent/api/storage/CopyVolumeAnswer.java b/core/src/com/cloud/agent/api/storage/CopyVolumeAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/CopyVolumeAnswer.java rename to core/src/com/cloud/agent/api/storage/CopyVolumeAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/CopyVolumeCommand.java b/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/CopyVolumeCommand.java rename to core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java diff --git a/api/src/com/cloud/agent/api/storage/CreateAnswer.java b/core/src/com/cloud/agent/api/storage/CreateAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/CreateAnswer.java rename to core/src/com/cloud/agent/api/storage/CreateAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/CreateCommand.java b/core/src/com/cloud/agent/api/storage/CreateCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/CreateCommand.java rename to core/src/com/cloud/agent/api/storage/CreateCommand.java diff --git a/api/src/com/cloud/agent/api/storage/CreateEntityDownloadURLAnswer.java b/core/src/com/cloud/agent/api/storage/CreateEntityDownloadURLAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/CreateEntityDownloadURLAnswer.java rename to core/src/com/cloud/agent/api/storage/CreateEntityDownloadURLAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java b/core/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java rename to core/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java diff --git a/api/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java b/core/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java rename to core/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/CreatePrivateTemplateCommand.java b/core/src/com/cloud/agent/api/storage/CreatePrivateTemplateCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/CreatePrivateTemplateCommand.java rename to core/src/com/cloud/agent/api/storage/CreatePrivateTemplateCommand.java diff --git a/api/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLAnswer.java b/core/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLAnswer.java rename to core/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLCommand.java b/core/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLCommand.java rename to core/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLCommand.java diff --git a/api/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java b/core/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java rename to core/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java diff --git a/api/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java b/core/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java rename to core/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java diff --git a/api/src/com/cloud/agent/api/storage/DestroyAnswer.java b/core/src/com/cloud/agent/api/storage/DestroyAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/DestroyAnswer.java rename to core/src/com/cloud/agent/api/storage/DestroyAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/DestroyCommand.java b/core/src/com/cloud/agent/api/storage/DestroyCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/DestroyCommand.java rename to core/src/com/cloud/agent/api/storage/DestroyCommand.java diff --git a/api/src/com/cloud/agent/api/storage/DownloadAnswer.java b/core/src/com/cloud/agent/api/storage/DownloadAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/DownloadAnswer.java rename to core/src/com/cloud/agent/api/storage/DownloadAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/DownloadCommand.java b/core/src/com/cloud/agent/api/storage/DownloadCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/DownloadCommand.java rename to core/src/com/cloud/agent/api/storage/DownloadCommand.java diff --git a/api/src/com/cloud/agent/api/storage/DownloadProgressCommand.java b/core/src/com/cloud/agent/api/storage/DownloadProgressCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/DownloadProgressCommand.java rename to core/src/com/cloud/agent/api/storage/DownloadProgressCommand.java diff --git a/api/src/com/cloud/agent/api/storage/ListTemplateAnswer.java b/core/src/com/cloud/agent/api/storage/ListTemplateAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/ListTemplateAnswer.java rename to core/src/com/cloud/agent/api/storage/ListTemplateAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/ListTemplateCommand.java b/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/ListTemplateCommand.java rename to core/src/com/cloud/agent/api/storage/ListTemplateCommand.java diff --git a/api/src/com/cloud/agent/api/storage/ListVolumeAnswer.java b/core/src/com/cloud/agent/api/storage/ListVolumeAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/ListVolumeAnswer.java rename to core/src/com/cloud/agent/api/storage/ListVolumeAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/ListVolumeCommand.java b/core/src/com/cloud/agent/api/storage/ListVolumeCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/ListVolumeCommand.java rename to core/src/com/cloud/agent/api/storage/ListVolumeCommand.java diff --git a/api/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityAnswer.java b/core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityAnswer.java rename to core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityCommand.java b/core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityCommand.java rename to core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityCommand.java diff --git a/api/src/com/cloud/agent/api/storage/MigrateVolumeAnswer.java b/core/src/com/cloud/agent/api/storage/MigrateVolumeAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/MigrateVolumeAnswer.java rename to core/src/com/cloud/agent/api/storage/MigrateVolumeAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java b/core/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java rename to core/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java diff --git a/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java b/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java rename to core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java b/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java rename to core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java diff --git a/api/src/com/cloud/agent/api/storage/ResizeVolumeAnswer.java b/core/src/com/cloud/agent/api/storage/ResizeVolumeAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/ResizeVolumeAnswer.java rename to core/src/com/cloud/agent/api/storage/ResizeVolumeAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/ResizeVolumeCommand.java b/core/src/com/cloud/agent/api/storage/ResizeVolumeCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/ResizeVolumeCommand.java rename to core/src/com/cloud/agent/api/storage/ResizeVolumeCommand.java diff --git a/api/src/com/cloud/agent/api/storage/StorageCommand.java b/core/src/com/cloud/agent/api/storage/StorageCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/StorageCommand.java rename to core/src/com/cloud/agent/api/storage/StorageCommand.java diff --git a/api/src/com/cloud/agent/api/storage/UpgradeDiskAnswer.java b/core/src/com/cloud/agent/api/storage/UpgradeDiskAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/UpgradeDiskAnswer.java rename to core/src/com/cloud/agent/api/storage/UpgradeDiskAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/UpgradeDiskCommand.java b/core/src/com/cloud/agent/api/storage/UpgradeDiskCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/UpgradeDiskCommand.java rename to core/src/com/cloud/agent/api/storage/UpgradeDiskCommand.java diff --git a/api/src/com/cloud/agent/api/storage/UploadAnswer.java b/core/src/com/cloud/agent/api/storage/UploadAnswer.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/UploadAnswer.java rename to core/src/com/cloud/agent/api/storage/UploadAnswer.java diff --git a/api/src/com/cloud/agent/api/storage/UploadCommand.java b/core/src/com/cloud/agent/api/storage/UploadCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/UploadCommand.java rename to core/src/com/cloud/agent/api/storage/UploadCommand.java diff --git a/api/src/com/cloud/agent/api/storage/UploadProgressCommand.java b/core/src/com/cloud/agent/api/storage/UploadProgressCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/UploadProgressCommand.java rename to core/src/com/cloud/agent/api/storage/UploadProgressCommand.java diff --git a/api/src/com/cloud/agent/api/storage/ssCommand.java b/core/src/com/cloud/agent/api/storage/ssCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/storage/ssCommand.java rename to core/src/com/cloud/agent/api/storage/ssCommand.java diff --git a/api/src/com/cloud/agent/api/uploadTemplateToSwiftFromSecondaryStorageCommand.java b/core/src/com/cloud/agent/api/uploadTemplateToSwiftFromSecondaryStorageCommand.java similarity index 100% rename from api/src/com/cloud/agent/api/uploadTemplateToSwiftFromSecondaryStorageCommand.java rename to core/src/com/cloud/agent/api/uploadTemplateToSwiftFromSecondaryStorageCommand.java diff --git a/core/src/com/cloud/resource/ResourceListener.java b/core/src/com/cloud/resource/ResourceListener.java index 0efea12aee5..17fba6cd52d 100755 --- a/core/src/com/cloud/resource/ResourceListener.java +++ b/core/src/com/cloud/resource/ResourceListener.java @@ -20,7 +20,7 @@ import java.net.URI; import java.util.List; import java.util.Map; -import com.cloud.host.HostVO; +import com.cloud.host.Host; public interface ResourceListener { static final Integer EVENT_DISCOVER_BEFORE = 0x1; @@ -33,9 +33,9 @@ public interface ResourceListener { static final Integer EVENT_PREPARE_MAINTENANCE_AFTER = 0x1 << 7; static final Integer EVENT_ALL = (EVENT_DISCOVER_BEFORE | EVENT_DISCOVER_AFTER | EVENT_DELETE_HOST_BEFORE | EVENT_DELETE_HOST_AFTER | EVENT_CANCEL_MAINTENANCE_BEFORE | EVENT_CANCEL_MAINTENANCE_AFTER | EVENT_PREPARE_MAINTENANCE_BEFORE | EVENT_PREPARE_MAINTENANCE_AFTER); - + /** - * + * * @param dcid * @param podId * @param clusterId @@ -43,63 +43,63 @@ public interface ResourceListener { * @param username * @param password * @param hostTags - * + * * Called before Discover.find() */ void processDiscoverEventBefore(Long dcid, Long podId, Long clusterId, URI uri, String username, String password, List hostTags); /** - * + * * @param resources - * + * * Called after Discover.find() */ void processDiscoverEventAfter(Map> resources); /** - * + * * @param host - * + * * Called before host delete */ - void processDeleteHostEventBefore(HostVO host); + void processDeleteHostEventBefore(Host host); /** - * + * * @param host - * + * * Called after host delete. NOTE param host includes stale data which has been removed from database */ - void processDeletHostEventAfter(HostVO host); + void processDeletHostEventAfter(Host host); /** - * + * * @param hostId - * + * * Called before AgentManager.cancelMaintenance */ void processCancelMaintenaceEventBefore(Long hostId); /** - * + * * @param hostId - * + * * Called after AgentManager.cancelMaintenance */ void processCancelMaintenaceEventAfter(Long hostId); /** - * + * * @param hostId - * + * * Called before AgentManager.main */ void processPrepareMaintenaceEventBefore(Long hostId); /** - * + * * @param hostId - * + * * Called after AgentManager.main */ void processPrepareMaintenaceEventAfter(Long hostId); diff --git a/api/src/com/cloud/storage/resource/StoragePoolResource.java b/core/src/com/cloud/storage/resource/StoragePoolResource.java similarity index 100% rename from api/src/com/cloud/storage/resource/StoragePoolResource.java rename to core/src/com/cloud/storage/resource/StoragePoolResource.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/AgentControlAnswerTest.java b/core/test/org/apache/cloudstack/api/agent/test/AgentControlAnswerTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/AgentControlAnswerTest.java rename to core/test/org/apache/cloudstack/api/agent/test/AgentControlAnswerTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/AgentControlCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/AgentControlCommandTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/AgentControlCommandTest.java rename to core/test/org/apache/cloudstack/api/agent/test/AgentControlCommandTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/AnswerTest.java b/core/test/org/apache/cloudstack/api/agent/test/AnswerTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/AnswerTest.java rename to core/test/org/apache/cloudstack/api/agent/test/AnswerTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/AttachIsoCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/AttachIsoCommandTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/AttachIsoCommandTest.java rename to core/test/org/apache/cloudstack/api/agent/test/AttachIsoCommandTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/AttachVolumeAnswerTest.java b/core/test/org/apache/cloudstack/api/agent/test/AttachVolumeAnswerTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/AttachVolumeAnswerTest.java rename to core/test/org/apache/cloudstack/api/agent/test/AttachVolumeAnswerTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/AttachVolumeCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/AttachVolumeCommandTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/AttachVolumeCommandTest.java rename to core/test/org/apache/cloudstack/api/agent/test/AttachVolumeCommandTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java b/core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java rename to core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java rename to core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/BumpUpPriorityCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/BumpUpPriorityCommandTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/BumpUpPriorityCommandTest.java rename to core/test/org/apache/cloudstack/api/agent/test/BumpUpPriorityCommandTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/CancelCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/CancelCommandTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/CancelCommandTest.java rename to core/test/org/apache/cloudstack/api/agent/test/CancelCommandTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/ChangeAgentAnswerTest.java b/core/test/org/apache/cloudstack/api/agent/test/ChangeAgentAnswerTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/ChangeAgentAnswerTest.java rename to core/test/org/apache/cloudstack/api/agent/test/ChangeAgentAnswerTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/ChangeAgentCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/ChangeAgentCommandTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/ChangeAgentCommandTest.java rename to core/test/org/apache/cloudstack/api/agent/test/ChangeAgentCommandTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/CheckHealthAnswerTest.java b/core/test/org/apache/cloudstack/api/agent/test/CheckHealthAnswerTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/CheckHealthAnswerTest.java rename to core/test/org/apache/cloudstack/api/agent/test/CheckHealthAnswerTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/CheckHealthCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/CheckHealthCommandTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/CheckHealthCommandTest.java rename to core/test/org/apache/cloudstack/api/agent/test/CheckHealthCommandTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java b/core/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java rename to core/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/CheckNetworkCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/CheckNetworkCommandTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/CheckNetworkCommandTest.java rename to core/test/org/apache/cloudstack/api/agent/test/CheckNetworkCommandTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/CheckOnHostCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/CheckOnHostCommandTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/CheckOnHostCommandTest.java rename to core/test/org/apache/cloudstack/api/agent/test/CheckOnHostCommandTest.java diff --git a/api/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java similarity index 100% rename from api/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java rename to core/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java diff --git a/api/test/src/com/cloud/agent/api/test/ResizeVolumeCommandTest.java b/core/test/src/com/cloud/agent/api/test/ResizeVolumeCommandTest.java similarity index 100% rename from api/test/src/com/cloud/agent/api/test/ResizeVolumeCommandTest.java rename to core/test/src/com/cloud/agent/api/test/ResizeVolumeCommandTest.java diff --git a/core/src/com/cloud/capacity/CapacityVO.java b/engine/schema/src/com/cloud/capacity/CapacityVO.java similarity index 100% rename from core/src/com/cloud/capacity/CapacityVO.java rename to engine/schema/src/com/cloud/capacity/CapacityVO.java diff --git a/core/src/com/cloud/certificate/CertificateVO.java b/engine/schema/src/com/cloud/certificate/CertificateVO.java similarity index 100% rename from core/src/com/cloud/certificate/CertificateVO.java rename to engine/schema/src/com/cloud/certificate/CertificateVO.java diff --git a/core/src/com/cloud/host/DetailVO.java b/engine/schema/src/com/cloud/host/DetailVO.java similarity index 100% rename from core/src/com/cloud/host/DetailVO.java rename to engine/schema/src/com/cloud/host/DetailVO.java diff --git a/core/src/com/cloud/host/HostTagVO.java b/engine/schema/src/com/cloud/host/HostTagVO.java similarity index 100% rename from core/src/com/cloud/host/HostTagVO.java rename to engine/schema/src/com/cloud/host/HostTagVO.java diff --git a/core/src/com/cloud/host/HostVO.java b/engine/schema/src/com/cloud/host/HostVO.java similarity index 100% rename from core/src/com/cloud/host/HostVO.java rename to engine/schema/src/com/cloud/host/HostVO.java diff --git a/core/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java b/engine/schema/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java similarity index 100% rename from core/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java rename to engine/schema/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java diff --git a/core/src/com/cloud/network/VpnUserVO.java b/engine/schema/src/com/cloud/network/VpnUserVO.java similarity index 100% rename from core/src/com/cloud/network/VpnUserVO.java rename to engine/schema/src/com/cloud/network/VpnUserVO.java diff --git a/core/src/com/cloud/network/security/SecurityGroupRuleVO.java b/engine/schema/src/com/cloud/network/security/SecurityGroupRuleVO.java similarity index 100% rename from core/src/com/cloud/network/security/SecurityGroupRuleVO.java rename to engine/schema/src/com/cloud/network/security/SecurityGroupRuleVO.java diff --git a/core/src/com/cloud/network/security/SecurityGroupRulesVO.java b/engine/schema/src/com/cloud/network/security/SecurityGroupRulesVO.java similarity index 100% rename from core/src/com/cloud/network/security/SecurityGroupRulesVO.java rename to engine/schema/src/com/cloud/network/security/SecurityGroupRulesVO.java diff --git a/core/src/com/cloud/network/security/SecurityGroupVMMapVO.java b/engine/schema/src/com/cloud/network/security/SecurityGroupVMMapVO.java similarity index 100% rename from core/src/com/cloud/network/security/SecurityGroupVMMapVO.java rename to engine/schema/src/com/cloud/network/security/SecurityGroupVMMapVO.java diff --git a/core/src/com/cloud/network/security/SecurityGroupVO.java b/engine/schema/src/com/cloud/network/security/SecurityGroupVO.java similarity index 100% rename from core/src/com/cloud/network/security/SecurityGroupVO.java rename to engine/schema/src/com/cloud/network/security/SecurityGroupVO.java diff --git a/core/src/com/cloud/network/security/SecurityGroupWork.java b/engine/schema/src/com/cloud/network/security/SecurityGroupWork.java similarity index 100% rename from core/src/com/cloud/network/security/SecurityGroupWork.java rename to engine/schema/src/com/cloud/network/security/SecurityGroupWork.java diff --git a/core/src/com/cloud/network/security/SecurityGroupWorkVO.java b/engine/schema/src/com/cloud/network/security/SecurityGroupWorkVO.java similarity index 100% rename from core/src/com/cloud/network/security/SecurityGroupWorkVO.java rename to engine/schema/src/com/cloud/network/security/SecurityGroupWorkVO.java diff --git a/core/src/com/cloud/network/security/VmRulesetLogVO.java b/engine/schema/src/com/cloud/network/security/VmRulesetLogVO.java similarity index 100% rename from core/src/com/cloud/network/security/VmRulesetLogVO.java rename to engine/schema/src/com/cloud/network/security/VmRulesetLogVO.java diff --git a/core/src/com/cloud/storage/DiskOfferingVO.java b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java similarity index 100% rename from core/src/com/cloud/storage/DiskOfferingVO.java rename to engine/schema/src/com/cloud/storage/DiskOfferingVO.java diff --git a/core/src/com/cloud/storage/GuestOSCategoryVO.java b/engine/schema/src/com/cloud/storage/GuestOSCategoryVO.java similarity index 100% rename from core/src/com/cloud/storage/GuestOSCategoryVO.java rename to engine/schema/src/com/cloud/storage/GuestOSCategoryVO.java diff --git a/core/src/com/cloud/storage/GuestOSVO.java b/engine/schema/src/com/cloud/storage/GuestOSVO.java similarity index 100% rename from core/src/com/cloud/storage/GuestOSVO.java rename to engine/schema/src/com/cloud/storage/GuestOSVO.java diff --git a/core/src/com/cloud/storage/LaunchPermissionVO.java b/engine/schema/src/com/cloud/storage/LaunchPermissionVO.java similarity index 100% rename from core/src/com/cloud/storage/LaunchPermissionVO.java rename to engine/schema/src/com/cloud/storage/LaunchPermissionVO.java diff --git a/core/src/com/cloud/storage/S3VO.java b/engine/schema/src/com/cloud/storage/S3VO.java similarity index 100% rename from core/src/com/cloud/storage/S3VO.java rename to engine/schema/src/com/cloud/storage/S3VO.java diff --git a/core/src/com/cloud/storage/SnapshotPolicyVO.java b/engine/schema/src/com/cloud/storage/SnapshotPolicyVO.java similarity index 100% rename from core/src/com/cloud/storage/SnapshotPolicyVO.java rename to engine/schema/src/com/cloud/storage/SnapshotPolicyVO.java diff --git a/core/src/com/cloud/storage/SnapshotScheduleVO.java b/engine/schema/src/com/cloud/storage/SnapshotScheduleVO.java similarity index 100% rename from core/src/com/cloud/storage/SnapshotScheduleVO.java rename to engine/schema/src/com/cloud/storage/SnapshotScheduleVO.java diff --git a/core/src/com/cloud/storage/SnapshotVO.java b/engine/schema/src/com/cloud/storage/SnapshotVO.java similarity index 100% rename from core/src/com/cloud/storage/SnapshotVO.java rename to engine/schema/src/com/cloud/storage/SnapshotVO.java diff --git a/core/src/com/cloud/storage/StoragePoolHostAssoc.java b/engine/schema/src/com/cloud/storage/StoragePoolHostAssoc.java similarity index 100% rename from core/src/com/cloud/storage/StoragePoolHostAssoc.java rename to engine/schema/src/com/cloud/storage/StoragePoolHostAssoc.java diff --git a/core/src/com/cloud/storage/StoragePoolHostVO.java b/engine/schema/src/com/cloud/storage/StoragePoolHostVO.java similarity index 94% rename from core/src/com/cloud/storage/StoragePoolHostVO.java rename to engine/schema/src/com/cloud/storage/StoragePoolHostVO.java index a8a2bac4886..1a4b9b87dce 100644 --- a/core/src/com/cloud/storage/StoragePoolHostVO.java +++ b/engine/schema/src/com/cloud/storage/StoragePoolHostVO.java @@ -28,7 +28,6 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import com.cloud.utils.db.GenericDaoBase; -import org.apache.cloudstack.api.InternalIdentity; /** * Join table for storage pools and hosts @@ -40,24 +39,24 @@ public class StoragePoolHostVO implements StoragePoolHostAssoc { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Long id; - + @Column(name="pool_id") private long poolId; - + @Column(name="host_id") private long hostId; - + @Column(name="local_path") private String localPath; - + @Column(name=GenericDaoBase.CREATED_COLUMN) - private Date created = null; - + private final Date created = null; + @Column(name="last_updated") @Temporal(value=TemporalType.TIMESTAMP) - private Date lastUpdated = null; - - + private final Date lastUpdated = null; + + public StoragePoolHostVO() { super(); } @@ -76,6 +75,7 @@ public class StoragePoolHostVO implements StoragePoolHostAssoc { } + @Override public long getId() { return id; } diff --git a/core/src/com/cloud/storage/StoragePoolWorkVO.java b/engine/schema/src/com/cloud/storage/StoragePoolWorkVO.java similarity index 100% rename from core/src/com/cloud/storage/StoragePoolWorkVO.java rename to engine/schema/src/com/cloud/storage/StoragePoolWorkVO.java diff --git a/core/src/com/cloud/storage/SwiftVO.java b/engine/schema/src/com/cloud/storage/SwiftVO.java similarity index 100% rename from core/src/com/cloud/storage/SwiftVO.java rename to engine/schema/src/com/cloud/storage/SwiftVO.java diff --git a/core/src/com/cloud/storage/UploadVO.java b/engine/schema/src/com/cloud/storage/UploadVO.java similarity index 100% rename from core/src/com/cloud/storage/UploadVO.java rename to engine/schema/src/com/cloud/storage/UploadVO.java diff --git a/core/src/com/cloud/storage/VMTemplateDetailVO.java b/engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java similarity index 100% rename from core/src/com/cloud/storage/VMTemplateDetailVO.java rename to engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java diff --git a/core/src/com/cloud/storage/VMTemplateHostVO.java b/engine/schema/src/com/cloud/storage/VMTemplateHostVO.java similarity index 100% rename from core/src/com/cloud/storage/VMTemplateHostVO.java rename to engine/schema/src/com/cloud/storage/VMTemplateHostVO.java diff --git a/core/src/com/cloud/storage/VMTemplateS3VO.java b/engine/schema/src/com/cloud/storage/VMTemplateS3VO.java similarity index 100% rename from core/src/com/cloud/storage/VMTemplateS3VO.java rename to engine/schema/src/com/cloud/storage/VMTemplateS3VO.java diff --git a/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java b/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java similarity index 100% rename from core/src/com/cloud/storage/VMTemplateStoragePoolVO.java rename to engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java diff --git a/core/src/com/cloud/storage/VMTemplateSwiftVO.java b/engine/schema/src/com/cloud/storage/VMTemplateSwiftVO.java similarity index 100% rename from core/src/com/cloud/storage/VMTemplateSwiftVO.java rename to engine/schema/src/com/cloud/storage/VMTemplateSwiftVO.java diff --git a/core/src/com/cloud/storage/VMTemplateVO.java b/engine/schema/src/com/cloud/storage/VMTemplateVO.java similarity index 100% rename from core/src/com/cloud/storage/VMTemplateVO.java rename to engine/schema/src/com/cloud/storage/VMTemplateVO.java diff --git a/core/src/com/cloud/storage/VMTemplateZoneVO.java b/engine/schema/src/com/cloud/storage/VMTemplateZoneVO.java similarity index 100% rename from core/src/com/cloud/storage/VMTemplateZoneVO.java rename to engine/schema/src/com/cloud/storage/VMTemplateZoneVO.java diff --git a/core/src/com/cloud/storage/VolumeHostVO.java b/engine/schema/src/com/cloud/storage/VolumeHostVO.java similarity index 100% rename from core/src/com/cloud/storage/VolumeHostVO.java rename to engine/schema/src/com/cloud/storage/VolumeHostVO.java diff --git a/core/src/com/cloud/storage/VolumeVO.java b/engine/schema/src/com/cloud/storage/VolumeVO.java similarity index 100% rename from core/src/com/cloud/storage/VolumeVO.java rename to engine/schema/src/com/cloud/storage/VolumeVO.java diff --git a/framework/jobs/pom.xml b/framework/jobs/pom.xml index 56490216f16..5ae63af77ad 100644 --- a/framework/jobs/pom.xml +++ b/framework/jobs/pom.xml @@ -18,12 +18,31 @@ --> 4.0.0 - org.apache.cloudstack cloud-framework-jobs - 4.0.0-SNAPSHOT - - org.quartz-scheduler - quartz - 2.1.6 - + + org.apache.cloudstack + cloudstack-framework + 4.2.0-SNAPSHOT + ../pom.xml + + + + org.quartz-scheduler + quartz + 2.1.6 + + + org.apache.cloudstack + cloud-utils + ${project.version} + + + org.apache.cloudstack + cloud-api + ${project.version} + + + + install + diff --git a/framework/pom.xml b/framework/pom.xml index 4dfb409f04e..ddcdcb0439a 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -33,5 +33,6 @@ ipc rest events + jobs diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java index a0c991b5ad6..7153282a2aa 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java @@ -30,12 +30,10 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; @@ -46,17 +44,12 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; -import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.agent.api.StoragePoolInfo; import com.cloud.alert.AlertManager; -import com.cloud.capacity.Capacity; -import com.cloud.capacity.CapacityVO; -import com.cloud.capacity.dao.CapacityDao; import com.cloud.exception.DiscoveryException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.host.Host; import com.cloud.host.HostVO; -import com.cloud.host.Status; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.resource.ResourceManager; import com.cloud.server.ManagementServer; @@ -67,29 +60,14 @@ import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolAutomation; import com.cloud.storage.StoragePoolDiscoverer; import com.cloud.storage.StoragePoolHostVO; -import com.cloud.storage.StoragePoolStatus; -import com.cloud.storage.StoragePoolWorkVO; -import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.StoragePoolWorkDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.user.Account; -import com.cloud.user.User; -import com.cloud.user.UserContext; import com.cloud.user.dao.UserDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.UriUtils; import com.cloud.utils.db.DB; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.exception.ExecutionException; -import com.cloud.vm.ConsoleProxyVO; -import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.SecondaryStorageVmVO; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.dao.ConsoleProxyDao; import com.cloud.vm.dao.DomainRouterDao; @@ -157,7 +135,7 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements throw new InvalidParameterValueException( "Cluster id requires pod id"); } - + PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters(); URI uri = null; @@ -195,7 +173,7 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements String tags = (String) dsInfos.get("tags"); Map details = (Map) dsInfos .get("details"); - + parameters.setTags(tags); parameters.setDetails(details); @@ -208,7 +186,7 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements } String userInfo = uri.getUserInfo(); int port = uri.getPort(); - StoragePoolVO pool = null; + StoragePool pool = null; if (s_logger.isDebugEnabled()) { s_logger.debug("createPool Params @ scheme - " + scheme + " storageHost - " + storageHost + " hostPath - " @@ -272,7 +250,7 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements parameters.setPath(hostPath); } else { for (StoragePoolDiscoverer discoverer : _discoverers) { - Map> pools; + Map> pools; try { pools = discoverer.find(zoneId, podId, uri, details); } catch (DiscoveryException e) { @@ -281,7 +259,7 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements e); } if (pools != null) { - Map.Entry> entry = pools + Map.Entry> entry = pools .entrySet().iterator().next(); pool = entry.getKey(); details = entry.getValue(); @@ -310,7 +288,7 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements parameters.setPath(hostPath); } else { StoragePoolType type = Enum.valueOf(StoragePoolType.class, scheme); - + if (type != null) { parameters.setType(type); parameters.setHost(storageHost); @@ -332,7 +310,7 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements + " already in use by another pod (id=" + oldPodId + ")"); } } - + Object existingUuid = dsInfos.get("uuid"); String uuid = null; @@ -368,7 +346,7 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements parameters.setName(poolName); parameters.setClusterId(clusterId); parameters.setProviderName(providerName); - + return dataStoreHelper.createPrimaryDataStore(parameters); } @@ -457,7 +435,7 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements primaryDataStoreDao.expunge(primarystore.getId()); return false; } - + this.dataStoreHelper.attachCluster(store); return true; } @@ -527,11 +505,11 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements } } } - + if (!deleteFlag) { throw new CloudRuntimeException("Failed to delete storage pool on host"); } - + return this.dataStoreHelper.deletePrimaryDataStore(store); } diff --git a/server/pom.xml b/server/pom.xml index 2d960bef303..808dd3eee0a 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -34,6 +34,11 @@ httpcore ${cs.httpcore.version} + + org.apache.cloudstack + cloud-framework-jobs + ${project.version} + org.apache.httpcomponents httpclient diff --git a/core/src/com/cloud/alert/AlertManager.java b/server/src/com/cloud/alert/AlertManager.java similarity index 100% rename from core/src/com/cloud/alert/AlertManager.java rename to server/src/com/cloud/alert/AlertManager.java diff --git a/core/src/com/cloud/async/AsyncJobVO.java b/server/src/com/cloud/async/AsyncJobVO.java similarity index 100% rename from core/src/com/cloud/async/AsyncJobVO.java rename to server/src/com/cloud/async/AsyncJobVO.java diff --git a/core/src/com/cloud/async/SyncQueueItemVO.java b/server/src/com/cloud/async/SyncQueueItemVO.java similarity index 100% rename from core/src/com/cloud/async/SyncQueueItemVO.java rename to server/src/com/cloud/async/SyncQueueItemVO.java diff --git a/core/src/com/cloud/async/SyncQueueVO.java b/server/src/com/cloud/async/SyncQueueVO.java similarity index 100% rename from core/src/com/cloud/async/SyncQueueVO.java rename to server/src/com/cloud/async/SyncQueueVO.java diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java b/server/src/com/cloud/capacity/CapacityManagerImpl.java index 089307fc44c..1eb2fa5894a 100755 --- a/server/src/com/cloud/capacity/CapacityManagerImpl.java +++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java @@ -28,12 +28,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import com.cloud.dc.ClusterDetailsDao; -import com.cloud.dc.DataCenter; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InsufficientServerCapacityException; -import com.cloud.resource.ResourceState; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -50,7 +44,10 @@ import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.ClusterDetailsDao; +import com.cloud.dc.dao.ClusterDao; import com.cloud.exception.ConnectionException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; @@ -104,9 +101,9 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, HostDao _hostDao; @Inject VMInstanceDao _vmDao; - @Inject + @Inject VolumeDao _volumeDao; - @Inject + @Inject VMTemplatePoolDao _templatePoolDao; @Inject AgentManager _agentManager; @@ -115,16 +112,16 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, @Inject StorageManager _storageMgr; @Inject - SwiftManager _swiftMgr; + SwiftManager _swiftMgr; @Inject - ConfigurationManager _configMgr; + ConfigurationManager _configMgr; @Inject HypervisorCapabilitiesDao _hypervisorCapabilitiesDao; @Inject protected VMSnapshotDao _vmSnapshotDao; @Inject protected UserVmDao _userVMDao; - + @Inject ClusterDetailsDao _clusterDetailsDao; @Inject @@ -191,8 +188,8 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, long actualTotalCpu = capacityCpu.getTotalCapacity(); float cpuOvercommitRatio =Float.parseFloat(_clusterDetailsDao.findDetail(clusterId,"cpuOvercommitRatio").getValue()); float memoryOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterId,"memoryOvercommitRatio").getValue()); - int vmCPU = (int) (svo.getCpu() * svo.getSpeed()); - long vmMem = (long) (svo.getRamSize() * 1024L * 1024L); + int vmCPU = svo.getCpu() * svo.getSpeed(); + long vmMem = svo.getRamSize() * 1024L * 1024L; long actualTotalMem = capacityMemory.getTotalCapacity(); long totalMem = (long) (actualTotalMem * memoryOvercommitRatio); long totalCpu = (long) (actualTotalCpu * cpuOvercommitRatio); @@ -266,8 +263,8 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, return; } - int cpu = (int) (svo.getCpu() * svo.getSpeed()); - long ram = (long) (svo.getRamSize() * 1024L * 1024L); + int cpu = svo.getCpu() * svo.getSpeed(); + long ram = svo.getRamSize() * 1024L * 1024L; Transaction txn = Transaction.currentTxn(); @@ -398,10 +395,10 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, failureReason = "Host does not have enough reserved CPU available"; } } else { - + long reservedCpuValueToUse = reservedCpu; long reservedMemValueToUse = reservedMem; - + if(!considerReservedCapacity){ if (s_logger.isDebugEnabled()) { s_logger.debug("considerReservedCapacity is" + considerReservedCapacity + " , not considering reserved capacity for calculating free capacity"); @@ -458,7 +455,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, return hasCapacity; } - + private long getVMSnapshotAllocatedCapacity(StoragePoolVO pool){ List volumes = _volumeDao.findByPoolId(pool.getId()); long totalSize = 0; @@ -486,39 +483,39 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, } return totalSize; } - + @Override public long getAllocatedPoolCapacity(StoragePoolVO pool, VMTemplateVO templateForVmCreation){ - + // Get size for all the volumes Pair sizes = _volumeDao.getCountAndTotalByPool(pool.getId()); long totalAllocatedSize = sizes.second() + sizes.first() * _extraBytesPerVolume; - - // Get size for VM Snapshots + + // Get size for VM Snapshots totalAllocatedSize = totalAllocatedSize + getVMSnapshotAllocatedCapacity(pool); // Iterate through all templates on this storage pool boolean tmpinstalled = false; List templatePoolVOs; templatePoolVOs = _templatePoolDao.listByPoolId(pool.getId()); - - for (VMTemplateStoragePoolVO templatePoolVO : templatePoolVOs) { + + for (VMTemplateStoragePoolVO templatePoolVO : templatePoolVOs) { if ((templateForVmCreation != null) && !tmpinstalled && (templatePoolVO.getTemplateId() == templateForVmCreation.getId())) { tmpinstalled = true; } long templateSize = templatePoolVO.getTemplateSize(); totalAllocatedSize += templateSize + _extraBytesPerVolume; } - + // Add the size for the templateForVmCreation if its not already present /*if ((templateForVmCreation != null) && !tmpinstalled) { - + }*/ - + return totalAllocatedSize; } - - + + @DB @Override public void updateCapacityForHost(HostVO host){ @@ -528,7 +525,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, for (ServiceOfferingVO offering : offerings) { offeringsMap.put(offering.getId(), offering); } - + long usedCpu = 0; long usedMemory = 0; long reservedMemory = 0; @@ -574,7 +571,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, + usedCpu); cpuCap.setUsedCapacity(usedCpu); } - + if (memCap.getUsedCapacity() == usedMemory && memCap.getReservedCapacity() == reservedMemory) { s_logger.debug("No need to calibrate memory capacity, host:" + host.getId() + " usedMem: " + memCap.getUsedCapacity() + " reservedMem: " + memCap.getReservedCapacity()); @@ -591,7 +588,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, + " new usedMem: " + usedMemory); memCap.setUsedCapacity(usedMemory); } - + try { _capacityDao.update(cpuCap.getId(), cpuCap); _capacityDao.update(memCap.getId(), memCap); @@ -610,24 +607,24 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, capacity.setReservedCapacity(reservedMemory); capacity.setCapacityState(capacityState); _capacityDao.persist(capacity); - + capacity = new CapacityVO( host.getId(), host.getDataCenterId(), - host.getPodId(), + host.getPodId(), host.getClusterId(), usedCpu, - (long)(host.getCpus().longValue() * host.getSpeed().longValue()), + host.getCpus().longValue() * host.getSpeed().longValue(), CapacityVO.CAPACITY_TYPE_CPU); capacity.setReservedCapacity(reservedCpu); capacity.setCapacityState(capacityState); _capacityDao.persist(capacity); txn.commit(); - + } - + } - + @Override public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vm, boolean transitionStatus, Object opaque) { return true; @@ -681,7 +678,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, releaseVmCapacity(vm, false, false, oldHostId); } } - + if ((newState == State.Starting || newState == State.Migrating || event == Event.AgentReportMigrated) && vm.getHostId() != null) { boolean fromLastHost = false; if (vm.getLastHostId() == vm.getHostId()) { @@ -729,7 +726,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, _capacityDao.update(CapacityVOCpu.getId(), CapacityVOCpu); } else { CapacityVO capacity = new CapacityVO(server.getId(), server.getDataCenterId(), server.getPodId(), server.getClusterId(), 0L, - (long) (server.getCpus().longValue() * server.getSpeed().longValue()), + server.getCpus().longValue() * server.getSpeed().longValue(), CapacityVO.CAPACITY_TYPE_CPU); _capacityDao.persist(capacity); } @@ -815,32 +812,32 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, @Override public void processCancelMaintenaceEventAfter(Long hostId) { - updateCapacityForHost(_hostDao.findById(hostId)); + updateCapacityForHost(_hostDao.findById(hostId)); } @Override public void processCancelMaintenaceEventBefore(Long hostId) { // TODO Auto-generated method stub - + } @Override - public void processDeletHostEventAfter(HostVO host) { + public void processDeletHostEventAfter(Host host) { // TODO Auto-generated method stub - + } @Override - public void processDeleteHostEventBefore(HostVO host) { + public void processDeleteHostEventBefore(Host host) { // TODO Auto-generated method stub - + } @Override public void processDiscoverEventAfter( Map> resources) { // TODO Auto-generated method stub - + } @Override @@ -848,11 +845,11 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, Long clusterId, URI uri, String username, String password, List hostTags) { // TODO Auto-generated method stub - + } @Override - public void processPrepareMaintenaceEventAfter(Long hostId) { + public void processPrepareMaintenaceEventAfter(Long hostId) { _capacityDao.removeBy(Capacity.CAPACITY_TYPE_MEMORY, null, null, null, hostId); _capacityDao.removeBy(Capacity.CAPACITY_TYPE_CPU, null, null, null, hostId); } @@ -860,7 +857,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, @Override public void processPrepareMaintenaceEventBefore(Long hostId) { // TODO Auto-generated method stub - + } @Override @@ -871,7 +868,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, Long maxGuestLimit = _hypervisorCapabilitiesDao.getMaxGuestsLimit(hypervisorType, hypervisorVersion); if(vmCount.longValue() >= maxGuestLimit.longValue()){ if (s_logger.isDebugEnabled()) { - s_logger.debug("Host name: " + host.getName() + ", hostId: "+ host.getId() + + s_logger.debug("Host name: " + host.getName() + ", hostId: "+ host.getId() + " already reached max Running VMs(count includes system VMs), limit is: " + maxGuestLimit + ",Running VM counts is: "+vmCount.longValue()); } return true; diff --git a/server/src/com/cloud/storage/OCFS2ManagerImpl.java b/server/src/com/cloud/storage/OCFS2ManagerImpl.java index 476bf04cae9..5eb9a4a5c44 100755 --- a/server/src/com/cloud/storage/OCFS2ManagerImpl.java +++ b/server/src/com/cloud/storage/OCFS2ManagerImpl.java @@ -56,7 +56,7 @@ import com.cloud.utils.exception.CloudRuntimeException; @Local(value ={OCFS2Manager.class}) public class OCFS2ManagerImpl extends ManagerBase implements OCFS2Manager, ResourceListener { private static final Logger s_logger = Logger.getLogger(OCFS2ManagerImpl.class); - + @Inject ClusterDetailsDao _clusterDetailsDao; @Inject AgentManager _agentMgr; @Inject HostDao _hostDao; @@ -64,7 +64,7 @@ public class OCFS2ManagerImpl extends ManagerBase implements OCFS2Manager, Resou @Inject ResourceManager _resourceMgr; @Inject StoragePoolHostDao _poolHostDao; @Inject PrimaryDataStoreDao _poolDao; - + @Override public boolean configure(String name, Map params) throws ConfigurationException { return true; @@ -96,8 +96,8 @@ public class OCFS2ManagerImpl extends ManagerBase implements OCFS2Manager, Resou } return lst; } - - + + private boolean prepareNodes(String clusterName, List hosts) { PrepareOCFS2NodesCommand cmd = new PrepareOCFS2NodesCommand(clusterName, marshalNodes(hosts)); for (HostVO h : hosts) { @@ -111,36 +111,36 @@ public class OCFS2ManagerImpl extends ManagerBase implements OCFS2Manager, Resou return false; } } - + return true; } - + private String getClusterName(Long clusterId) { ClusterVO cluster = _clusterDao.findById(clusterId); if (cluster == null) { throw new CloudRuntimeException("Cannot get cluster for id " + clusterId); } - - String clusterName = "OvmCluster" + cluster.getId(); + + String clusterName = "OvmCluster" + cluster.getId(); return clusterName; } - + @Override public boolean prepareNodes(List hosts, StoragePool pool) { if (pool.getPoolType() != StoragePoolType.OCFS2) { throw new CloudRuntimeException("None OCFS2 storage pool is getting into OCFS2 manager!"); } - + return prepareNodes(getClusterName(pool.getClusterId()), hosts); } @Override - public boolean prepareNodes(Long clusterId) { + public boolean prepareNodes(Long clusterId) { ClusterVO cluster = _clusterDao.findById(clusterId); if (cluster == null) { throw new CloudRuntimeException("Cannot find cluster for ID " + clusterId); } - + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getClusterId(), Op.EQ, clusterId); sc.addAnd(sc.getEntity().getPodId(), Op.EQ, cluster.getPodId()); @@ -151,36 +151,36 @@ public class OCFS2ManagerImpl extends ManagerBase implements OCFS2Manager, Resou s_logger.debug("There is no host in cluster " + clusterId + ", no need to prepare OCFS2 nodes"); return true; } - + return prepareNodes(getClusterName(clusterId), hosts); } @Override public void processDiscoverEventBefore(Long dcid, Long podId, Long clusterId, URI uri, String username, String password, List hostTags) { // TODO Auto-generated method stub - + } @Override public void processDiscoverEventAfter(Map> resources) { // TODO Auto-generated method stub - + } @Override - public void processDeleteHostEventBefore(HostVO host) { + public void processDeleteHostEventBefore(Host host) { // TODO Auto-generated method stub - + } @Override - public void processDeletHostEventAfter(HostVO host) { + public void processDeletHostEventAfter(Host host) { String errMsg = String.format("Prepare OCFS2 nodes failed after delete host %1$s (zone:%2$s, pod:%3$s, cluster:%4$s", host.getId(), host.getDataCenterId(), host.getPodId(), host.getClusterId()); - + if (host.getHypervisorType() != HypervisorType.Ovm) { return; } - + boolean hasOcfs2 = false; List poolRefs = _poolHostDao.listByHostId(host.getId()); for (StoragePoolHostVO poolRef : poolRefs) { @@ -205,24 +205,24 @@ public class OCFS2ManagerImpl extends ManagerBase implements OCFS2Manager, Resou @Override public void processCancelMaintenaceEventBefore(Long hostId) { // TODO Auto-generated method stub - + } @Override public void processCancelMaintenaceEventAfter(Long hostId) { // TODO Auto-generated method stub - + } @Override public void processPrepareMaintenaceEventBefore(Long hostId) { // TODO Auto-generated method stub - + } @Override public void processPrepareMaintenaceEventAfter(Long hostId) { // TODO Auto-generated method stub - + } } From f6913b5088d62ddfbd5f56c797d8568ce68e3097 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Wed, 1 May 2013 15:15:57 -0700 Subject: [PATCH 06/71] Removed files that are no longer used and further separated out the files in the core project --- .../src/com/cloud/alert/AlertAdapter.java | 0 ... => DownloadSnapshotFromSwiftCommand.java} | 6 +-- ...teFromSwiftToSecondaryStorageCommand.java} | 6 +-- ...teToSwiftFromSecondaryStorageCommand.java} | 6 +-- .../com/cloud/storage/SecondaryStorage.java | 30 -------------- .../cloud/storage/SecondaryStorageLayer.java | 39 ------------------- .../storage/snapshot/SnapshotManagerImpl.java | 4 +- .../cloud/template/TemplateManagerImpl.java | 8 ++-- .../resource/NfsSecondaryStorageResource.java | 24 ++++++------ 9 files changed, 27 insertions(+), 96 deletions(-) rename {core => api}/src/com/cloud/alert/AlertAdapter.java (100%) rename core/src/com/cloud/agent/api/{downloadSnapshotFromSwiftCommand.java => DownloadSnapshotFromSwiftCommand.java} (90%) rename core/src/com/cloud/agent/api/{downloadTemplateFromSwiftToSecondaryStorageCommand.java => DownloadTemplateFromSwiftToSecondaryStorageCommand.java} (91%) rename core/src/com/cloud/agent/api/{uploadTemplateToSwiftFromSecondaryStorageCommand.java => UploadTemplateToSwiftFromSecondaryStorageCommand.java} (91%) delete mode 100644 core/src/com/cloud/storage/SecondaryStorage.java delete mode 100644 core/src/com/cloud/storage/SecondaryStorageLayer.java diff --git a/core/src/com/cloud/alert/AlertAdapter.java b/api/src/com/cloud/alert/AlertAdapter.java similarity index 100% rename from core/src/com/cloud/alert/AlertAdapter.java rename to api/src/com/cloud/alert/AlertAdapter.java diff --git a/core/src/com/cloud/agent/api/downloadSnapshotFromSwiftCommand.java b/core/src/com/cloud/agent/api/DownloadSnapshotFromSwiftCommand.java similarity index 90% rename from core/src/com/cloud/agent/api/downloadSnapshotFromSwiftCommand.java rename to core/src/com/cloud/agent/api/DownloadSnapshotFromSwiftCommand.java index a2ae611d316..0711b2ef2d8 100644 --- a/core/src/com/cloud/agent/api/downloadSnapshotFromSwiftCommand.java +++ b/core/src/com/cloud/agent/api/DownloadSnapshotFromSwiftCommand.java @@ -22,17 +22,17 @@ import com.cloud.agent.api.to.SwiftTO; /** * This currently assumes that both primary and secondary storage are mounted on the XenServer. */ -public class downloadSnapshotFromSwiftCommand extends SnapshotCommand { +public class DownloadSnapshotFromSwiftCommand extends SnapshotCommand { @LogLevel(Log4jLevel.Off) private SwiftTO _swift; private String _parent; - protected downloadSnapshotFromSwiftCommand() { + protected DownloadSnapshotFromSwiftCommand() { } - public downloadSnapshotFromSwiftCommand(SwiftTO swift, String secondaryStorageUrl, Long dcId, Long accountId, Long volumeId, String parent, String BackupUuid, int wait) { + public DownloadSnapshotFromSwiftCommand(SwiftTO swift, String secondaryStorageUrl, Long dcId, Long accountId, Long volumeId, String parent, String BackupUuid, int wait) { super(null, secondaryStorageUrl, BackupUuid, "", dcId, accountId, volumeId); setParent(parent); diff --git a/core/src/com/cloud/agent/api/downloadTemplateFromSwiftToSecondaryStorageCommand.java b/core/src/com/cloud/agent/api/DownloadTemplateFromSwiftToSecondaryStorageCommand.java similarity index 91% rename from core/src/com/cloud/agent/api/downloadTemplateFromSwiftToSecondaryStorageCommand.java rename to core/src/com/cloud/agent/api/DownloadTemplateFromSwiftToSecondaryStorageCommand.java index 82290656095..79ec882c8d7 100644 --- a/core/src/com/cloud/agent/api/downloadTemplateFromSwiftToSecondaryStorageCommand.java +++ b/core/src/com/cloud/agent/api/DownloadTemplateFromSwiftToSecondaryStorageCommand.java @@ -24,7 +24,7 @@ import com.cloud.agent.api.to.SwiftTO; * */ -public class downloadTemplateFromSwiftToSecondaryStorageCommand extends Command { +public class DownloadTemplateFromSwiftToSecondaryStorageCommand extends Command { @LogLevel(Log4jLevel.Off) private SwiftTO swift; private String secondaryStorageUrl; @@ -34,11 +34,11 @@ public class downloadTemplateFromSwiftToSecondaryStorageCommand extends Command private Long templateId; private String path; - protected downloadTemplateFromSwiftToSecondaryStorageCommand() { + protected DownloadTemplateFromSwiftToSecondaryStorageCommand() { } - public downloadTemplateFromSwiftToSecondaryStorageCommand(SwiftTO swift, String secondaryStorageUrl, Long dcId, Long accountId, Long templateId, String path, int wait) { + public DownloadTemplateFromSwiftToSecondaryStorageCommand(SwiftTO swift, String secondaryStorageUrl, Long dcId, Long accountId, Long templateId, String path, int wait) { this.swift = swift; this.secondaryStorageUrl = secondaryStorageUrl; diff --git a/core/src/com/cloud/agent/api/uploadTemplateToSwiftFromSecondaryStorageCommand.java b/core/src/com/cloud/agent/api/UploadTemplateToSwiftFromSecondaryStorageCommand.java similarity index 91% rename from core/src/com/cloud/agent/api/uploadTemplateToSwiftFromSecondaryStorageCommand.java rename to core/src/com/cloud/agent/api/UploadTemplateToSwiftFromSecondaryStorageCommand.java index 10001b149fa..7ba377da8c3 100644 --- a/core/src/com/cloud/agent/api/uploadTemplateToSwiftFromSecondaryStorageCommand.java +++ b/core/src/com/cloud/agent/api/UploadTemplateToSwiftFromSecondaryStorageCommand.java @@ -24,7 +24,7 @@ import com.cloud.agent.api.to.SwiftTO; * */ -public class uploadTemplateToSwiftFromSecondaryStorageCommand extends Command { +public class UploadTemplateToSwiftFromSecondaryStorageCommand extends Command { @LogLevel(Log4jLevel.Off) private SwiftTO swift; private String secondaryStorageUrl; @@ -33,11 +33,11 @@ public class uploadTemplateToSwiftFromSecondaryStorageCommand extends Command { private Long accountId; private Long templateId; - protected uploadTemplateToSwiftFromSecondaryStorageCommand() { + protected UploadTemplateToSwiftFromSecondaryStorageCommand() { } - public uploadTemplateToSwiftFromSecondaryStorageCommand(SwiftTO swift, String secondaryStorageUrl, Long dcId, Long accountId, Long templateId, int wait) { + public UploadTemplateToSwiftFromSecondaryStorageCommand(SwiftTO swift, String secondaryStorageUrl, Long dcId, Long accountId, Long templateId, int wait) { this.swift = swift; this.secondaryStorageUrl = secondaryStorageUrl; diff --git a/core/src/com/cloud/storage/SecondaryStorage.java b/core/src/com/cloud/storage/SecondaryStorage.java deleted file mode 100644 index dc01642767f..00000000000 --- a/core/src/com/cloud/storage/SecondaryStorage.java +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.storage; - -public interface SecondaryStorage { - - String getBackupPath(); - - String getTemplatePath(); - - String getIsoPath(); - - void createTemplate(); - - void destroyTemplate(); -} diff --git a/core/src/com/cloud/storage/SecondaryStorageLayer.java b/core/src/com/cloud/storage/SecondaryStorageLayer.java deleted file mode 100644 index 539733d3531..00000000000 --- a/core/src/com/cloud/storage/SecondaryStorageLayer.java +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.storage; - -import java.net.URI; - -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.utils.component.Adapter; - -public interface SecondaryStorageLayer extends Adapter { - - /** - * Mounts a template - * - * @param poolId the pool to mount it to. - * @param poolUuid the pool's uuid if it is needed. - * @param name unique name to the template. - * @param url url to access the template. - * @param format format of the template. - * @param accountId account id the template belongs to. - * @return a String that unique identifies the reference the template once it is mounted. - */ - String mountTemplate(long poolId, String poolUuid, String name, URI url, ImageFormat format, long accountId); - -} diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 7dafe4ac865..26aae48ba38 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -48,7 +48,7 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.DeleteSnapshotsDirCommand; import com.cloud.agent.api.DownloadSnapshotFromS3Command; -import com.cloud.agent.api.downloadSnapshotFromSwiftCommand; +import com.cloud.agent.api.DownloadSnapshotFromSwiftCommand; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.alert.AlertManager; @@ -384,7 +384,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, String parent = null; try { for (String backupUuid : BackupUuids) { - downloadSnapshotFromSwiftCommand cmd = new downloadSnapshotFromSwiftCommand(swift, secondaryStoragePoolUrl, dcId, accountId, volumeId, parent, backupUuid, _backupsnapshotwait); + DownloadSnapshotFromSwiftCommand cmd = new DownloadSnapshotFromSwiftCommand(swift, secondaryStoragePoolUrl, dcId, accountId, volumeId, parent, backupUuid, _backupsnapshotwait); Answer answer = _agentMgr.sendToSSVM(dcId, cmd); if ((answer == null) || !answer.getResult()) { throw new CloudRuntimeException("downloadSnapshotsFromSwift failed "); diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 8b5ee3aac1b..a8729e1490a 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -75,8 +75,8 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.ComputeChecksumCommand; -import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand; -import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand; +import com.cloud.agent.api.DownloadTemplateFromSwiftToSecondaryStorageCommand; +import com.cloud.agent.api.UploadTemplateToSwiftFromSecondaryStorageCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; @@ -579,7 +579,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return errMsg; } - downloadTemplateFromSwiftToSecondaryStorageCommand cmd = new downloadTemplateFromSwiftToSecondaryStorageCommand(swift, secHost.getName(), dcId, template.getAccountId(), templateId, + DownloadTemplateFromSwiftToSecondaryStorageCommand cmd = new DownloadTemplateFromSwiftToSecondaryStorageCommand(swift, secHost.getName(), dcId, template.getAccountId(), templateId, tmpltSwift.getPath(), _primaryStorageDownloadWait); try { Answer answer = _agentMgr.sendToSSVM(dcId, cmd); @@ -628,7 +628,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return errMsg; } - uploadTemplateToSwiftFromSecondaryStorageCommand cmd = new uploadTemplateToSwiftFromSecondaryStorageCommand(swift, secHost.getName(), secHost.getDataCenterId(), template.getAccountId(), + UploadTemplateToSwiftFromSecondaryStorageCommand cmd = new UploadTemplateToSwiftFromSecondaryStorageCommand(swift, secHost.getName(), secHost.getDataCenterId(), template.getAccountId(), templateId, _primaryStorageDownloadWait); Answer answer = null; try { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 638d5cad99d..e7fa5b2f1bc 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -80,9 +80,9 @@ import com.cloud.agent.api.SecStorageVMSetupCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupSecondaryStorageCommand; import com.cloud.agent.api.UploadTemplateToS3FromSecondaryStorageCommand; -import com.cloud.agent.api.downloadSnapshotFromSwiftCommand; -import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand; -import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand; +import com.cloud.agent.api.DownloadSnapshotFromSwiftCommand; +import com.cloud.agent.api.DownloadTemplateFromSwiftToSecondaryStorageCommand; +import com.cloud.agent.api.UploadTemplateToSwiftFromSecondaryStorageCommand; import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand; import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; @@ -190,20 +190,20 @@ SecondaryStorageResource { return execute((ListTemplateCommand)cmd); } else if (cmd instanceof ListVolumeCommand){ return execute((ListVolumeCommand)cmd); - }else if (cmd instanceof downloadSnapshotFromSwiftCommand){ - return execute((downloadSnapshotFromSwiftCommand)cmd); + }else if (cmd instanceof DownloadSnapshotFromSwiftCommand){ + return execute((DownloadSnapshotFromSwiftCommand)cmd); } else if (cmd instanceof DownloadSnapshotFromS3Command) { return execute((DownloadSnapshotFromS3Command) cmd); } else if (cmd instanceof DeleteSnapshotBackupCommand){ return execute((DeleteSnapshotBackupCommand)cmd); } else if (cmd instanceof DeleteSnapshotsDirCommand){ return execute((DeleteSnapshotsDirCommand)cmd); - } else if (cmd instanceof downloadTemplateFromSwiftToSecondaryStorageCommand) { - return execute((downloadTemplateFromSwiftToSecondaryStorageCommand) cmd); + } else if (cmd instanceof DownloadTemplateFromSwiftToSecondaryStorageCommand) { + return execute((DownloadTemplateFromSwiftToSecondaryStorageCommand) cmd); } else if (cmd instanceof DownloadTemplateFromS3ToSecondaryStorageCommand) { return execute((DownloadTemplateFromS3ToSecondaryStorageCommand) cmd); - } else if (cmd instanceof uploadTemplateToSwiftFromSecondaryStorageCommand) { - return execute((uploadTemplateToSwiftFromSecondaryStorageCommand) cmd); + } else if (cmd instanceof UploadTemplateToSwiftFromSecondaryStorageCommand) { + return execute((UploadTemplateToSwiftFromSecondaryStorageCommand) cmd); } else if (cmd instanceof UploadTemplateToS3FromSecondaryStorageCommand) { return execute((UploadTemplateToS3FromSecondaryStorageCommand) cmd); } else if (cmd instanceof DeleteObjectFromSwiftCommand) { @@ -281,7 +281,7 @@ SecondaryStorageResource { } - private Answer execute(downloadTemplateFromSwiftToSecondaryStorageCommand cmd) { + private Answer execute(DownloadTemplateFromSwiftToSecondaryStorageCommand cmd) { SwiftTO swift = cmd.getSwift(); String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); Long accountId = cmd.getAccountId(); @@ -324,7 +324,7 @@ SecondaryStorageResource { } } - private Answer execute(uploadTemplateToSwiftFromSecondaryStorageCommand cmd) { + private Answer execute(UploadTemplateToSwiftFromSecondaryStorageCommand cmd) { SwiftTO swift = cmd.getSwift(); String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); Long accountId = cmd.getAccountId(); @@ -769,7 +769,7 @@ SecondaryStorageResource { SNAPSHOT_ROOT_DIR, accountId, volumeId); } - public Answer execute(downloadSnapshotFromSwiftCommand cmd){ + public Answer execute(DownloadSnapshotFromSwiftCommand cmd){ SwiftTO swift = cmd.getSwift(); String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); Long accountId = cmd.getAccountId(); From 572e71e57d7f5f3cef9c20e55b79773cca013e00 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Thu, 2 May 2013 06:50:38 -0700 Subject: [PATCH 07/71] Moved most of the VOs and DAOs from server package into engine-schema as well --- .../com/cloud/info/ConsoleProxyLoadInfo.java | 0 .../com/cloud/info/RunningHostCountInfo.java | 0 .../com/cloud/network/UserIpv6Address.java | 0 .../src/com/cloud/vm/ConsoleProxy.java | 0 .../src/com/cloud/vm/SecondaryStorageVm.java | 0 {core => api}/src/com/cloud/vm/SystemVm.java | 0 .../src/com/cloud/vm/VirtualMachineName.java | 0 .../src/com/cloud/vm/VmDetailConstants.java | 0 core/src/com/cloud/vm/ConsoleProxyVO.java | 151 --------- .../src/com/cloud/alert/dao/AlertDao.java | 0 .../src/com/cloud/alert/dao/AlertDaoImpl.java | 0 .../com/cloud/capacity/dao/CapacityDao.java | 0 .../cloud/capacity/dao/CapacityDaoImpl.java | 1 - .../cloud/certificate/dao/CertificateDao.java | 0 .../certificate/dao/CertificateDaoImpl.java | 0 .../ClusterInvalidSessionException.java | 0 .../cluster/ManagementServerHostPeerVO.java | 0 .../cloud/cluster/ManagementServerHostVO.java | 0 .../cluster/agentlb/HostTransferMapVO.java | 0 .../agentlb/dao/HostTransferMapDao.java | 0 .../agentlb/dao/HostTransferMapDaoImpl.java | 0 .../cluster/dao/ManagementServerHostDao.java | 0 .../dao/ManagementServerHostDaoImpl.java | 0 .../dao/ManagementServerHostPeerDao.java | 0 .../dao/ManagementServerHostPeerDaoImpl.java | 0 .../configuration/dao/ConfigurationDao.java | 0 .../dao/ConfigurationDaoImpl.java | 0 .../configuration/dao/ResourceCountDao.java | 0 .../dao/ResourceCountDaoImpl.java | 0 .../configuration/dao/ResourceLimitDao.java | 0 .../dao/ResourceLimitDaoImpl.java | 0 .../src/com/cloud/dc/AccountVlanMapVO.java | 0 .../src/com/cloud/dc/ClusterDetailsDao.java | 0 .../com/cloud/dc/ClusterDetailsDaoImpl.java | 0 .../src/com/cloud/dc/ClusterDetailsVO.java | 0 .../schema}/src/com/cloud/dc/ClusterVO.java | 0 .../src/com/cloud/dc/ClusterVSMMapVO.java | 0 .../com/cloud/dc/DataCenterIpAddressVO.java | 0 .../dc/DataCenterLinkLocalIpAddressVO.java | 0 .../src/com/cloud/dc/DataCenterVO.java | 0 .../src/com/cloud/dc/DataCenterVnetVO.java | 0 .../schema}/src/com/cloud/dc/DcDetailVO.java | 0 .../schema}/src/com/cloud/dc/HostPodVO.java | 0 .../schema}/src/com/cloud/dc/PodCluster.java | 0 .../src/com/cloud/dc/PodVlanMapVO.java | 0 .../schema}/src/com/cloud/dc/PodVlanVO.java | 0 .../cloud/dc/StorageNetworkIpAddressVO.java | 0 .../com/cloud/dc/StorageNetworkIpRangeVO.java | 0 .../schema}/src/com/cloud/dc/VlanVO.java | 0 .../com/cloud/dc/dao/AccountVlanMapDao.java | 0 .../cloud/dc/dao/AccountVlanMapDaoImpl.java | 0 .../src/com/cloud/dc/dao/ClusterDao.java | 0 .../src/com/cloud/dc/dao/ClusterDaoImpl.java | 0 .../com/cloud/dc/dao/ClusterVSMMapDao.java | 0 .../cloud/dc/dao/ClusterVSMMapDaoImpl.java | 0 .../src/com/cloud/dc/dao/DataCenterDao.java | 0 .../com/cloud/dc/dao/DataCenterDaoImpl.java | 0 .../cloud/dc/dao/DataCenterIpAddressDao.java | 0 .../dc/dao/DataCenterIpAddressDaoImpl.java | 0 .../dao/DataCenterLinkLocalIpAddressDao.java | 0 .../DataCenterLinkLocalIpAddressDaoImpl.java | 0 .../com/cloud/dc/dao/DataCenterVnetDao.java | 0 .../cloud/dc/dao/DataCenterVnetDaoImpl.java | 0 .../src/com/cloud/dc/dao/DcDetailsDao.java | 0 .../com/cloud/dc/dao/DcDetailsDaoImpl.java | 0 .../src/com/cloud/dc/dao/HostPodDao.java | 0 .../src/com/cloud/dc/dao/HostPodDaoImpl.java | 0 .../src/com/cloud/dc/dao/PodVlanDao.java | 0 .../src/com/cloud/dc/dao/PodVlanDaoImpl.java | 0 .../src/com/cloud/dc/dao/PodVlanMapDao.java | 0 .../com/cloud/dc/dao/PodVlanMapDaoImpl.java | 0 .../dc/dao/StorageNetworkIpAddressDao.java | 0 .../dao/StorageNetworkIpAddressDaoImpl.java | 0 .../dc/dao/StorageNetworkIpRangeDao.java | 0 .../dc/dao/StorageNetworkIpRangeDaoImpl.java | 0 .../schema}/src/com/cloud/dc/dao/VlanDao.java | 0 .../src/com/cloud/dc/dao/VlanDaoImpl.java | 0 .../src/com/cloud/domain/DomainVO.java | 0 .../src/com/cloud/domain/dao/DomainDao.java | 0 .../com/cloud/domain/dao/DomainDaoImpl.java | 0 .../src/com/cloud/host/dao/HostDao.java | 0 .../src/com/cloud/host/dao/HostDaoImpl.java | 0 .../com/cloud/host/dao/HostDetailsDao.java | 0 .../cloud/host/dao/HostDetailsDaoImpl.java | 0 .../src/com/cloud/host/dao/HostTagsDao.java | 0 .../com/cloud/host/dao/HostTagsDaoImpl.java | 0 .../dao/HypervisorCapabilitiesDao.java | 0 .../dao/HypervisorCapabilitiesDaoImpl.java | 0 .../src/com/cloud/keystore/KeystoreDao.java | 0 .../com/cloud/keystore/KeystoreDaoImpl.java | 0 .../src/com/cloud/keystore/KeystoreVO.java | 0 .../cloud/migration/DiskOffering20Dao.java | 0 .../migration/DiskOffering20DaoImpl.java | 0 .../com/cloud/migration/DiskOffering20VO.java | 0 .../cloud/migration/DiskOffering21Dao.java | 0 .../migration/DiskOffering21DaoImpl.java | 0 .../com/cloud/migration/DiskOffering21VO.java | 0 .../cloud/migration/ServiceOffering20Dao.java | 0 .../migration/ServiceOffering20DaoImpl.java | 0 .../cloud/migration/ServiceOffering20VO.java | 0 .../cloud/migration/ServiceOffering21Dao.java | 0 .../migration/ServiceOffering21DaoImpl.java | 0 .../cloud/migration/ServiceOffering21VO.java | 0 .../cloud/network/LBHealthCheckPolicyVO.java | 0 .../com/cloud/network/UserIpv6AddressVO.java | 0 .../as/AutoScalePolicyConditionMapVO.java | 0 .../cloud/network/as/AutoScalePolicyVO.java | 0 .../as/AutoScaleVmGroupPolicyMapVO.java | 0 .../cloud/network/as/AutoScaleVmGroupVO.java | 0 .../network/as/AutoScaleVmProfileVO.java | 0 .../src/com/cloud/network/as/ConditionVO.java | 0 .../src/com/cloud/network/as/CounterVO.java | 0 .../dao/AutoScalePolicyConditionMapDao.java | 0 .../AutoScalePolicyConditionMapDaoImpl.java | 0 .../network/as/dao/AutoScalePolicyDao.java | 0 .../as/dao/AutoScalePolicyDaoImpl.java | 0 .../network/as/dao/AutoScaleVmGroupDao.java | 0 .../as/dao/AutoScaleVmGroupDaoImpl.java | 0 .../as/dao/AutoScaleVmGroupPolicyMapDao.java | 0 .../dao/AutoScaleVmGroupPolicyMapDaoImpl.java | 0 .../network/as/dao/AutoScaleVmProfileDao.java | 0 .../as/dao/AutoScaleVmProfileDaoImpl.java | 0 .../cloud/network/as/dao/ConditionDao.java | 0 .../network/as/dao/ConditionDaoImpl.java | 0 .../com/cloud/network/as/dao/CounterDao.java | 0 .../cloud/network/as/dao/CounterDaoImpl.java | 0 .../dao/ExternalFirewallDeviceDao.java | 0 .../dao/ExternalFirewallDeviceDaoImpl.java | 0 .../network/dao/ExternalFirewallDeviceVO.java | 0 .../dao/ExternalLoadBalancerDeviceDao.java | 0 .../ExternalLoadBalancerDeviceDaoImpl.java | 0 .../dao/ExternalLoadBalancerDeviceVO.java | 0 .../network/dao/FirewallRulesCidrsDao.java | 0 .../dao/FirewallRulesCidrsDaoImpl.java | 0 .../network/dao/FirewallRulesCidrsVO.java | 0 .../cloud/network/dao/FirewallRulesDao.java | 0 .../network/dao/FirewallRulesDaoImpl.java | 0 .../com/cloud/network/dao/IPAddressDao.java | 0 .../cloud/network/dao/IPAddressDaoImpl.java | 0 .../com/cloud/network/dao/IPAddressVO.java | 0 .../dao/InlineLoadBalancerNicMapDao.java | 0 .../dao/InlineLoadBalancerNicMapDaoImpl.java | 0 .../dao/InlineLoadBalancerNicMapVO.java | 0 .../network/dao/LBHealthCheckPolicyDao.java | 0 .../dao/LBHealthCheckPolicyDaoImpl.java | 0 .../network/dao/LBStickinessPolicyDao.java | 0 .../dao/LBStickinessPolicyDaoImpl.java | 0 .../network/dao/LBStickinessPolicyVO.java | 0 .../cloud/network/dao/LoadBalancerDao.java | 0 .../network/dao/LoadBalancerDaoImpl.java | 0 .../network/dao/LoadBalancerVMMapDao.java | 0 .../network/dao/LoadBalancerVMMapDaoImpl.java | 0 .../network/dao/LoadBalancerVMMapVO.java | 0 .../com/cloud/network/dao/LoadBalancerVO.java | 0 .../cloud/network/dao/NetworkAccountDao.java | 0 .../network/dao/NetworkAccountDaoImpl.java | 0 .../cloud/network/dao/NetworkAccountVO.java | 0 .../src/com/cloud/network/dao/NetworkDao.java | 0 .../com/cloud/network/dao/NetworkDaoImpl.java | 0 .../cloud/network/dao/NetworkDomainDao.java | 0 .../network/dao/NetworkDomainDaoImpl.java | 0 .../cloud/network/dao/NetworkDomainVO.java | 0 .../dao/NetworkExternalFirewallDao.java | 0 .../dao/NetworkExternalFirewallDaoImpl.java | 0 .../dao/NetworkExternalFirewallVO.java | 0 .../dao/NetworkExternalLoadBalancerDao.java | 0 .../NetworkExternalLoadBalancerDaoImpl.java | 0 .../dao/NetworkExternalLoadBalancerVO.java | 0 .../com/cloud/network/dao/NetworkOpDao.java | 0 .../cloud/network/dao/NetworkOpDaoImpl.java | 0 .../com/cloud/network/dao/NetworkOpVO.java | 0 .../network/dao/NetworkRuleConfigDao.java | 0 .../network/dao/NetworkRuleConfigDaoImpl.java | 0 .../network/dao/NetworkRuleConfigVO.java | 0 .../network/dao/NetworkServiceMapDao.java | 0 .../network/dao/NetworkServiceMapDaoImpl.java | 0 .../network/dao/NetworkServiceMapVO.java | 0 .../src/com/cloud/network/dao/NetworkVO.java | 0 .../cloud/network/dao/PhysicalNetworkDao.java | 0 .../network/dao/PhysicalNetworkDaoImpl.java | 0 ...PhysicalNetworkIsolationMethodDaoImpl.java | 0 .../dao/PhysicalNetworkIsolationMethodVO.java | 0 .../PhysicalNetworkServiceProviderDao.java | 0 ...PhysicalNetworkServiceProviderDaoImpl.java | 0 .../dao/PhysicalNetworkServiceProviderVO.java | 0 .../dao/PhysicalNetworkTagDaoImpl.java | 0 .../network/dao/PhysicalNetworkTagVO.java | 0 .../dao/PhysicalNetworkTrafficTypeDao.java | 0 .../PhysicalNetworkTrafficTypeDaoImpl.java | 0 .../dao/PhysicalNetworkTrafficTypeVO.java | 0 .../cloud/network/dao/PhysicalNetworkVO.java | 0 .../com/cloud/network/dao/PortProfileDao.java | 0 .../cloud/network/dao/PortProfileDaoImpl.java | 0 .../com/cloud/network/dao/PortProfileVO.java | 0 .../cloud/network/dao/RemoteAccessVpnDao.java | 0 .../network/dao/RemoteAccessVpnDaoImpl.java | 0 .../cloud/network/dao/RemoteAccessVpnVO.java | 0 .../cloud/network/dao/RouterNetworkDao.java | 0 .../network/dao/RouterNetworkDaoImpl.java | 0 .../cloud/network/dao/RouterNetworkVO.java | 0 .../dao/Site2SiteCustomerGatewayDao.java | 0 .../dao/Site2SiteCustomerGatewayDaoImpl.java | 0 .../dao/Site2SiteCustomerGatewayVO.java | 0 .../dao/Site2SiteVpnConnectionDao.java | 0 .../dao/Site2SiteVpnConnectionDaoImpl.java | 0 .../network/dao/Site2SiteVpnConnectionVO.java | 0 .../network/dao/Site2SiteVpnGatewayDao.java | 0 .../dao/Site2SiteVpnGatewayDaoImpl.java | 0 .../network/dao/Site2SiteVpnGatewayVO.java | 0 .../cloud/network/dao/UserIpv6AddressDao.java | 0 .../network/dao/UserIpv6AddressDaoImpl.java | 0 .../network/dao/VirtualRouterProviderDao.java | 0 .../dao/VirtualRouterProviderDaoImpl.java | 0 .../src/com/cloud/network/dao/VpnUserDao.java | 0 .../com/cloud/network/dao/VpnUserDaoImpl.java | 0 .../element/VirtualRouterProviderVO.java | 0 .../cloud/network/rules/FirewallRuleVO.java | 0 .../network/rules/PortForwardingRuleVO.java | 0 .../rules/dao/PortForwardingRulesDao.java | 0 .../rules/dao/PortForwardingRulesDaoImpl.java | 0 .../security/dao/SecurityGroupDao.java | 0 .../security/dao/SecurityGroupDaoImpl.java | 0 .../security/dao/SecurityGroupRuleDao.java | 0 .../dao/SecurityGroupRuleDaoImpl.java | 0 .../security/dao/SecurityGroupRulesDao.java | 0 .../dao/SecurityGroupRulesDaoImpl.java | 0 .../security/dao/SecurityGroupVMMapDao.java | 0 .../dao/SecurityGroupVMMapDaoImpl.java | 0 .../security/dao/SecurityGroupWorkDao.java | 0 .../dao/SecurityGroupWorkDaoImpl.java | 45 ++- .../network/security/dao/VmRulesetLogDao.java | 0 .../security/dao/VmRulesetLogDaoImpl.java | 0 .../com/cloud/network/vpc/PrivateIpVO.java | 0 .../com/cloud/network/vpc/StaticRouteVO.java | 0 .../com/cloud/network/vpc/VpcGatewayVO.java | 0 .../network/vpc/VpcOfferingServiceMapVO.java | 0 .../com/cloud/network/vpc/VpcOfferingVO.java | 0 .../cloud/network/vpc/VpcServiceMapVO.java | 0 .../src/com/cloud/network/vpc/VpcVO.java | 0 .../cloud/network/vpc/dao/PrivateIpDao.java | 0 .../network/vpc/dao/PrivateIpDaoImpl.java | 0 .../cloud/network/vpc/dao/StaticRouteDao.java | 0 .../network/vpc/dao/StaticRouteDaoImpl.java | 0 .../src/com/cloud/network/vpc/dao/VpcDao.java | 0 .../com/cloud/network/vpc/dao/VpcDaoImpl.java | 0 .../cloud/network/vpc/dao/VpcGatewayDao.java | 0 .../network/vpc/dao/VpcGatewayDaoImpl.java | 0 .../cloud/network/vpc/dao/VpcOfferingDao.java | 0 .../network/vpc/dao/VpcOfferingDaoImpl.java | 0 .../vpc/dao/VpcOfferingServiceMapDao.java | 0 .../vpc/dao/VpcOfferingServiceMapDaoImpl.java | 0 .../network/vpc/dao/VpcServiceMapDao.java | 0 .../network/vpc/dao/VpcServiceMapDaoImpl.java | 0 .../NetworkOfferingServiceMapVO.java | 0 .../cloud/offerings/NetworkOfferingVO.java | 0 .../offerings/dao/NetworkOfferingDao.java | 0 .../offerings/dao/NetworkOfferingDaoImpl.java | 0 .../dao/NetworkOfferingServiceMapDao.java | 0 .../dao/NetworkOfferingServiceMapDaoImpl.java | 0 .../com/cloud/projects/ProjectAccountVO.java | 0 .../cloud/projects/ProjectInvitationVO.java | 0 .../src/com/cloud/projects/ProjectVO.java | 0 .../cloud/projects/dao/ProjectAccountDao.java | 0 .../projects/dao/ProjectAccountDaoImpl.java | 0 .../com/cloud/projects/dao/ProjectDao.java | 0 .../cloud/projects/dao/ProjectDaoImpl.java | 0 .../projects/dao/ProjectInvitationDao.java | 0 .../dao/ProjectInvitationDaoImpl.java | 0 .../cloud/secstorage/CommandExecLogDao.java | 0 .../secstorage/CommandExecLogDaoImpl.java | 0 .../cloud/secstorage/CommandExecLogVO.java | 0 .../com/cloud/service/ServiceOfferingVO.java | 0 .../cloud/service/dao/ServiceOfferingDao.java | 0 .../service/dao/ServiceOfferingDaoImpl.java | 0 .../cloud/storage/dao/DiskOfferingDao.java | 0 .../storage/dao/DiskOfferingDaoImpl.java | 0 .../cloud/storage/dao/GuestOSCategoryDao.java | 0 .../storage/dao/GuestOSCategoryDaoImpl.java | 0 .../src/com/cloud/storage/dao/GuestOSDao.java | 0 .../com/cloud/storage/dao/GuestOSDaoImpl.java | 0 .../storage/dao/LaunchPermissionDao.java | 0 .../storage/dao/LaunchPermissionDaoImpl.java | 0 .../src/com/cloud/storage/dao/S3Dao.java | 0 .../src/com/cloud/storage/dao/S3DaoImpl.java | 0 .../com/cloud/storage/dao/SnapshotDao.java | 0 .../cloud/storage/dao/SnapshotDaoImpl.java | 0 .../cloud/storage/dao/SnapshotPolicyDao.java | 0 .../storage/dao/SnapshotPolicyDaoImpl.java | 0 .../storage/dao/SnapshotScheduleDao.java | 0 .../storage/dao/SnapshotScheduleDaoImpl.java | 0 .../dao/StoragePoolDetailsDaoImpl.java | 0 .../cloud/storage/dao/StoragePoolHostDao.java | 0 .../storage/dao/StoragePoolHostDaoImpl.java | 0 .../cloud/storage/dao/StoragePoolWorkDao.java | 0 .../storage/dao/StoragePoolWorkDaoImpl.java | 0 .../src/com/cloud/storage/dao/SwiftDao.java | 0 .../com/cloud/storage/dao/SwiftDaoImpl.java | 0 .../src/com/cloud/storage/dao/UploadDao.java | 0 .../com/cloud/storage/dao/UploadDaoImpl.java | 0 .../com/cloud/storage/dao/VMTemplateDao.java | 0 .../cloud/storage/dao/VMTemplateDaoImpl.java | 0 .../storage/dao/VMTemplateDetailsDao.java | 0 .../storage/dao/VMTemplateDetailsDaoImpl.java | 0 .../cloud/storage/dao/VMTemplateHostDao.java | 0 .../storage/dao/VMTemplateHostDaoImpl.java | 0 .../cloud/storage/dao/VMTemplatePoolDao.java | 0 .../storage/dao/VMTemplatePoolDaoImpl.java | 0 .../cloud/storage/dao/VMTemplateS3Dao.java | 0 .../storage/dao/VMTemplateS3DaoImpl.java | 0 .../cloud/storage/dao/VMTemplateSwiftDao.java | 0 .../storage/dao/VMTemplateSwiftDaoImpl.java | 0 .../cloud/storage/dao/VMTemplateZoneDao.java | 0 .../storage/dao/VMTemplateZoneDaoImpl.java | 0 .../src/com/cloud/storage/dao/VolumeDao.java | 0 .../com/cloud/storage/dao/VolumeDaoImpl.java | 0 .../com/cloud/storage/dao/VolumeHostDao.java | 0 .../cloud/storage/dao/VolumeHostDaoImpl.java | 0 .../src/com/cloud/tags/ResourceTagVO.java | 0 .../com/cloud/tags/dao/ResourceTagDao.java | 0 .../cloud/tags/dao/ResourceTagsDaoImpl.java | 0 .../com/cloud/upgrade/DatabaseCreator.java | 0 .../upgrade/DatabaseIntegrityChecker.java | 0 .../cloud/upgrade/DatabaseUpgradeChecker.java | 8 +- .../PremiumDatabaseUpgradeChecker.java | 0 .../src/com/cloud/upgrade/dao/DbUpgrade.java | 0 .../com/cloud/upgrade/dao/DbUpgradeUtils.java | 0 .../cloud/upgrade/dao/Upgrade217to218.java | 0 .../com/cloud/upgrade/dao/Upgrade218to22.java | 17 +- .../dao/Upgrade218to224DomainVlans.java | 0 .../upgrade/dao/Upgrade218to22Premium.java | 0 .../cloud/upgrade/dao/Upgrade2210to2211.java | 0 .../cloud/upgrade/dao/Upgrade2211to2212.java | 0 .../upgrade/dao/Upgrade2211to2212Premium.java | 0 .../cloud/upgrade/dao/Upgrade2212to2213.java | 0 .../cloud/upgrade/dao/Upgrade2213to2214.java | 48 +-- .../cloud/upgrade/dao/Upgrade2214to30.java | 0 .../cloud/upgrade/dao/Upgrade221to222.java | 0 .../upgrade/dao/Upgrade221to222Premium.java | 0 .../cloud/upgrade/dao/Upgrade222to224.java | 0 .../upgrade/dao/Upgrade222to224Premium.java | 0 .../cloud/upgrade/dao/Upgrade224to225.java | 0 .../cloud/upgrade/dao/Upgrade225to226.java | 0 .../cloud/upgrade/dao/Upgrade227to228.java | 0 .../upgrade/dao/Upgrade227to228Premium.java | 0 .../cloud/upgrade/dao/Upgrade228to229.java | 0 .../cloud/upgrade/dao/Upgrade229to2210.java | 0 .../cloud/upgrade/dao/Upgrade301to302.java | 0 .../com/cloud/upgrade/dao/Upgrade302to40.java | 0 .../com/cloud/upgrade/dao/Upgrade30to301.java | 0 .../com/cloud/upgrade/dao/Upgrade30xBase.java | 0 .../com/cloud/upgrade/dao/Upgrade40to41.java | 0 .../cloud/upgrade/dao/Upgrade410to420.java | 0 .../upgrade/dao/UpgradeSnapshot217to224.java | 0 .../upgrade/dao/UpgradeSnapshot223to224.java | 0 .../src/com/cloud/upgrade/dao/VersionDao.java | 0 .../com/cloud/upgrade/dao/VersionDaoImpl.java | 0 .../src/com/cloud/upgrade/dao/VersionVO.java | 0 .../usage/ExternalPublicIpStatisticsVO.java | 0 .../src/com/cloud/usage/UsageIPAddressVO.java | 0 .../src/com/cloud/usage/UsageJobVO.java | 0 .../usage/UsageLoadBalancerPolicyVO.java | 0 .../cloud/usage/UsageNetworkOfferingVO.java | 0 .../src/com/cloud/usage/UsageNetworkVO.java | 0 .../usage/UsagePortForwardingRuleVO.java | 0 .../com/cloud/usage/UsageSecurityGroupVO.java | 0 .../src/com/cloud/usage/UsageStorageVO.java | 0 .../com/cloud/usage/UsageVMInstanceVO.java | 0 .../schema}/src/com/cloud/usage/UsageVO.java | 0 .../src/com/cloud/usage/UsageVPNUserVO.java | 0 .../src/com/cloud/usage/UsageVolumeVO.java | 0 .../dao/ExternalPublicIpStatisticsDao.java | 0 .../ExternalPublicIpStatisticsDaoImpl.java | 0 .../src/com/cloud/usage/dao/UsageDao.java | 16 +- .../src/com/cloud/usage/dao/UsageDaoImpl.java | 23 +- .../cloud/usage/dao/UsageIPAddressDao.java | 0 .../usage/dao/UsageIPAddressDaoImpl.java | 0 .../src/com/cloud/usage/dao/UsageJobDao.java | 4 +- .../com/cloud/usage/dao/UsageJobDaoImpl.java | 6 +- .../usage/dao/UsageLoadBalancerPolicyDao.java | 0 .../dao/UsageLoadBalancerPolicyDaoImpl.java | 0 .../com/cloud/usage/dao/UsageNetworkDao.java | 0 .../cloud/usage/dao/UsageNetworkDaoImpl.java | 0 .../usage/dao/UsageNetworkOfferingDao.java | 0 .../dao/UsageNetworkOfferingDaoImpl.java | 0 .../usage/dao/UsagePortForwardingRuleDao.java | 0 .../dao/UsagePortForwardingRuleDaoImpl.java | 0 .../usage/dao/UsageSecurityGroupDao.java | 0 .../usage/dao/UsageSecurityGroupDaoImpl.java | 0 .../com/cloud/usage/dao/UsageStorageDao.java | 0 .../cloud/usage/dao/UsageStorageDaoImpl.java | 0 .../cloud/usage/dao/UsageVMInstanceDao.java | 0 .../usage/dao/UsageVMInstanceDaoImpl.java | 0 .../com/cloud/usage/dao/UsageVPNUserDao.java | 0 .../cloud/usage/dao/UsageVPNUserDaoImpl.java | 0 .../com/cloud/usage/dao/UsageVolumeDao.java | 0 .../cloud/usage/dao/UsageVolumeDaoImpl.java | 0 .../src/com/cloud/user/AccountDetailVO.java | 0 .../src/com/cloud/user/AccountDetailsDao.java | 0 .../com/cloud/user/AccountDetailsDaoImpl.java | 0 .../src/com/cloud/user/dao/AccountDao.java | 0 .../com/cloud/user/dao/AccountDaoImpl.java | 0 .../src/com/cloud/user/dao/SSHKeyPairDao.java | 0 .../com/cloud/user/dao/SSHKeyPairDaoImpl.java | 0 .../com/cloud/user/dao/UserAccountDao.java | 0 .../cloud/user/dao/UserAccountDaoImpl.java | 0 .../src/com/cloud/user/dao/UserDao.java | 0 .../src/com/cloud/user/dao/UserDaoImpl.java | 0 .../com/cloud/user/dao/UserStatisticsDao.java | 0 .../cloud/user/dao/UserStatisticsDaoImpl.java | 0 .../com/cloud/user/dao/UserStatsLogDao.java | 0 .../cloud/user/dao/UserStatsLogDaoImpl.java | 0 .../src/com/cloud/vm/ConsoleProxyVO.java | 287 ++++++++++++++++++ .../src/com/cloud/vm/DomainRouterVO.java | 0 .../com/cloud/vm/InstanceGroupVMMapVO.java | 0 .../src/com/cloud/vm/InstanceGroupVO.java | 0 .../schema}/src/com/cloud/vm/ItWorkDao.java | 0 .../src/com/cloud/vm/ItWorkDaoImpl.java | 0 .../schema}/src/com/cloud/vm/ItWorkVO.java | 0 .../schema}/src/com/cloud/vm/NicVO.java | 0 .../com/cloud/vm/SecondaryStorageVmVO.java | 0 .../com/cloud/vm/UserVmCloneSettingVO.java | 0 .../src/com/cloud/vm/UserVmDetailVO.java | 0 .../schema}/src/com/cloud/vm/UserVmVO.java | 0 .../src/com/cloud/vm/dao/ConsoleProxyDao.java | 0 .../com/cloud/vm/dao/ConsoleProxyDaoImpl.java | 0 .../src/com/cloud/vm/dao/DomainRouterDao.java | 0 .../com/cloud/vm/dao/DomainRouterDaoImpl.java | 0 .../com/cloud/vm/dao/InstanceGroupDao.java | 0 .../cloud/vm/dao/InstanceGroupDaoImpl.java | 0 .../cloud/vm/dao/InstanceGroupVMMapDao.java | 0 .../vm/dao/InstanceGroupVMMapDaoImpl.java | 0 .../schema}/src/com/cloud/vm/dao/NicDao.java | 0 .../src/com/cloud/vm/dao/NicDaoImpl.java | 0 .../com/cloud/vm/dao/NicSecondaryIpDao.java | 0 .../cloud/vm/dao/NicSecondaryIpDaoImpl.java | 0 .../com/cloud/vm/dao/NicSecondaryIpVO.java | 0 .../cloud/vm/dao/SecondaryStorageVmDao.java | 0 .../vm/dao/SecondaryStorageVmDaoImpl.java | 0 .../cloud/vm/dao/UserVmCloneSettingDao.java | 0 .../vm/dao/UserVmCloneSettingDaoImpl.java | 0 .../src/com/cloud/vm/dao/UserVmDao.java | 0 .../src/com/cloud/vm/dao/UserVmDaoImpl.java | 0 .../src/com/cloud/vm/dao/UserVmData.java | 0 .../com/cloud/vm/dao/UserVmDetailsDao.java | 0 .../cloud/vm/dao/UserVmDetailsDaoImpl.java | 0 .../src/com/cloud/vm/dao/VMInstanceDao.java | 0 .../com/cloud/vm/dao/VMInstanceDaoImpl.java | 0 .../cloud/vm/snapshot/dao/VMSnapshotDao.java | 0 .../vm/snapshot/dao/VMSnapshotDaoImpl.java | 0 .../affinity/AffinityGroupVMMapVO.java | 0 .../cloudstack/affinity/AffinityGroupVO.java | 0 .../affinity/dao/AffinityGroupDao.java | 0 .../affinity/dao/AffinityGroupDaoImpl.java | 0 .../affinity/dao/AffinityGroupVMMapDao.java | 0 .../dao/AffinityGroupVMMapDaoImpl.java | 0 .../cloudstack/region/RegionSyncVO.java | 0 .../apache/cloudstack/region/RegionVO.java | 0 .../cloudstack/region/dao/RegionDao.java | 0 .../cloudstack/region/dao/RegionDaoImpl.java | 0 .../gslb/GlobalLoadBalancerDaoImpl.java | 0 .../gslb/GlobalLoadBalancerLbRuleMapDao.java | 0 .../GlobalLoadBalancerLbRuleMapDaoImpl.java | 0 .../gslb/GlobalLoadBalancerLbRuleMapVO.java | 0 .../gslb/GlobalLoadBalancerRuleDao.java | 0 .../region/gslb/GlobalLoadBalancerRuleVO.java | 0 .../src/com/cloud/cluster/CheckPointVO.java | 121 -------- .../com/cloud/cluster/dao/StackMaidDao.java | 44 --- .../cloud/cluster/dao/StackMaidDaoImpl.java | 208 ------------- .../consoleproxy/ConsoleProxyManagerImpl.java | 194 +----------- .../src/com/cloud/maint/AgentUpgradeVO.java | 63 ---- .../src/com/cloud/maint/UpgradeManager.java | 47 --- .../com/cloud/maint/UpgradeManagerImpl.java | 189 ------------ .../com/cloud/maint/UpgradeManagerMBean.java | 23 -- .../src/com/cloud/maint/UpgradeMonitor.java | 34 --- .../com/cloud/maint/dao/AgentUpgradeDao.java | 23 -- .../cloud/maint/dao/AgentUpgradeDaoImpl.java | 29 -- .../migration/Db21to22MigrationUtil.java | 228 -------------- .../Db22beta4to22GAMigrationUtil.java | 128 -------- .../src/com/cloud/maint/Version.java | 0 479 files changed, 374 insertions(+), 1563 deletions(-) rename {core => api}/src/com/cloud/info/ConsoleProxyLoadInfo.java (100%) rename {core => api}/src/com/cloud/info/RunningHostCountInfo.java (100%) rename {server => api}/src/com/cloud/network/UserIpv6Address.java (100%) rename {core => api}/src/com/cloud/vm/ConsoleProxy.java (100%) rename {core => api}/src/com/cloud/vm/SecondaryStorageVm.java (100%) rename {core => api}/src/com/cloud/vm/SystemVm.java (100%) rename {core => api}/src/com/cloud/vm/VirtualMachineName.java (100%) rename {core => api}/src/com/cloud/vm/VmDetailConstants.java (100%) delete mode 100644 core/src/com/cloud/vm/ConsoleProxyVO.java rename {server => engine/schema}/src/com/cloud/alert/dao/AlertDao.java (100%) rename {server => engine/schema}/src/com/cloud/alert/dao/AlertDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/capacity/dao/CapacityDao.java (100%) rename {server => engine/schema}/src/com/cloud/capacity/dao/CapacityDaoImpl.java (99%) rename {server => engine/schema}/src/com/cloud/certificate/dao/CertificateDao.java (100%) rename {server => engine/schema}/src/com/cloud/certificate/dao/CertificateDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/cluster/ClusterInvalidSessionException.java (100%) rename {server => engine/schema}/src/com/cloud/cluster/ManagementServerHostPeerVO.java (100%) rename {server => engine/schema}/src/com/cloud/cluster/ManagementServerHostVO.java (100%) rename {server => engine/schema}/src/com/cloud/cluster/agentlb/HostTransferMapVO.java (100%) rename {server => engine/schema}/src/com/cloud/cluster/agentlb/dao/HostTransferMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/cluster/agentlb/dao/HostTransferMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/cluster/dao/ManagementServerHostDao.java (100%) rename {server => engine/schema}/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/cluster/dao/ManagementServerHostPeerDao.java (100%) rename {server => engine/schema}/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/configuration/dao/ConfigurationDao.java (100%) rename {server => engine/schema}/src/com/cloud/configuration/dao/ConfigurationDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/configuration/dao/ResourceCountDao.java (100%) rename {server => engine/schema}/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/configuration/dao/ResourceLimitDao.java (100%) rename {server => engine/schema}/src/com/cloud/configuration/dao/ResourceLimitDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/AccountVlanMapVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/ClusterDetailsDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/ClusterDetailsDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/ClusterDetailsVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/ClusterVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/ClusterVSMMapVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/DataCenterIpAddressVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/DataCenterLinkLocalIpAddressVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/DataCenterVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/DataCenterVnetVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/DcDetailVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/HostPodVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/PodCluster.java (100%) rename {server => engine/schema}/src/com/cloud/dc/PodVlanMapVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/PodVlanVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/StorageNetworkIpAddressVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/StorageNetworkIpRangeVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/VlanVO.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/AccountVlanMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/AccountVlanMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/ClusterDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/ClusterDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/ClusterVSMMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/ClusterVSMMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/DataCenterDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/DataCenterDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/DataCenterIpAddressDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/DataCenterVnetDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/DcDetailsDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/DcDetailsDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/HostPodDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/HostPodDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/PodVlanDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/PodVlanDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/PodVlanMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/PodVlanMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/StorageNetworkIpAddressDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/StorageNetworkIpRangeDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/VlanDao.java (100%) rename {server => engine/schema}/src/com/cloud/dc/dao/VlanDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/domain/DomainVO.java (100%) rename {server => engine/schema}/src/com/cloud/domain/dao/DomainDao.java (100%) rename {server => engine/schema}/src/com/cloud/domain/dao/DomainDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/host/dao/HostDao.java (100%) rename {server => engine/schema}/src/com/cloud/host/dao/HostDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/host/dao/HostDetailsDao.java (100%) rename {server => engine/schema}/src/com/cloud/host/dao/HostDetailsDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/host/dao/HostTagsDao.java (100%) rename {server => engine/schema}/src/com/cloud/host/dao/HostTagsDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java (100%) rename {server => engine/schema}/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/keystore/KeystoreDao.java (100%) rename {server => engine/schema}/src/com/cloud/keystore/KeystoreDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/keystore/KeystoreVO.java (100%) rename {server => engine/schema}/src/com/cloud/migration/DiskOffering20Dao.java (100%) rename {server => engine/schema}/src/com/cloud/migration/DiskOffering20DaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/migration/DiskOffering20VO.java (100%) rename {server => engine/schema}/src/com/cloud/migration/DiskOffering21Dao.java (100%) rename {server => engine/schema}/src/com/cloud/migration/DiskOffering21DaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/migration/DiskOffering21VO.java (100%) rename {server => engine/schema}/src/com/cloud/migration/ServiceOffering20Dao.java (100%) rename {server => engine/schema}/src/com/cloud/migration/ServiceOffering20DaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/migration/ServiceOffering20VO.java (100%) rename {server => engine/schema}/src/com/cloud/migration/ServiceOffering21Dao.java (100%) rename {server => engine/schema}/src/com/cloud/migration/ServiceOffering21DaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/migration/ServiceOffering21VO.java (100%) rename {server => engine/schema}/src/com/cloud/network/LBHealthCheckPolicyVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/UserIpv6AddressVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/AutoScalePolicyConditionMapVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/AutoScalePolicyVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/AutoScaleVmGroupPolicyMapVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/AutoScaleVmGroupVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/AutoScaleVmProfileVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/ConditionVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/CounterVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/AutoScalePolicyDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/AutoScalePolicyDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/AutoScaleVmGroupDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/AutoScaleVmGroupDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/AutoScaleVmProfileDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/AutoScaleVmProfileDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/ConditionDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/ConditionDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/CounterDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/as/dao/CounterDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/ExternalFirewallDeviceDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/ExternalFirewallDeviceDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/ExternalFirewallDeviceVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/ExternalLoadBalancerDeviceVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/FirewallRulesCidrsDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/FirewallRulesCidrsVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/FirewallRulesDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/FirewallRulesDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/IPAddressDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/IPAddressDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/IPAddressVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/InlineLoadBalancerNicMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/InlineLoadBalancerNicMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/InlineLoadBalancerNicMapVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/LBStickinessPolicyDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/LBStickinessPolicyVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/LoadBalancerDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/LoadBalancerDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/LoadBalancerVMMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/LoadBalancerVMMapVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/LoadBalancerVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkAccountDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkAccountDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkAccountVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkDomainDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkDomainDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkDomainVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkExternalFirewallDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkExternalFirewallDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkExternalFirewallVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkExternalLoadBalancerDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkExternalLoadBalancerDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkExternalLoadBalancerVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkOpDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkOpDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkOpVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkRuleConfigDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkRuleConfigDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkRuleConfigVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkServiceMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkServiceMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkServiceMapVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/NetworkVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PhysicalNetworkDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PhysicalNetworkDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PhysicalNetworkServiceProviderVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PhysicalNetworkTagDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PhysicalNetworkTagVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PhysicalNetworkVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PortProfileDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PortProfileDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/PortProfileVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/RemoteAccessVpnDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/RemoteAccessVpnDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/RemoteAccessVpnVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/RouterNetworkDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/RouterNetworkDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/RouterNetworkVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/Site2SiteCustomerGatewayDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/Site2SiteCustomerGatewayDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/Site2SiteVpnConnectionDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/Site2SiteVpnConnectionDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/Site2SiteVpnGatewayVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/UserIpv6AddressDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/UserIpv6AddressDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/VirtualRouterProviderDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/VirtualRouterProviderDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/VpnUserDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/VpnUserDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/element/VirtualRouterProviderVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/rules/FirewallRuleVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/rules/PortForwardingRuleVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/security/dao/SecurityGroupDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/security/dao/SecurityGroupRuleDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/security/dao/SecurityGroupRuleDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/security/dao/SecurityGroupRulesDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/security/dao/SecurityGroupVMMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/security/dao/SecurityGroupVMMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/security/dao/SecurityGroupWorkDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java (93%) rename {server => engine/schema}/src/com/cloud/network/security/dao/VmRulesetLogDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/security/dao/VmRulesetLogDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/PrivateIpVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/StaticRouteVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/VpcGatewayVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/VpcOfferingServiceMapVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/VpcOfferingVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/VpcServiceMapVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/VpcVO.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/PrivateIpDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/PrivateIpDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/StaticRouteDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/StaticRouteDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/VpcDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/VpcDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/VpcGatewayDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/VpcGatewayDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/VpcOfferingDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/VpcOfferingDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/VpcOfferingServiceMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/VpcServiceMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/vpc/dao/VpcServiceMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/offerings/NetworkOfferingServiceMapVO.java (100%) rename {server => engine/schema}/src/com/cloud/offerings/NetworkOfferingVO.java (100%) rename {server => engine/schema}/src/com/cloud/offerings/dao/NetworkOfferingDao.java (100%) rename {server => engine/schema}/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/projects/ProjectAccountVO.java (100%) rename {server => engine/schema}/src/com/cloud/projects/ProjectInvitationVO.java (100%) rename {server => engine/schema}/src/com/cloud/projects/ProjectVO.java (100%) rename {server => engine/schema}/src/com/cloud/projects/dao/ProjectAccountDao.java (100%) rename {server => engine/schema}/src/com/cloud/projects/dao/ProjectAccountDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/projects/dao/ProjectDao.java (100%) rename {server => engine/schema}/src/com/cloud/projects/dao/ProjectDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/projects/dao/ProjectInvitationDao.java (100%) rename {server => engine/schema}/src/com/cloud/projects/dao/ProjectInvitationDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/secstorage/CommandExecLogDao.java (100%) rename {server => engine/schema}/src/com/cloud/secstorage/CommandExecLogDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/secstorage/CommandExecLogVO.java (100%) rename {server => engine/schema}/src/com/cloud/service/ServiceOfferingVO.java (100%) rename {server => engine/schema}/src/com/cloud/service/dao/ServiceOfferingDao.java (100%) rename {server => engine/schema}/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/DiskOfferingDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/DiskOfferingDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/GuestOSCategoryDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/GuestOSCategoryDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/GuestOSDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/GuestOSDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/LaunchPermissionDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/S3Dao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/S3DaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/SnapshotDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/SnapshotDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/SnapshotPolicyDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/SnapshotScheduleDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/StoragePoolHostDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/StoragePoolHostDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/StoragePoolWorkDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/SwiftDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/SwiftDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/UploadDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/UploadDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplateDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplateDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplateDetailsDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplateHostDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplatePoolDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplateS3Dao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplateS3DaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplateSwiftDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplateSwiftDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplateZoneDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VolumeDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VolumeDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VolumeHostDao.java (100%) rename {server => engine/schema}/src/com/cloud/storage/dao/VolumeHostDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/tags/ResourceTagVO.java (100%) rename {server => engine/schema}/src/com/cloud/tags/dao/ResourceTagDao.java (100%) rename {server => engine/schema}/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/DatabaseCreator.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/DatabaseIntegrityChecker.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/DatabaseUpgradeChecker.java (98%) rename {server => engine/schema}/src/com/cloud/upgrade/PremiumDatabaseUpgradeChecker.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/DbUpgrade.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/DbUpgradeUtils.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade217to218.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade218to22.java (99%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade218to224DomainVlans.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade218to22Premium.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade2210to2211.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade2211to2212.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade2211to2212Premium.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade2212to2213.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade2213to2214.java (96%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade2214to30.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade221to222.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade221to222Premium.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade222to224.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade222to224Premium.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade224to225.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade225to226.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade227to228.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade227to228Premium.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade228to229.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade229to2210.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade301to302.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade302to40.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade30to301.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade30xBase.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade40to41.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/Upgrade410to420.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/UpgradeSnapshot217to224.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/UpgradeSnapshot223to224.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/VersionDao.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/VersionDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/upgrade/dao/VersionVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/ExternalPublicIpStatisticsVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/UsageIPAddressVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/UsageJobVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/UsageLoadBalancerPolicyVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/UsageNetworkOfferingVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/UsageNetworkVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/UsagePortForwardingRuleVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/UsageSecurityGroupVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/UsageStorageVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/UsageVMInstanceVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/UsageVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/UsageVPNUserVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/UsageVolumeVO.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDao.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageDao.java (70%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageDaoImpl.java (94%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageIPAddressDao.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageJobDao.java (92%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageJobDaoImpl.java (97%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDao.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageNetworkDao.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageNetworkDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageNetworkOfferingDao.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsagePortForwardingRuleDao.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsagePortForwardingRuleDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageSecurityGroupDao.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageStorageDao.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageStorageDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageVMInstanceDao.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageVPNUserDao.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageVolumeDao.java (100%) rename {server => engine/schema}/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/user/AccountDetailVO.java (100%) rename {server => engine/schema}/src/com/cloud/user/AccountDetailsDao.java (100%) rename {server => engine/schema}/src/com/cloud/user/AccountDetailsDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/user/dao/AccountDao.java (100%) rename {server => engine/schema}/src/com/cloud/user/dao/AccountDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/user/dao/SSHKeyPairDao.java (100%) rename {server => engine/schema}/src/com/cloud/user/dao/SSHKeyPairDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/user/dao/UserAccountDao.java (100%) rename {server => engine/schema}/src/com/cloud/user/dao/UserAccountDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/user/dao/UserDao.java (100%) rename {server => engine/schema}/src/com/cloud/user/dao/UserDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/user/dao/UserStatisticsDao.java (100%) rename {server => engine/schema}/src/com/cloud/user/dao/UserStatisticsDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/user/dao/UserStatsLogDao.java (100%) rename {server => engine/schema}/src/com/cloud/user/dao/UserStatsLogDaoImpl.java (100%) create mode 100644 engine/schema/src/com/cloud/vm/ConsoleProxyVO.java rename {core => engine/schema}/src/com/cloud/vm/DomainRouterVO.java (100%) rename {core => engine/schema}/src/com/cloud/vm/InstanceGroupVMMapVO.java (100%) rename {core => engine/schema}/src/com/cloud/vm/InstanceGroupVO.java (100%) rename {server => engine/schema}/src/com/cloud/vm/ItWorkDao.java (100%) rename {server => engine/schema}/src/com/cloud/vm/ItWorkDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/vm/ItWorkVO.java (100%) rename {server => engine/schema}/src/com/cloud/vm/NicVO.java (100%) rename {core => engine/schema}/src/com/cloud/vm/SecondaryStorageVmVO.java (100%) rename {core => engine/schema}/src/com/cloud/vm/UserVmCloneSettingVO.java (100%) rename {core => engine/schema}/src/com/cloud/vm/UserVmDetailVO.java (100%) rename {core => engine/schema}/src/com/cloud/vm/UserVmVO.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/ConsoleProxyDao.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/DomainRouterDao.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/DomainRouterDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/InstanceGroupDao.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/InstanceGroupDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/InstanceGroupVMMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/InstanceGroupVMMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/NicDao.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/NicDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/NicSecondaryIpDao.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/NicSecondaryIpVO.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/SecondaryStorageVmDao.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/UserVmCloneSettingDao.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/UserVmCloneSettingDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/UserVmDao.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/UserVmDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/UserVmData.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/UserVmDetailsDao.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/UserVmDetailsDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/VMInstanceDao.java (100%) rename {server => engine/schema}/src/com/cloud/vm/dao/VMInstanceDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/vm/snapshot/dao/VMSnapshotDao.java (100%) rename {server => engine/schema}/src/com/cloud/vm/snapshot/dao/VMSnapshotDaoImpl.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/affinity/AffinityGroupVMMapVO.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/affinity/AffinityGroupVO.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDao.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/region/RegionSyncVO.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/region/RegionVO.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/region/dao/RegionDao.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/region/dao/RegionDaoImpl.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDao.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDaoImpl.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleDao.java (100%) rename {server => engine/schema}/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java (100%) delete mode 100644 server/src/com/cloud/cluster/CheckPointVO.java delete mode 100644 server/src/com/cloud/cluster/dao/StackMaidDao.java delete mode 100644 server/src/com/cloud/cluster/dao/StackMaidDaoImpl.java delete mode 100644 server/src/com/cloud/maint/AgentUpgradeVO.java delete mode 100644 server/src/com/cloud/maint/UpgradeManager.java delete mode 100644 server/src/com/cloud/maint/UpgradeManagerImpl.java delete mode 100644 server/src/com/cloud/maint/UpgradeManagerMBean.java delete mode 100644 server/src/com/cloud/maint/UpgradeMonitor.java delete mode 100644 server/src/com/cloud/maint/dao/AgentUpgradeDao.java delete mode 100644 server/src/com/cloud/maint/dao/AgentUpgradeDaoImpl.java delete mode 100755 server/src/com/cloud/migration/Db21to22MigrationUtil.java delete mode 100644 server/src/com/cloud/migration/Db22beta4to22GAMigrationUtil.java rename {server => utils}/src/com/cloud/maint/Version.java (100%) diff --git a/core/src/com/cloud/info/ConsoleProxyLoadInfo.java b/api/src/com/cloud/info/ConsoleProxyLoadInfo.java similarity index 100% rename from core/src/com/cloud/info/ConsoleProxyLoadInfo.java rename to api/src/com/cloud/info/ConsoleProxyLoadInfo.java diff --git a/core/src/com/cloud/info/RunningHostCountInfo.java b/api/src/com/cloud/info/RunningHostCountInfo.java similarity index 100% rename from core/src/com/cloud/info/RunningHostCountInfo.java rename to api/src/com/cloud/info/RunningHostCountInfo.java diff --git a/server/src/com/cloud/network/UserIpv6Address.java b/api/src/com/cloud/network/UserIpv6Address.java similarity index 100% rename from server/src/com/cloud/network/UserIpv6Address.java rename to api/src/com/cloud/network/UserIpv6Address.java diff --git a/core/src/com/cloud/vm/ConsoleProxy.java b/api/src/com/cloud/vm/ConsoleProxy.java similarity index 100% rename from core/src/com/cloud/vm/ConsoleProxy.java rename to api/src/com/cloud/vm/ConsoleProxy.java diff --git a/core/src/com/cloud/vm/SecondaryStorageVm.java b/api/src/com/cloud/vm/SecondaryStorageVm.java similarity index 100% rename from core/src/com/cloud/vm/SecondaryStorageVm.java rename to api/src/com/cloud/vm/SecondaryStorageVm.java diff --git a/core/src/com/cloud/vm/SystemVm.java b/api/src/com/cloud/vm/SystemVm.java similarity index 100% rename from core/src/com/cloud/vm/SystemVm.java rename to api/src/com/cloud/vm/SystemVm.java diff --git a/core/src/com/cloud/vm/VirtualMachineName.java b/api/src/com/cloud/vm/VirtualMachineName.java similarity index 100% rename from core/src/com/cloud/vm/VirtualMachineName.java rename to api/src/com/cloud/vm/VirtualMachineName.java diff --git a/core/src/com/cloud/vm/VmDetailConstants.java b/api/src/com/cloud/vm/VmDetailConstants.java similarity index 100% rename from core/src/com/cloud/vm/VmDetailConstants.java rename to api/src/com/cloud/vm/VmDetailConstants.java diff --git a/core/src/com/cloud/vm/ConsoleProxyVO.java b/core/src/com/cloud/vm/ConsoleProxyVO.java deleted file mode 100644 index c57b44f32f0..00000000000 --- a/core/src/com/cloud/vm/ConsoleProxyVO.java +++ /dev/null @@ -1,151 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.vm; - -import java.util.Date; - -import javax.persistence.Column; -import javax.persistence.DiscriminatorValue; -import javax.persistence.Entity; -import javax.persistence.PrimaryKeyJoinColumn; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; -import javax.persistence.Transient; - -import com.cloud.hypervisor.Hypervisor.HypervisorType; - -/** - * ConsoleProxyVO domain object - */ - -@Entity -@Table(name = "console_proxy") -@PrimaryKeyJoinColumn(name = "id") -@DiscriminatorValue(value = "ConsoleProxy") -public class ConsoleProxyVO extends VMInstanceVO implements ConsoleProxy { - - @Column(name = "public_ip_address", nullable = false) - private String publicIpAddress; - - @Column(name = "public_mac_address", nullable = false) - private String publicMacAddress; - - @Column(name = "public_netmask", nullable = false) - private String publicNetmask; - - @Column(name = "active_session", updatable = true, nullable = false) - private int activeSession; - - @Temporal(TemporalType.TIMESTAMP) - @Column(name = "last_update", updatable = true, nullable = true) - private Date lastUpdateTime; - - @Column(name = "session_details", updatable = true, nullable = true) - private byte[] sessionDetails; - - @Transient - private boolean sslEnabled = false; - - @Transient - private int port; - - /** - * Correct constructor to use. - * - */ - public ConsoleProxyVO(long id, long serviceOfferingId, String name, long templateId, HypervisorType hypervisorType, long guestOSId, long dataCenterId, long domainId, long accountId, - int activeSession, boolean haEnabled) { - super(id, serviceOfferingId, name, name, Type.ConsoleProxy, templateId, hypervisorType, guestOSId, domainId, accountId, haEnabled); - this.activeSession = activeSession; - } - - protected ConsoleProxyVO() { - super(); - } - - public void setPublicIpAddress(String publicIpAddress) { - this.publicIpAddress = publicIpAddress; - } - - public void setPublicNetmask(String publicNetmask) { - this.publicNetmask = publicNetmask; - } - - public void setPublicMacAddress(String publicMacAddress) { - this.publicMacAddress = publicMacAddress; - } - - public void setActiveSession(int activeSession) { - this.activeSession = activeSession; - } - - public void setLastUpdateTime(Date time) { - this.lastUpdateTime = time; - } - - public void setSessionDetails(byte[] details) { - this.sessionDetails = details; - } - - @Override - public String getPublicIpAddress() { - return this.publicIpAddress; - } - - @Override - public String getPublicNetmask() { - return this.publicNetmask; - } - - @Override - public String getPublicMacAddress() { - return this.publicMacAddress; - } - - @Override - public int getActiveSession() { - return this.activeSession; - } - - @Override - public Date getLastUpdateTime() { - return this.lastUpdateTime; - } - - @Override - public byte[] getSessionDetails() { - return this.sessionDetails; - } - - public boolean isSslEnabled() { - return sslEnabled; - } - - public void setSslEnabled(boolean sslEnabled) { - this.sslEnabled = sslEnabled; - } - - public void setPort(int port) { - this.port = port; - } - - public int getPort() { - return port; - } - -} diff --git a/server/src/com/cloud/alert/dao/AlertDao.java b/engine/schema/src/com/cloud/alert/dao/AlertDao.java similarity index 100% rename from server/src/com/cloud/alert/dao/AlertDao.java rename to engine/schema/src/com/cloud/alert/dao/AlertDao.java diff --git a/server/src/com/cloud/alert/dao/AlertDaoImpl.java b/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java similarity index 100% rename from server/src/com/cloud/alert/dao/AlertDaoImpl.java rename to engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java diff --git a/server/src/com/cloud/capacity/dao/CapacityDao.java b/engine/schema/src/com/cloud/capacity/dao/CapacityDao.java similarity index 100% rename from server/src/com/cloud/capacity/dao/CapacityDao.java rename to engine/schema/src/com/cloud/capacity/dao/CapacityDao.java diff --git a/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java b/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java similarity index 99% rename from server/src/com/cloud/capacity/dao/CapacityDaoImpl.java rename to engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java index ec5081a6edf..0b9ff1a5ece 100755 --- a/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java +++ b/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java @@ -27,7 +27,6 @@ import java.util.Map; import javax.ejb.Local; import javax.inject.Inject; -import com.cloud.configuration.Config; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; diff --git a/server/src/com/cloud/certificate/dao/CertificateDao.java b/engine/schema/src/com/cloud/certificate/dao/CertificateDao.java similarity index 100% rename from server/src/com/cloud/certificate/dao/CertificateDao.java rename to engine/schema/src/com/cloud/certificate/dao/CertificateDao.java diff --git a/server/src/com/cloud/certificate/dao/CertificateDaoImpl.java b/engine/schema/src/com/cloud/certificate/dao/CertificateDaoImpl.java similarity index 100% rename from server/src/com/cloud/certificate/dao/CertificateDaoImpl.java rename to engine/schema/src/com/cloud/certificate/dao/CertificateDaoImpl.java diff --git a/server/src/com/cloud/cluster/ClusterInvalidSessionException.java b/engine/schema/src/com/cloud/cluster/ClusterInvalidSessionException.java similarity index 100% rename from server/src/com/cloud/cluster/ClusterInvalidSessionException.java rename to engine/schema/src/com/cloud/cluster/ClusterInvalidSessionException.java diff --git a/server/src/com/cloud/cluster/ManagementServerHostPeerVO.java b/engine/schema/src/com/cloud/cluster/ManagementServerHostPeerVO.java similarity index 100% rename from server/src/com/cloud/cluster/ManagementServerHostPeerVO.java rename to engine/schema/src/com/cloud/cluster/ManagementServerHostPeerVO.java diff --git a/server/src/com/cloud/cluster/ManagementServerHostVO.java b/engine/schema/src/com/cloud/cluster/ManagementServerHostVO.java similarity index 100% rename from server/src/com/cloud/cluster/ManagementServerHostVO.java rename to engine/schema/src/com/cloud/cluster/ManagementServerHostVO.java diff --git a/server/src/com/cloud/cluster/agentlb/HostTransferMapVO.java b/engine/schema/src/com/cloud/cluster/agentlb/HostTransferMapVO.java similarity index 100% rename from server/src/com/cloud/cluster/agentlb/HostTransferMapVO.java rename to engine/schema/src/com/cloud/cluster/agentlb/HostTransferMapVO.java diff --git a/server/src/com/cloud/cluster/agentlb/dao/HostTransferMapDao.java b/engine/schema/src/com/cloud/cluster/agentlb/dao/HostTransferMapDao.java similarity index 100% rename from server/src/com/cloud/cluster/agentlb/dao/HostTransferMapDao.java rename to engine/schema/src/com/cloud/cluster/agentlb/dao/HostTransferMapDao.java diff --git a/server/src/com/cloud/cluster/agentlb/dao/HostTransferMapDaoImpl.java b/engine/schema/src/com/cloud/cluster/agentlb/dao/HostTransferMapDaoImpl.java similarity index 100% rename from server/src/com/cloud/cluster/agentlb/dao/HostTransferMapDaoImpl.java rename to engine/schema/src/com/cloud/cluster/agentlb/dao/HostTransferMapDaoImpl.java diff --git a/server/src/com/cloud/cluster/dao/ManagementServerHostDao.java b/engine/schema/src/com/cloud/cluster/dao/ManagementServerHostDao.java similarity index 100% rename from server/src/com/cloud/cluster/dao/ManagementServerHostDao.java rename to engine/schema/src/com/cloud/cluster/dao/ManagementServerHostDao.java diff --git a/server/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java b/engine/schema/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java similarity index 100% rename from server/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java rename to engine/schema/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java diff --git a/server/src/com/cloud/cluster/dao/ManagementServerHostPeerDao.java b/engine/schema/src/com/cloud/cluster/dao/ManagementServerHostPeerDao.java similarity index 100% rename from server/src/com/cloud/cluster/dao/ManagementServerHostPeerDao.java rename to engine/schema/src/com/cloud/cluster/dao/ManagementServerHostPeerDao.java diff --git a/server/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java b/engine/schema/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java similarity index 100% rename from server/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java rename to engine/schema/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java diff --git a/server/src/com/cloud/configuration/dao/ConfigurationDao.java b/engine/schema/src/com/cloud/configuration/dao/ConfigurationDao.java similarity index 100% rename from server/src/com/cloud/configuration/dao/ConfigurationDao.java rename to engine/schema/src/com/cloud/configuration/dao/ConfigurationDao.java diff --git a/server/src/com/cloud/configuration/dao/ConfigurationDaoImpl.java b/engine/schema/src/com/cloud/configuration/dao/ConfigurationDaoImpl.java similarity index 100% rename from server/src/com/cloud/configuration/dao/ConfigurationDaoImpl.java rename to engine/schema/src/com/cloud/configuration/dao/ConfigurationDaoImpl.java diff --git a/server/src/com/cloud/configuration/dao/ResourceCountDao.java b/engine/schema/src/com/cloud/configuration/dao/ResourceCountDao.java similarity index 100% rename from server/src/com/cloud/configuration/dao/ResourceCountDao.java rename to engine/schema/src/com/cloud/configuration/dao/ResourceCountDao.java diff --git a/server/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java b/engine/schema/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java similarity index 100% rename from server/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java rename to engine/schema/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java diff --git a/server/src/com/cloud/configuration/dao/ResourceLimitDao.java b/engine/schema/src/com/cloud/configuration/dao/ResourceLimitDao.java similarity index 100% rename from server/src/com/cloud/configuration/dao/ResourceLimitDao.java rename to engine/schema/src/com/cloud/configuration/dao/ResourceLimitDao.java diff --git a/server/src/com/cloud/configuration/dao/ResourceLimitDaoImpl.java b/engine/schema/src/com/cloud/configuration/dao/ResourceLimitDaoImpl.java similarity index 100% rename from server/src/com/cloud/configuration/dao/ResourceLimitDaoImpl.java rename to engine/schema/src/com/cloud/configuration/dao/ResourceLimitDaoImpl.java diff --git a/server/src/com/cloud/dc/AccountVlanMapVO.java b/engine/schema/src/com/cloud/dc/AccountVlanMapVO.java similarity index 100% rename from server/src/com/cloud/dc/AccountVlanMapVO.java rename to engine/schema/src/com/cloud/dc/AccountVlanMapVO.java diff --git a/server/src/com/cloud/dc/ClusterDetailsDao.java b/engine/schema/src/com/cloud/dc/ClusterDetailsDao.java similarity index 100% rename from server/src/com/cloud/dc/ClusterDetailsDao.java rename to engine/schema/src/com/cloud/dc/ClusterDetailsDao.java diff --git a/server/src/com/cloud/dc/ClusterDetailsDaoImpl.java b/engine/schema/src/com/cloud/dc/ClusterDetailsDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/ClusterDetailsDaoImpl.java rename to engine/schema/src/com/cloud/dc/ClusterDetailsDaoImpl.java diff --git a/server/src/com/cloud/dc/ClusterDetailsVO.java b/engine/schema/src/com/cloud/dc/ClusterDetailsVO.java similarity index 100% rename from server/src/com/cloud/dc/ClusterDetailsVO.java rename to engine/schema/src/com/cloud/dc/ClusterDetailsVO.java diff --git a/server/src/com/cloud/dc/ClusterVO.java b/engine/schema/src/com/cloud/dc/ClusterVO.java similarity index 100% rename from server/src/com/cloud/dc/ClusterVO.java rename to engine/schema/src/com/cloud/dc/ClusterVO.java diff --git a/server/src/com/cloud/dc/ClusterVSMMapVO.java b/engine/schema/src/com/cloud/dc/ClusterVSMMapVO.java similarity index 100% rename from server/src/com/cloud/dc/ClusterVSMMapVO.java rename to engine/schema/src/com/cloud/dc/ClusterVSMMapVO.java diff --git a/server/src/com/cloud/dc/DataCenterIpAddressVO.java b/engine/schema/src/com/cloud/dc/DataCenterIpAddressVO.java similarity index 100% rename from server/src/com/cloud/dc/DataCenterIpAddressVO.java rename to engine/schema/src/com/cloud/dc/DataCenterIpAddressVO.java diff --git a/server/src/com/cloud/dc/DataCenterLinkLocalIpAddressVO.java b/engine/schema/src/com/cloud/dc/DataCenterLinkLocalIpAddressVO.java similarity index 100% rename from server/src/com/cloud/dc/DataCenterLinkLocalIpAddressVO.java rename to engine/schema/src/com/cloud/dc/DataCenterLinkLocalIpAddressVO.java diff --git a/server/src/com/cloud/dc/DataCenterVO.java b/engine/schema/src/com/cloud/dc/DataCenterVO.java similarity index 100% rename from server/src/com/cloud/dc/DataCenterVO.java rename to engine/schema/src/com/cloud/dc/DataCenterVO.java diff --git a/server/src/com/cloud/dc/DataCenterVnetVO.java b/engine/schema/src/com/cloud/dc/DataCenterVnetVO.java similarity index 100% rename from server/src/com/cloud/dc/DataCenterVnetVO.java rename to engine/schema/src/com/cloud/dc/DataCenterVnetVO.java diff --git a/server/src/com/cloud/dc/DcDetailVO.java b/engine/schema/src/com/cloud/dc/DcDetailVO.java similarity index 100% rename from server/src/com/cloud/dc/DcDetailVO.java rename to engine/schema/src/com/cloud/dc/DcDetailVO.java diff --git a/server/src/com/cloud/dc/HostPodVO.java b/engine/schema/src/com/cloud/dc/HostPodVO.java similarity index 100% rename from server/src/com/cloud/dc/HostPodVO.java rename to engine/schema/src/com/cloud/dc/HostPodVO.java diff --git a/server/src/com/cloud/dc/PodCluster.java b/engine/schema/src/com/cloud/dc/PodCluster.java similarity index 100% rename from server/src/com/cloud/dc/PodCluster.java rename to engine/schema/src/com/cloud/dc/PodCluster.java diff --git a/server/src/com/cloud/dc/PodVlanMapVO.java b/engine/schema/src/com/cloud/dc/PodVlanMapVO.java similarity index 100% rename from server/src/com/cloud/dc/PodVlanMapVO.java rename to engine/schema/src/com/cloud/dc/PodVlanMapVO.java diff --git a/server/src/com/cloud/dc/PodVlanVO.java b/engine/schema/src/com/cloud/dc/PodVlanVO.java similarity index 100% rename from server/src/com/cloud/dc/PodVlanVO.java rename to engine/schema/src/com/cloud/dc/PodVlanVO.java diff --git a/server/src/com/cloud/dc/StorageNetworkIpAddressVO.java b/engine/schema/src/com/cloud/dc/StorageNetworkIpAddressVO.java similarity index 100% rename from server/src/com/cloud/dc/StorageNetworkIpAddressVO.java rename to engine/schema/src/com/cloud/dc/StorageNetworkIpAddressVO.java diff --git a/server/src/com/cloud/dc/StorageNetworkIpRangeVO.java b/engine/schema/src/com/cloud/dc/StorageNetworkIpRangeVO.java similarity index 100% rename from server/src/com/cloud/dc/StorageNetworkIpRangeVO.java rename to engine/schema/src/com/cloud/dc/StorageNetworkIpRangeVO.java diff --git a/server/src/com/cloud/dc/VlanVO.java b/engine/schema/src/com/cloud/dc/VlanVO.java similarity index 100% rename from server/src/com/cloud/dc/VlanVO.java rename to engine/schema/src/com/cloud/dc/VlanVO.java diff --git a/server/src/com/cloud/dc/dao/AccountVlanMapDao.java b/engine/schema/src/com/cloud/dc/dao/AccountVlanMapDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/AccountVlanMapDao.java rename to engine/schema/src/com/cloud/dc/dao/AccountVlanMapDao.java diff --git a/server/src/com/cloud/dc/dao/AccountVlanMapDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/AccountVlanMapDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/AccountVlanMapDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/AccountVlanMapDaoImpl.java diff --git a/server/src/com/cloud/dc/dao/ClusterDao.java b/engine/schema/src/com/cloud/dc/dao/ClusterDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/ClusterDao.java rename to engine/schema/src/com/cloud/dc/dao/ClusterDao.java diff --git a/server/src/com/cloud/dc/dao/ClusterDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/ClusterDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java diff --git a/server/src/com/cloud/dc/dao/ClusterVSMMapDao.java b/engine/schema/src/com/cloud/dc/dao/ClusterVSMMapDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/ClusterVSMMapDao.java rename to engine/schema/src/com/cloud/dc/dao/ClusterVSMMapDao.java diff --git a/server/src/com/cloud/dc/dao/ClusterVSMMapDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/ClusterVSMMapDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/ClusterVSMMapDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/ClusterVSMMapDaoImpl.java diff --git a/server/src/com/cloud/dc/dao/DataCenterDao.java b/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/DataCenterDao.java rename to engine/schema/src/com/cloud/dc/dao/DataCenterDao.java diff --git a/server/src/com/cloud/dc/dao/DataCenterDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/DataCenterDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java diff --git a/server/src/com/cloud/dc/dao/DataCenterIpAddressDao.java b/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/DataCenterIpAddressDao.java rename to engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDao.java diff --git a/server/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java diff --git a/server/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDao.java b/engine/schema/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDao.java rename to engine/schema/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDao.java diff --git a/server/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDaoImpl.java diff --git a/server/src/com/cloud/dc/dao/DataCenterVnetDao.java b/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/DataCenterVnetDao.java rename to engine/schema/src/com/cloud/dc/dao/DataCenterVnetDao.java diff --git a/server/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java diff --git a/server/src/com/cloud/dc/dao/DcDetailsDao.java b/engine/schema/src/com/cloud/dc/dao/DcDetailsDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/DcDetailsDao.java rename to engine/schema/src/com/cloud/dc/dao/DcDetailsDao.java diff --git a/server/src/com/cloud/dc/dao/DcDetailsDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DcDetailsDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/DcDetailsDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/DcDetailsDaoImpl.java diff --git a/server/src/com/cloud/dc/dao/HostPodDao.java b/engine/schema/src/com/cloud/dc/dao/HostPodDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/HostPodDao.java rename to engine/schema/src/com/cloud/dc/dao/HostPodDao.java diff --git a/server/src/com/cloud/dc/dao/HostPodDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/HostPodDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java diff --git a/server/src/com/cloud/dc/dao/PodVlanDao.java b/engine/schema/src/com/cloud/dc/dao/PodVlanDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/PodVlanDao.java rename to engine/schema/src/com/cloud/dc/dao/PodVlanDao.java diff --git a/server/src/com/cloud/dc/dao/PodVlanDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/PodVlanDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/PodVlanDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/PodVlanDaoImpl.java diff --git a/server/src/com/cloud/dc/dao/PodVlanMapDao.java b/engine/schema/src/com/cloud/dc/dao/PodVlanMapDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/PodVlanMapDao.java rename to engine/schema/src/com/cloud/dc/dao/PodVlanMapDao.java diff --git a/server/src/com/cloud/dc/dao/PodVlanMapDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/PodVlanMapDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/PodVlanMapDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/PodVlanMapDaoImpl.java diff --git a/server/src/com/cloud/dc/dao/StorageNetworkIpAddressDao.java b/engine/schema/src/com/cloud/dc/dao/StorageNetworkIpAddressDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/StorageNetworkIpAddressDao.java rename to engine/schema/src/com/cloud/dc/dao/StorageNetworkIpAddressDao.java diff --git a/server/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java diff --git a/server/src/com/cloud/dc/dao/StorageNetworkIpRangeDao.java b/engine/schema/src/com/cloud/dc/dao/StorageNetworkIpRangeDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/StorageNetworkIpRangeDao.java rename to engine/schema/src/com/cloud/dc/dao/StorageNetworkIpRangeDao.java diff --git a/server/src/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java diff --git a/server/src/com/cloud/dc/dao/VlanDao.java b/engine/schema/src/com/cloud/dc/dao/VlanDao.java similarity index 100% rename from server/src/com/cloud/dc/dao/VlanDao.java rename to engine/schema/src/com/cloud/dc/dao/VlanDao.java diff --git a/server/src/com/cloud/dc/dao/VlanDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java similarity index 100% rename from server/src/com/cloud/dc/dao/VlanDaoImpl.java rename to engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java diff --git a/server/src/com/cloud/domain/DomainVO.java b/engine/schema/src/com/cloud/domain/DomainVO.java similarity index 100% rename from server/src/com/cloud/domain/DomainVO.java rename to engine/schema/src/com/cloud/domain/DomainVO.java diff --git a/server/src/com/cloud/domain/dao/DomainDao.java b/engine/schema/src/com/cloud/domain/dao/DomainDao.java similarity index 100% rename from server/src/com/cloud/domain/dao/DomainDao.java rename to engine/schema/src/com/cloud/domain/dao/DomainDao.java diff --git a/server/src/com/cloud/domain/dao/DomainDaoImpl.java b/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java similarity index 100% rename from server/src/com/cloud/domain/dao/DomainDaoImpl.java rename to engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java diff --git a/server/src/com/cloud/host/dao/HostDao.java b/engine/schema/src/com/cloud/host/dao/HostDao.java similarity index 100% rename from server/src/com/cloud/host/dao/HostDao.java rename to engine/schema/src/com/cloud/host/dao/HostDao.java diff --git a/server/src/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java similarity index 100% rename from server/src/com/cloud/host/dao/HostDaoImpl.java rename to engine/schema/src/com/cloud/host/dao/HostDaoImpl.java diff --git a/server/src/com/cloud/host/dao/HostDetailsDao.java b/engine/schema/src/com/cloud/host/dao/HostDetailsDao.java similarity index 100% rename from server/src/com/cloud/host/dao/HostDetailsDao.java rename to engine/schema/src/com/cloud/host/dao/HostDetailsDao.java diff --git a/server/src/com/cloud/host/dao/HostDetailsDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDetailsDaoImpl.java similarity index 100% rename from server/src/com/cloud/host/dao/HostDetailsDaoImpl.java rename to engine/schema/src/com/cloud/host/dao/HostDetailsDaoImpl.java diff --git a/server/src/com/cloud/host/dao/HostTagsDao.java b/engine/schema/src/com/cloud/host/dao/HostTagsDao.java similarity index 100% rename from server/src/com/cloud/host/dao/HostTagsDao.java rename to engine/schema/src/com/cloud/host/dao/HostTagsDao.java diff --git a/server/src/com/cloud/host/dao/HostTagsDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostTagsDaoImpl.java similarity index 100% rename from server/src/com/cloud/host/dao/HostTagsDaoImpl.java rename to engine/schema/src/com/cloud/host/dao/HostTagsDaoImpl.java diff --git a/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java b/engine/schema/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java similarity index 100% rename from server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java rename to engine/schema/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java diff --git a/server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java b/engine/schema/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java similarity index 100% rename from server/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java rename to engine/schema/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java diff --git a/server/src/com/cloud/keystore/KeystoreDao.java b/engine/schema/src/com/cloud/keystore/KeystoreDao.java similarity index 100% rename from server/src/com/cloud/keystore/KeystoreDao.java rename to engine/schema/src/com/cloud/keystore/KeystoreDao.java diff --git a/server/src/com/cloud/keystore/KeystoreDaoImpl.java b/engine/schema/src/com/cloud/keystore/KeystoreDaoImpl.java similarity index 100% rename from server/src/com/cloud/keystore/KeystoreDaoImpl.java rename to engine/schema/src/com/cloud/keystore/KeystoreDaoImpl.java diff --git a/server/src/com/cloud/keystore/KeystoreVO.java b/engine/schema/src/com/cloud/keystore/KeystoreVO.java similarity index 100% rename from server/src/com/cloud/keystore/KeystoreVO.java rename to engine/schema/src/com/cloud/keystore/KeystoreVO.java diff --git a/server/src/com/cloud/migration/DiskOffering20Dao.java b/engine/schema/src/com/cloud/migration/DiskOffering20Dao.java similarity index 100% rename from server/src/com/cloud/migration/DiskOffering20Dao.java rename to engine/schema/src/com/cloud/migration/DiskOffering20Dao.java diff --git a/server/src/com/cloud/migration/DiskOffering20DaoImpl.java b/engine/schema/src/com/cloud/migration/DiskOffering20DaoImpl.java similarity index 100% rename from server/src/com/cloud/migration/DiskOffering20DaoImpl.java rename to engine/schema/src/com/cloud/migration/DiskOffering20DaoImpl.java diff --git a/server/src/com/cloud/migration/DiskOffering20VO.java b/engine/schema/src/com/cloud/migration/DiskOffering20VO.java similarity index 100% rename from server/src/com/cloud/migration/DiskOffering20VO.java rename to engine/schema/src/com/cloud/migration/DiskOffering20VO.java diff --git a/server/src/com/cloud/migration/DiskOffering21Dao.java b/engine/schema/src/com/cloud/migration/DiskOffering21Dao.java similarity index 100% rename from server/src/com/cloud/migration/DiskOffering21Dao.java rename to engine/schema/src/com/cloud/migration/DiskOffering21Dao.java diff --git a/server/src/com/cloud/migration/DiskOffering21DaoImpl.java b/engine/schema/src/com/cloud/migration/DiskOffering21DaoImpl.java similarity index 100% rename from server/src/com/cloud/migration/DiskOffering21DaoImpl.java rename to engine/schema/src/com/cloud/migration/DiskOffering21DaoImpl.java diff --git a/server/src/com/cloud/migration/DiskOffering21VO.java b/engine/schema/src/com/cloud/migration/DiskOffering21VO.java similarity index 100% rename from server/src/com/cloud/migration/DiskOffering21VO.java rename to engine/schema/src/com/cloud/migration/DiskOffering21VO.java diff --git a/server/src/com/cloud/migration/ServiceOffering20Dao.java b/engine/schema/src/com/cloud/migration/ServiceOffering20Dao.java similarity index 100% rename from server/src/com/cloud/migration/ServiceOffering20Dao.java rename to engine/schema/src/com/cloud/migration/ServiceOffering20Dao.java diff --git a/server/src/com/cloud/migration/ServiceOffering20DaoImpl.java b/engine/schema/src/com/cloud/migration/ServiceOffering20DaoImpl.java similarity index 100% rename from server/src/com/cloud/migration/ServiceOffering20DaoImpl.java rename to engine/schema/src/com/cloud/migration/ServiceOffering20DaoImpl.java diff --git a/server/src/com/cloud/migration/ServiceOffering20VO.java b/engine/schema/src/com/cloud/migration/ServiceOffering20VO.java similarity index 100% rename from server/src/com/cloud/migration/ServiceOffering20VO.java rename to engine/schema/src/com/cloud/migration/ServiceOffering20VO.java diff --git a/server/src/com/cloud/migration/ServiceOffering21Dao.java b/engine/schema/src/com/cloud/migration/ServiceOffering21Dao.java similarity index 100% rename from server/src/com/cloud/migration/ServiceOffering21Dao.java rename to engine/schema/src/com/cloud/migration/ServiceOffering21Dao.java diff --git a/server/src/com/cloud/migration/ServiceOffering21DaoImpl.java b/engine/schema/src/com/cloud/migration/ServiceOffering21DaoImpl.java similarity index 100% rename from server/src/com/cloud/migration/ServiceOffering21DaoImpl.java rename to engine/schema/src/com/cloud/migration/ServiceOffering21DaoImpl.java diff --git a/server/src/com/cloud/migration/ServiceOffering21VO.java b/engine/schema/src/com/cloud/migration/ServiceOffering21VO.java similarity index 100% rename from server/src/com/cloud/migration/ServiceOffering21VO.java rename to engine/schema/src/com/cloud/migration/ServiceOffering21VO.java diff --git a/server/src/com/cloud/network/LBHealthCheckPolicyVO.java b/engine/schema/src/com/cloud/network/LBHealthCheckPolicyVO.java similarity index 100% rename from server/src/com/cloud/network/LBHealthCheckPolicyVO.java rename to engine/schema/src/com/cloud/network/LBHealthCheckPolicyVO.java diff --git a/server/src/com/cloud/network/UserIpv6AddressVO.java b/engine/schema/src/com/cloud/network/UserIpv6AddressVO.java similarity index 100% rename from server/src/com/cloud/network/UserIpv6AddressVO.java rename to engine/schema/src/com/cloud/network/UserIpv6AddressVO.java diff --git a/server/src/com/cloud/network/as/AutoScalePolicyConditionMapVO.java b/engine/schema/src/com/cloud/network/as/AutoScalePolicyConditionMapVO.java similarity index 100% rename from server/src/com/cloud/network/as/AutoScalePolicyConditionMapVO.java rename to engine/schema/src/com/cloud/network/as/AutoScalePolicyConditionMapVO.java diff --git a/server/src/com/cloud/network/as/AutoScalePolicyVO.java b/engine/schema/src/com/cloud/network/as/AutoScalePolicyVO.java similarity index 100% rename from server/src/com/cloud/network/as/AutoScalePolicyVO.java rename to engine/schema/src/com/cloud/network/as/AutoScalePolicyVO.java diff --git a/server/src/com/cloud/network/as/AutoScaleVmGroupPolicyMapVO.java b/engine/schema/src/com/cloud/network/as/AutoScaleVmGroupPolicyMapVO.java similarity index 100% rename from server/src/com/cloud/network/as/AutoScaleVmGroupPolicyMapVO.java rename to engine/schema/src/com/cloud/network/as/AutoScaleVmGroupPolicyMapVO.java diff --git a/server/src/com/cloud/network/as/AutoScaleVmGroupVO.java b/engine/schema/src/com/cloud/network/as/AutoScaleVmGroupVO.java similarity index 100% rename from server/src/com/cloud/network/as/AutoScaleVmGroupVO.java rename to engine/schema/src/com/cloud/network/as/AutoScaleVmGroupVO.java diff --git a/server/src/com/cloud/network/as/AutoScaleVmProfileVO.java b/engine/schema/src/com/cloud/network/as/AutoScaleVmProfileVO.java similarity index 100% rename from server/src/com/cloud/network/as/AutoScaleVmProfileVO.java rename to engine/schema/src/com/cloud/network/as/AutoScaleVmProfileVO.java diff --git a/server/src/com/cloud/network/as/ConditionVO.java b/engine/schema/src/com/cloud/network/as/ConditionVO.java similarity index 100% rename from server/src/com/cloud/network/as/ConditionVO.java rename to engine/schema/src/com/cloud/network/as/ConditionVO.java diff --git a/server/src/com/cloud/network/as/CounterVO.java b/engine/schema/src/com/cloud/network/as/CounterVO.java similarity index 100% rename from server/src/com/cloud/network/as/CounterVO.java rename to engine/schema/src/com/cloud/network/as/CounterVO.java diff --git a/server/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDao.java b/engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDao.java similarity index 100% rename from server/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDao.java rename to engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDao.java diff --git a/server/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDaoImpl.java b/engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDaoImpl.java rename to engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDaoImpl.java diff --git a/server/src/com/cloud/network/as/dao/AutoScalePolicyDao.java b/engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyDao.java similarity index 100% rename from server/src/com/cloud/network/as/dao/AutoScalePolicyDao.java rename to engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyDao.java diff --git a/server/src/com/cloud/network/as/dao/AutoScalePolicyDaoImpl.java b/engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/as/dao/AutoScalePolicyDaoImpl.java rename to engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyDaoImpl.java diff --git a/server/src/com/cloud/network/as/dao/AutoScaleVmGroupDao.java b/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupDao.java similarity index 100% rename from server/src/com/cloud/network/as/dao/AutoScaleVmGroupDao.java rename to engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupDao.java diff --git a/server/src/com/cloud/network/as/dao/AutoScaleVmGroupDaoImpl.java b/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/as/dao/AutoScaleVmGroupDaoImpl.java rename to engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupDaoImpl.java diff --git a/server/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDao.java b/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDao.java similarity index 100% rename from server/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDao.java rename to engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDao.java diff --git a/server/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDaoImpl.java b/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDaoImpl.java rename to engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDaoImpl.java diff --git a/server/src/com/cloud/network/as/dao/AutoScaleVmProfileDao.java b/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmProfileDao.java similarity index 100% rename from server/src/com/cloud/network/as/dao/AutoScaleVmProfileDao.java rename to engine/schema/src/com/cloud/network/as/dao/AutoScaleVmProfileDao.java diff --git a/server/src/com/cloud/network/as/dao/AutoScaleVmProfileDaoImpl.java b/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmProfileDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/as/dao/AutoScaleVmProfileDaoImpl.java rename to engine/schema/src/com/cloud/network/as/dao/AutoScaleVmProfileDaoImpl.java diff --git a/server/src/com/cloud/network/as/dao/ConditionDao.java b/engine/schema/src/com/cloud/network/as/dao/ConditionDao.java similarity index 100% rename from server/src/com/cloud/network/as/dao/ConditionDao.java rename to engine/schema/src/com/cloud/network/as/dao/ConditionDao.java diff --git a/server/src/com/cloud/network/as/dao/ConditionDaoImpl.java b/engine/schema/src/com/cloud/network/as/dao/ConditionDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/as/dao/ConditionDaoImpl.java rename to engine/schema/src/com/cloud/network/as/dao/ConditionDaoImpl.java diff --git a/server/src/com/cloud/network/as/dao/CounterDao.java b/engine/schema/src/com/cloud/network/as/dao/CounterDao.java similarity index 100% rename from server/src/com/cloud/network/as/dao/CounterDao.java rename to engine/schema/src/com/cloud/network/as/dao/CounterDao.java diff --git a/server/src/com/cloud/network/as/dao/CounterDaoImpl.java b/engine/schema/src/com/cloud/network/as/dao/CounterDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/as/dao/CounterDaoImpl.java rename to engine/schema/src/com/cloud/network/as/dao/CounterDaoImpl.java diff --git a/server/src/com/cloud/network/dao/ExternalFirewallDeviceDao.java b/engine/schema/src/com/cloud/network/dao/ExternalFirewallDeviceDao.java similarity index 100% rename from server/src/com/cloud/network/dao/ExternalFirewallDeviceDao.java rename to engine/schema/src/com/cloud/network/dao/ExternalFirewallDeviceDao.java diff --git a/server/src/com/cloud/network/dao/ExternalFirewallDeviceDaoImpl.java b/engine/schema/src/com/cloud/network/dao/ExternalFirewallDeviceDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/ExternalFirewallDeviceDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/ExternalFirewallDeviceDaoImpl.java diff --git a/server/src/com/cloud/network/dao/ExternalFirewallDeviceVO.java b/engine/schema/src/com/cloud/network/dao/ExternalFirewallDeviceVO.java similarity index 100% rename from server/src/com/cloud/network/dao/ExternalFirewallDeviceVO.java rename to engine/schema/src/com/cloud/network/dao/ExternalFirewallDeviceVO.java diff --git a/server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDao.java b/engine/schema/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDao.java similarity index 100% rename from server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDao.java rename to engine/schema/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDao.java diff --git a/server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDaoImpl.java b/engine/schema/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDaoImpl.java diff --git a/server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceVO.java b/engine/schema/src/com/cloud/network/dao/ExternalLoadBalancerDeviceVO.java similarity index 100% rename from server/src/com/cloud/network/dao/ExternalLoadBalancerDeviceVO.java rename to engine/schema/src/com/cloud/network/dao/ExternalLoadBalancerDeviceVO.java diff --git a/server/src/com/cloud/network/dao/FirewallRulesCidrsDao.java b/engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsDao.java similarity index 100% rename from server/src/com/cloud/network/dao/FirewallRulesCidrsDao.java rename to engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsDao.java diff --git a/server/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java b/engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java diff --git a/server/src/com/cloud/network/dao/FirewallRulesCidrsVO.java b/engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsVO.java similarity index 100% rename from server/src/com/cloud/network/dao/FirewallRulesCidrsVO.java rename to engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsVO.java diff --git a/server/src/com/cloud/network/dao/FirewallRulesDao.java b/engine/schema/src/com/cloud/network/dao/FirewallRulesDao.java similarity index 100% rename from server/src/com/cloud/network/dao/FirewallRulesDao.java rename to engine/schema/src/com/cloud/network/dao/FirewallRulesDao.java diff --git a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java b/engine/schema/src/com/cloud/network/dao/FirewallRulesDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/FirewallRulesDaoImpl.java diff --git a/server/src/com/cloud/network/dao/IPAddressDao.java b/engine/schema/src/com/cloud/network/dao/IPAddressDao.java similarity index 100% rename from server/src/com/cloud/network/dao/IPAddressDao.java rename to engine/schema/src/com/cloud/network/dao/IPAddressDao.java diff --git a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java b/engine/schema/src/com/cloud/network/dao/IPAddressDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/IPAddressDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/IPAddressDaoImpl.java diff --git a/server/src/com/cloud/network/dao/IPAddressVO.java b/engine/schema/src/com/cloud/network/dao/IPAddressVO.java similarity index 100% rename from server/src/com/cloud/network/dao/IPAddressVO.java rename to engine/schema/src/com/cloud/network/dao/IPAddressVO.java diff --git a/server/src/com/cloud/network/dao/InlineLoadBalancerNicMapDao.java b/engine/schema/src/com/cloud/network/dao/InlineLoadBalancerNicMapDao.java similarity index 100% rename from server/src/com/cloud/network/dao/InlineLoadBalancerNicMapDao.java rename to engine/schema/src/com/cloud/network/dao/InlineLoadBalancerNicMapDao.java diff --git a/server/src/com/cloud/network/dao/InlineLoadBalancerNicMapDaoImpl.java b/engine/schema/src/com/cloud/network/dao/InlineLoadBalancerNicMapDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/InlineLoadBalancerNicMapDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/InlineLoadBalancerNicMapDaoImpl.java diff --git a/server/src/com/cloud/network/dao/InlineLoadBalancerNicMapVO.java b/engine/schema/src/com/cloud/network/dao/InlineLoadBalancerNicMapVO.java similarity index 100% rename from server/src/com/cloud/network/dao/InlineLoadBalancerNicMapVO.java rename to engine/schema/src/com/cloud/network/dao/InlineLoadBalancerNicMapVO.java diff --git a/server/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java b/engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java similarity index 100% rename from server/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java rename to engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java diff --git a/server/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java b/engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java diff --git a/server/src/com/cloud/network/dao/LBStickinessPolicyDao.java b/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDao.java similarity index 100% rename from server/src/com/cloud/network/dao/LBStickinessPolicyDao.java rename to engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDao.java diff --git a/server/src/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java b/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java diff --git a/server/src/com/cloud/network/dao/LBStickinessPolicyVO.java b/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyVO.java similarity index 100% rename from server/src/com/cloud/network/dao/LBStickinessPolicyVO.java rename to engine/schema/src/com/cloud/network/dao/LBStickinessPolicyVO.java diff --git a/server/src/com/cloud/network/dao/LoadBalancerDao.java b/engine/schema/src/com/cloud/network/dao/LoadBalancerDao.java similarity index 100% rename from server/src/com/cloud/network/dao/LoadBalancerDao.java rename to engine/schema/src/com/cloud/network/dao/LoadBalancerDao.java diff --git a/server/src/com/cloud/network/dao/LoadBalancerDaoImpl.java b/engine/schema/src/com/cloud/network/dao/LoadBalancerDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/LoadBalancerDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/LoadBalancerDaoImpl.java diff --git a/server/src/com/cloud/network/dao/LoadBalancerVMMapDao.java b/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDao.java similarity index 100% rename from server/src/com/cloud/network/dao/LoadBalancerVMMapDao.java rename to engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDao.java diff --git a/server/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java b/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java diff --git a/server/src/com/cloud/network/dao/LoadBalancerVMMapVO.java b/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapVO.java similarity index 100% rename from server/src/com/cloud/network/dao/LoadBalancerVMMapVO.java rename to engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapVO.java diff --git a/server/src/com/cloud/network/dao/LoadBalancerVO.java b/engine/schema/src/com/cloud/network/dao/LoadBalancerVO.java similarity index 100% rename from server/src/com/cloud/network/dao/LoadBalancerVO.java rename to engine/schema/src/com/cloud/network/dao/LoadBalancerVO.java diff --git a/server/src/com/cloud/network/dao/NetworkAccountDao.java b/engine/schema/src/com/cloud/network/dao/NetworkAccountDao.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkAccountDao.java rename to engine/schema/src/com/cloud/network/dao/NetworkAccountDao.java diff --git a/server/src/com/cloud/network/dao/NetworkAccountDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkAccountDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkAccountDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/NetworkAccountDaoImpl.java diff --git a/server/src/com/cloud/network/dao/NetworkAccountVO.java b/engine/schema/src/com/cloud/network/dao/NetworkAccountVO.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkAccountVO.java rename to engine/schema/src/com/cloud/network/dao/NetworkAccountVO.java diff --git a/server/src/com/cloud/network/dao/NetworkDao.java b/engine/schema/src/com/cloud/network/dao/NetworkDao.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkDao.java rename to engine/schema/src/com/cloud/network/dao/NetworkDao.java diff --git a/server/src/com/cloud/network/dao/NetworkDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java diff --git a/server/src/com/cloud/network/dao/NetworkDomainDao.java b/engine/schema/src/com/cloud/network/dao/NetworkDomainDao.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkDomainDao.java rename to engine/schema/src/com/cloud/network/dao/NetworkDomainDao.java diff --git a/server/src/com/cloud/network/dao/NetworkDomainDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkDomainDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkDomainDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/NetworkDomainDaoImpl.java diff --git a/server/src/com/cloud/network/dao/NetworkDomainVO.java b/engine/schema/src/com/cloud/network/dao/NetworkDomainVO.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkDomainVO.java rename to engine/schema/src/com/cloud/network/dao/NetworkDomainVO.java diff --git a/server/src/com/cloud/network/dao/NetworkExternalFirewallDao.java b/engine/schema/src/com/cloud/network/dao/NetworkExternalFirewallDao.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkExternalFirewallDao.java rename to engine/schema/src/com/cloud/network/dao/NetworkExternalFirewallDao.java diff --git a/server/src/com/cloud/network/dao/NetworkExternalFirewallDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkExternalFirewallDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkExternalFirewallDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/NetworkExternalFirewallDaoImpl.java diff --git a/server/src/com/cloud/network/dao/NetworkExternalFirewallVO.java b/engine/schema/src/com/cloud/network/dao/NetworkExternalFirewallVO.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkExternalFirewallVO.java rename to engine/schema/src/com/cloud/network/dao/NetworkExternalFirewallVO.java diff --git a/server/src/com/cloud/network/dao/NetworkExternalLoadBalancerDao.java b/engine/schema/src/com/cloud/network/dao/NetworkExternalLoadBalancerDao.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkExternalLoadBalancerDao.java rename to engine/schema/src/com/cloud/network/dao/NetworkExternalLoadBalancerDao.java diff --git a/server/src/com/cloud/network/dao/NetworkExternalLoadBalancerDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkExternalLoadBalancerDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkExternalLoadBalancerDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/NetworkExternalLoadBalancerDaoImpl.java diff --git a/server/src/com/cloud/network/dao/NetworkExternalLoadBalancerVO.java b/engine/schema/src/com/cloud/network/dao/NetworkExternalLoadBalancerVO.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkExternalLoadBalancerVO.java rename to engine/schema/src/com/cloud/network/dao/NetworkExternalLoadBalancerVO.java diff --git a/server/src/com/cloud/network/dao/NetworkOpDao.java b/engine/schema/src/com/cloud/network/dao/NetworkOpDao.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkOpDao.java rename to engine/schema/src/com/cloud/network/dao/NetworkOpDao.java diff --git a/server/src/com/cloud/network/dao/NetworkOpDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkOpDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkOpDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/NetworkOpDaoImpl.java diff --git a/server/src/com/cloud/network/dao/NetworkOpVO.java b/engine/schema/src/com/cloud/network/dao/NetworkOpVO.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkOpVO.java rename to engine/schema/src/com/cloud/network/dao/NetworkOpVO.java diff --git a/server/src/com/cloud/network/dao/NetworkRuleConfigDao.java b/engine/schema/src/com/cloud/network/dao/NetworkRuleConfigDao.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkRuleConfigDao.java rename to engine/schema/src/com/cloud/network/dao/NetworkRuleConfigDao.java diff --git a/server/src/com/cloud/network/dao/NetworkRuleConfigDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkRuleConfigDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkRuleConfigDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/NetworkRuleConfigDaoImpl.java diff --git a/server/src/com/cloud/network/dao/NetworkRuleConfigVO.java b/engine/schema/src/com/cloud/network/dao/NetworkRuleConfigVO.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkRuleConfigVO.java rename to engine/schema/src/com/cloud/network/dao/NetworkRuleConfigVO.java diff --git a/server/src/com/cloud/network/dao/NetworkServiceMapDao.java b/engine/schema/src/com/cloud/network/dao/NetworkServiceMapDao.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkServiceMapDao.java rename to engine/schema/src/com/cloud/network/dao/NetworkServiceMapDao.java diff --git a/server/src/com/cloud/network/dao/NetworkServiceMapDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkServiceMapDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkServiceMapDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/NetworkServiceMapDaoImpl.java diff --git a/server/src/com/cloud/network/dao/NetworkServiceMapVO.java b/engine/schema/src/com/cloud/network/dao/NetworkServiceMapVO.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkServiceMapVO.java rename to engine/schema/src/com/cloud/network/dao/NetworkServiceMapVO.java diff --git a/server/src/com/cloud/network/dao/NetworkVO.java b/engine/schema/src/com/cloud/network/dao/NetworkVO.java similarity index 100% rename from server/src/com/cloud/network/dao/NetworkVO.java rename to engine/schema/src/com/cloud/network/dao/NetworkVO.java diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkDao.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkDao.java similarity index 100% rename from server/src/com/cloud/network/dao/PhysicalNetworkDao.java rename to engine/schema/src/com/cloud/network/dao/PhysicalNetworkDao.java diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkDaoImpl.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/PhysicalNetworkDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/PhysicalNetworkDaoImpl.java diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodDaoImpl.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodDaoImpl.java diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodVO.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodVO.java similarity index 100% rename from server/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodVO.java rename to engine/schema/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodVO.java diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDao.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDao.java similarity index 100% rename from server/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDao.java rename to engine/schema/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDao.java diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDaoImpl.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDaoImpl.java diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkServiceProviderVO.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkServiceProviderVO.java similarity index 100% rename from server/src/com/cloud/network/dao/PhysicalNetworkServiceProviderVO.java rename to engine/schema/src/com/cloud/network/dao/PhysicalNetworkServiceProviderVO.java diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkTagDaoImpl.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTagDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/PhysicalNetworkTagDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/PhysicalNetworkTagDaoImpl.java diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkTagVO.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTagVO.java similarity index 100% rename from server/src/com/cloud/network/dao/PhysicalNetworkTagVO.java rename to engine/schema/src/com/cloud/network/dao/PhysicalNetworkTagVO.java diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDao.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDao.java similarity index 100% rename from server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDao.java rename to engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDao.java diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java similarity index 100% rename from server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java rename to engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkVO.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkVO.java similarity index 100% rename from server/src/com/cloud/network/dao/PhysicalNetworkVO.java rename to engine/schema/src/com/cloud/network/dao/PhysicalNetworkVO.java diff --git a/server/src/com/cloud/network/dao/PortProfileDao.java b/engine/schema/src/com/cloud/network/dao/PortProfileDao.java similarity index 100% rename from server/src/com/cloud/network/dao/PortProfileDao.java rename to engine/schema/src/com/cloud/network/dao/PortProfileDao.java diff --git a/server/src/com/cloud/network/dao/PortProfileDaoImpl.java b/engine/schema/src/com/cloud/network/dao/PortProfileDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/PortProfileDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/PortProfileDaoImpl.java diff --git a/server/src/com/cloud/network/dao/PortProfileVO.java b/engine/schema/src/com/cloud/network/dao/PortProfileVO.java similarity index 100% rename from server/src/com/cloud/network/dao/PortProfileVO.java rename to engine/schema/src/com/cloud/network/dao/PortProfileVO.java diff --git a/server/src/com/cloud/network/dao/RemoteAccessVpnDao.java b/engine/schema/src/com/cloud/network/dao/RemoteAccessVpnDao.java similarity index 100% rename from server/src/com/cloud/network/dao/RemoteAccessVpnDao.java rename to engine/schema/src/com/cloud/network/dao/RemoteAccessVpnDao.java diff --git a/server/src/com/cloud/network/dao/RemoteAccessVpnDaoImpl.java b/engine/schema/src/com/cloud/network/dao/RemoteAccessVpnDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/RemoteAccessVpnDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/RemoteAccessVpnDaoImpl.java diff --git a/server/src/com/cloud/network/dao/RemoteAccessVpnVO.java b/engine/schema/src/com/cloud/network/dao/RemoteAccessVpnVO.java similarity index 100% rename from server/src/com/cloud/network/dao/RemoteAccessVpnVO.java rename to engine/schema/src/com/cloud/network/dao/RemoteAccessVpnVO.java diff --git a/server/src/com/cloud/network/dao/RouterNetworkDao.java b/engine/schema/src/com/cloud/network/dao/RouterNetworkDao.java similarity index 100% rename from server/src/com/cloud/network/dao/RouterNetworkDao.java rename to engine/schema/src/com/cloud/network/dao/RouterNetworkDao.java diff --git a/server/src/com/cloud/network/dao/RouterNetworkDaoImpl.java b/engine/schema/src/com/cloud/network/dao/RouterNetworkDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/RouterNetworkDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/RouterNetworkDaoImpl.java diff --git a/server/src/com/cloud/network/dao/RouterNetworkVO.java b/engine/schema/src/com/cloud/network/dao/RouterNetworkVO.java similarity index 100% rename from server/src/com/cloud/network/dao/RouterNetworkVO.java rename to engine/schema/src/com/cloud/network/dao/RouterNetworkVO.java diff --git a/server/src/com/cloud/network/dao/Site2SiteCustomerGatewayDao.java b/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayDao.java similarity index 100% rename from server/src/com/cloud/network/dao/Site2SiteCustomerGatewayDao.java rename to engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayDao.java diff --git a/server/src/com/cloud/network/dao/Site2SiteCustomerGatewayDaoImpl.java b/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/Site2SiteCustomerGatewayDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayDaoImpl.java diff --git a/server/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java b/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java similarity index 100% rename from server/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java rename to engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java diff --git a/server/src/com/cloud/network/dao/Site2SiteVpnConnectionDao.java b/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionDao.java similarity index 100% rename from server/src/com/cloud/network/dao/Site2SiteVpnConnectionDao.java rename to engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionDao.java diff --git a/server/src/com/cloud/network/dao/Site2SiteVpnConnectionDaoImpl.java b/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/Site2SiteVpnConnectionDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionDaoImpl.java diff --git a/server/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java b/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java similarity index 100% rename from server/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java rename to engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java diff --git a/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java similarity index 100% rename from server/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java rename to engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java diff --git a/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java b/engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java diff --git a/server/src/com/cloud/network/dao/Site2SiteVpnGatewayVO.java b/engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayVO.java similarity index 100% rename from server/src/com/cloud/network/dao/Site2SiteVpnGatewayVO.java rename to engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayVO.java diff --git a/server/src/com/cloud/network/dao/UserIpv6AddressDao.java b/engine/schema/src/com/cloud/network/dao/UserIpv6AddressDao.java similarity index 100% rename from server/src/com/cloud/network/dao/UserIpv6AddressDao.java rename to engine/schema/src/com/cloud/network/dao/UserIpv6AddressDao.java diff --git a/server/src/com/cloud/network/dao/UserIpv6AddressDaoImpl.java b/engine/schema/src/com/cloud/network/dao/UserIpv6AddressDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/UserIpv6AddressDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/UserIpv6AddressDaoImpl.java diff --git a/server/src/com/cloud/network/dao/VirtualRouterProviderDao.java b/engine/schema/src/com/cloud/network/dao/VirtualRouterProviderDao.java similarity index 100% rename from server/src/com/cloud/network/dao/VirtualRouterProviderDao.java rename to engine/schema/src/com/cloud/network/dao/VirtualRouterProviderDao.java diff --git a/server/src/com/cloud/network/dao/VirtualRouterProviderDaoImpl.java b/engine/schema/src/com/cloud/network/dao/VirtualRouterProviderDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/VirtualRouterProviderDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/VirtualRouterProviderDaoImpl.java diff --git a/server/src/com/cloud/network/dao/VpnUserDao.java b/engine/schema/src/com/cloud/network/dao/VpnUserDao.java similarity index 100% rename from server/src/com/cloud/network/dao/VpnUserDao.java rename to engine/schema/src/com/cloud/network/dao/VpnUserDao.java diff --git a/server/src/com/cloud/network/dao/VpnUserDaoImpl.java b/engine/schema/src/com/cloud/network/dao/VpnUserDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/VpnUserDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/VpnUserDaoImpl.java diff --git a/server/src/com/cloud/network/element/VirtualRouterProviderVO.java b/engine/schema/src/com/cloud/network/element/VirtualRouterProviderVO.java similarity index 100% rename from server/src/com/cloud/network/element/VirtualRouterProviderVO.java rename to engine/schema/src/com/cloud/network/element/VirtualRouterProviderVO.java diff --git a/server/src/com/cloud/network/rules/FirewallRuleVO.java b/engine/schema/src/com/cloud/network/rules/FirewallRuleVO.java similarity index 100% rename from server/src/com/cloud/network/rules/FirewallRuleVO.java rename to engine/schema/src/com/cloud/network/rules/FirewallRuleVO.java diff --git a/server/src/com/cloud/network/rules/PortForwardingRuleVO.java b/engine/schema/src/com/cloud/network/rules/PortForwardingRuleVO.java similarity index 100% rename from server/src/com/cloud/network/rules/PortForwardingRuleVO.java rename to engine/schema/src/com/cloud/network/rules/PortForwardingRuleVO.java diff --git a/server/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java b/engine/schema/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java similarity index 100% rename from server/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java rename to engine/schema/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java diff --git a/server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java b/engine/schema/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java rename to engine/schema/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupDao.java b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupDao.java similarity index 100% rename from server/src/com/cloud/network/security/dao/SecurityGroupDao.java rename to engine/schema/src/com/cloud/network/security/dao/SecurityGroupDao.java diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java rename to engine/schema/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupRuleDao.java b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupRuleDao.java similarity index 100% rename from server/src/com/cloud/network/security/dao/SecurityGroupRuleDao.java rename to engine/schema/src/com/cloud/network/security/dao/SecurityGroupRuleDao.java diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupRuleDaoImpl.java b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupRuleDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/security/dao/SecurityGroupRuleDaoImpl.java rename to engine/schema/src/com/cloud/network/security/dao/SecurityGroupRuleDaoImpl.java diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupRulesDao.java b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupRulesDao.java similarity index 100% rename from server/src/com/cloud/network/security/dao/SecurityGroupRulesDao.java rename to engine/schema/src/com/cloud/network/security/dao/SecurityGroupRulesDao.java diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java rename to engine/schema/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupVMMapDao.java b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupVMMapDao.java similarity index 100% rename from server/src/com/cloud/network/security/dao/SecurityGroupVMMapDao.java rename to engine/schema/src/com/cloud/network/security/dao/SecurityGroupVMMapDao.java diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupVMMapDaoImpl.java b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupVMMapDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/security/dao/SecurityGroupVMMapDaoImpl.java rename to engine/schema/src/com/cloud/network/security/dao/SecurityGroupVMMapDaoImpl.java diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupWorkDao.java b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupWorkDao.java similarity index 100% rename from server/src/com/cloud/network/security/dao/SecurityGroupWorkDao.java rename to engine/schema/src/com/cloud/network/security/dao/SecurityGroupWorkDao.java diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java similarity index 93% rename from server/src/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java rename to engine/schema/src/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java index dcd1238186e..3154ffeb873 100644 --- a/server/src/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java +++ b/engine/schema/src/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java @@ -24,17 +24,16 @@ import javax.ejb.Local; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.ha.HaWorkVO; import com.cloud.network.security.SecurityGroupWork; -import com.cloud.network.security.SecurityGroupWorkVO; import com.cloud.network.security.SecurityGroupWork.Step; +import com.cloud.network.security.SecurityGroupWorkVO; import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -42,12 +41,12 @@ import com.cloud.utils.exception.CloudRuntimeException; public class SecurityGroupWorkDaoImpl extends GenericDaoBase implements SecurityGroupWorkDao { private static final Logger s_logger = Logger.getLogger(SecurityGroupWorkDaoImpl.class); - private SearchBuilder VmIdTakenSearch; - private SearchBuilder VmIdSeqNumSearch; - private SearchBuilder VmIdUnTakenSearch; - private SearchBuilder UntakenWorkSearch; - private SearchBuilder VmIdStepSearch; - private SearchBuilder CleanupSearch; + private final SearchBuilder VmIdTakenSearch; + private final SearchBuilder VmIdSeqNumSearch; + private final SearchBuilder VmIdUnTakenSearch; + private final SearchBuilder UntakenWorkSearch; + private final SearchBuilder VmIdStepSearch; + private final SearchBuilder CleanupSearch; protected SecurityGroupWorkDaoImpl() { @@ -56,38 +55,38 @@ public class SecurityGroupWorkDaoImpl extends GenericDaoBase sc = VmIdSeqNumSearch.create(); sc.setParameters("vmId", vmId); sc.setParameters("seqno", logSequenceNumber); - - final Filter filter = new Filter(HaWorkVO.class, null, true, 0l, 1l); + + final Filter filter = new Filter(SecurityGroupWorkVO.class, null, true, 0l, 1l); final List vos = lockRows(sc, filter, true); if (vos.size() == 0) { @@ -183,7 +182,7 @@ public class SecurityGroupWorkDaoImpl extends GenericDaoBase result = listIncludingRemovedBy(sc); - + return result; } - + @Override public List findAndCleanupUnfinishedWork(Date timeBefore) { final SearchCriteria sc = CleanupSearch.create(); @@ -230,7 +229,7 @@ public class SecurityGroupWorkDaoImpl extends GenericDaoBase findScheduledWork() { final SearchCriteria sc = UntakenWorkSearch.create(); @@ -238,5 +237,5 @@ public class SecurityGroupWorkDaoImpl extends GenericDaoBase> upgradedVersions = new TreeMap>(); diff --git a/server/src/com/cloud/upgrade/PremiumDatabaseUpgradeChecker.java b/engine/schema/src/com/cloud/upgrade/PremiumDatabaseUpgradeChecker.java similarity index 100% rename from server/src/com/cloud/upgrade/PremiumDatabaseUpgradeChecker.java rename to engine/schema/src/com/cloud/upgrade/PremiumDatabaseUpgradeChecker.java diff --git a/server/src/com/cloud/upgrade/dao/DbUpgrade.java b/engine/schema/src/com/cloud/upgrade/dao/DbUpgrade.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/DbUpgrade.java rename to engine/schema/src/com/cloud/upgrade/dao/DbUpgrade.java diff --git a/server/src/com/cloud/upgrade/dao/DbUpgradeUtils.java b/engine/schema/src/com/cloud/upgrade/dao/DbUpgradeUtils.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/DbUpgradeUtils.java rename to engine/schema/src/com/cloud/upgrade/dao/DbUpgradeUtils.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade217to218.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade217to218.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade217to218.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade217to218.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade218to22.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade218to22.java similarity index 99% rename from server/src/com/cloud/upgrade/dao/Upgrade218to22.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade218to22.java index 01fa2cc9cfa..2ef842ac6d2 100644 --- a/server/src/com/cloud/upgrade/dao/Upgrade218to22.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade218to22.java @@ -37,12 +37,9 @@ import java.util.UUID; import org.apache.log4j.Logger; import com.cloud.configuration.Resource.ResourceType; -import com.cloud.consoleproxy.ConsoleProxyManager; import com.cloud.event.EventTypes; import com.cloud.event.EventVO; import com.cloud.event.UsageEventVO; -import com.cloud.network.router.VpcVirtualNetworkApplianceManager; -import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.utils.DateUtil; import com.cloud.utils.NumbersUtil; import com.cloud.utils.exception.CloudRuntimeException; @@ -1146,7 +1143,7 @@ public class Upgrade218to22 implements DbUpgrade { if (!userVmSet.next()) { s_logger.warn("Skipping user_statistics upgrade for account id=" + accountId + " in datacenter id=" + dataCenterId); continue; - } + } deviceId = userVmSet.getLong(1); } else { s_logger.debug("Account id=" + accountId + " doesn't own any user vms and domRs, so skipping user_statistics update"); @@ -1407,9 +1404,9 @@ public class Upgrade218to22 implements DbUpgrade { rs.close(); pstmt.close(); - int proxyRamSize = NumbersUtil.parseInt(getConfigValue(conn, "consoleproxy.ram.size"), ConsoleProxyManager.DEFAULT_PROXY_VM_RAMSIZE); - int domrRamSize = NumbersUtil.parseInt(getConfigValue(conn, "router.ram.size"), VpcVirtualNetworkApplianceManager.DEFAULT_ROUTER_VM_RAMSIZE); - int ssvmRamSize = NumbersUtil.parseInt(getConfigValue(conn, "secstorage.vm.ram.size"), SecondaryStorageVmManager.DEFAULT_SS_VM_RAMSIZE); + int proxyRamSize = NumbersUtil.parseInt(getConfigValue(conn, "consoleproxy.ram.size"), 1024); // ConsoleProxyManager.DEFAULT_PROXY_VM_RAMSIZE); + int domrRamSize = NumbersUtil.parseInt(getConfigValue(conn, "router.ram.size"), 128); // VpcVirtualNetworkApplianceManager.DEFAULT_ROUTER_VM_RAMSIZE); + int ssvmRamSize = NumbersUtil.parseInt(getConfigValue(conn, "secstorage.vm.ram.size"), 256); // SecondaryStorageVmManager.DEFAULT_SS_VM_RAMSIZE); pstmt = conn .prepareStatement("select h.id, count(v.id) from host h, vm_instance v where h.type='Routing' and v.state='Running' and v.`type`='ConsoleProxy' and v.host_id=h.id group by h.id"); @@ -1566,9 +1563,9 @@ public class Upgrade218to22 implements DbUpgrade { rs.close(); pstmt.close(); - int proxyCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "consoleproxy.cpu.mhz"), ConsoleProxyManager.DEFAULT_PROXY_VM_CPUMHZ); - int domrCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "router.cpu.mhz"), VpcVirtualNetworkApplianceManager.DEFAULT_ROUTER_CPU_MHZ); - int ssvmCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "secstorage.vm.cpu.mhz"), SecondaryStorageVmManager.DEFAULT_SS_VM_CPUMHZ); + int proxyCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "consoleproxy.cpu.mhz"), 500); // ConsoleProxyManager.DEFAULT_PROXY_VM_CPUMHZ); + int domrCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "router.cpu.mhz"), 500); // VpcVirtualNetworkApplianceManager.DEFAULT_ROUTER_CPU_MHZ); + int ssvmCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "secstorage.vm.cpu.mhz"), 500); // SecondaryStorageVmManager.DEFAULT_SS_VM_CPUMHZ); pstmt = conn .prepareStatement("select h.id, count(v.id) from host h, vm_instance v where h.type='Routing' and v.state='Running' and v.`type`='ConsoleProxy' and v.host_id=h.id group by h.id"); diff --git a/server/src/com/cloud/upgrade/dao/Upgrade218to224DomainVlans.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade218to224DomainVlans.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade218to224DomainVlans.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade218to224DomainVlans.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade218to22Premium.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade218to22Premium.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade218to22Premium.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade218to22Premium.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade2210to2211.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade2210to2211.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade2210to2211.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade2210to2211.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade2211to2212.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade2211to2212.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade2211to2212.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade2211to2212.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade2211to2212Premium.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade2211to2212Premium.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade2211to2212Premium.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade2211to2212Premium.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade2212to2213.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade2212to2213.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade2212to2213.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade2212to2213.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade2213to2214.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade2213to2214.java similarity index 96% rename from server/src/com/cloud/upgrade/dao/Upgrade2213to2214.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade2213to2214.java index 48b08e41e0a..d3528e3335f 100644 --- a/server/src/com/cloud/upgrade/dao/Upgrade2213to2214.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade2213to2214.java @@ -26,9 +26,9 @@ import java.util.List; import org.apache.log4j.Logger; -import com.cloud.consoleproxy.ConsoleProxyManagerImpl; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; +import com.cloud.vm.ConsoleProxyVO; public class Upgrade2213to2214 implements DbUpgrade { final static Logger s_logger = Logger.getLogger(Upgrade2213to2214.class); @@ -70,13 +70,13 @@ public class Upgrade2213to2214 implements DbUpgrade { if (privateKeyMd5.equalsIgnoreCase("432ea1370f57ccd774f4f36052c5fd73")) { s_logger.debug("Need to upgrade cloudstack provided certificate"); pstmt = conn.prepareStatement("update `cloud`.`keystore` set `cloud`.`keystore`.key = ?, certificate = ? where name = 'CPVMCertificate'"); - pstmt.setString(1, ConsoleProxyManagerImpl.keyContent); - pstmt.setString(2, ConsoleProxyManagerImpl.certContent); + pstmt.setString(1, ConsoleProxyVO.keyContent); + pstmt.setString(2, ConsoleProxyVO.certContent); pstmt.executeUpdate(); - + pstmt = conn.prepareStatement("insert into `cloud`.`keystore` (name, certificate, seq, domain_suffix) VALUES (?,?,?,?)"); pstmt.setString(1, "root"); - pstmt.setString(2, ConsoleProxyManagerImpl.rootCa); + pstmt.setString(2, ConsoleProxyVO.rootCa); pstmt.setInt(3, 0); pstmt.setString(4, "realhostip.com"); pstmt.executeUpdate(); @@ -87,7 +87,7 @@ public class Upgrade2213to2214 implements DbUpgrade { } catch (SQLException e) { s_logger.debug("Failed to upgrade keystore: " + e.toString()); } - + } @Override @@ -162,10 +162,10 @@ public class Upgrade2213to2214 implements DbUpgrade { pstmt.close(); } catch (SQLException e) { throw new CloudRuntimeException("Unable to execute changes for op_vm_ruleset_log", e); - } + } - //Drop i_async__removed, i_async_job__removed (if exists) and add i_async_job__removed + //Drop i_async__removed, i_async_job__removed (if exists) and add i_async_job__removed keys = new ArrayList(); keys.add("i_async__removed"); keys.add("i_async_job__removed"); @@ -177,21 +177,21 @@ public class Upgrade2213to2214 implements DbUpgrade { } catch (SQLException e) { throw new CloudRuntimeException("Unable to insert index for removed column in async_job", e); } - + keys = new ArrayList(); keys.add("fk_ssh_keypair__account_id"); keys.add("fk_ssh_keypair__domain_id"); keys.add("fk_ssh_keypairs__account_id"); keys.add("fk_ssh_keypairs__domain_id"); DbUpgradeUtils.dropKeysIfExist(conn, "ssh_keypairs", keys, true); - + keys = new ArrayList(); keys.add("fk_ssh_keypair__account_id"); keys.add("fk_ssh_keypair__domain_id"); keys.add("fk_ssh_keypairs__account_id"); keys.add("fk_ssh_keypairs__domain_id"); DbUpgradeUtils.dropKeysIfExist(conn, "ssh_keypairs", keys, false); - + try { PreparedStatement pstmt; pstmt = conn.prepareStatement("ALTER TABLE `cloud`.`ssh_keypairs` ADD CONSTRAINT `fk_ssh_keypairs__account_id` FOREIGN KEY `fk_ssh_keypairs__account_id` (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE"); pstmt.executeUpdate(); @@ -199,7 +199,7 @@ public class Upgrade2213to2214 implements DbUpgrade { } catch (SQLException e) { throw new CloudRuntimeException("Unable to execute ssh_keypairs table update for adding account_id foreign key", e); } - + try { PreparedStatement pstmt; pstmt = conn.prepareStatement("ALTER TABLE `cloud`.`ssh_keypairs` ADD CONSTRAINT `fk_ssh_keypairs__domain_id` FOREIGN KEY `fk_ssh_keypairs__domain_id` (`domain_id`) REFERENCES `domain` (`id`) ON DELETE CASCADE"); pstmt.executeUpdate(); @@ -208,7 +208,7 @@ public class Upgrade2213to2214 implements DbUpgrade { throw new CloudRuntimeException("Unable to execute ssh_keypairs table update for adding domain_id foreign key", e); } - //Drop i_async__removed, i_async_job__removed (if exists) and add i_async_job__removed + //Drop i_async__removed, i_async_job__removed (if exists) and add i_async_job__removed keys = new ArrayList(); keys.add("i_async__removed"); keys.add("i_async_job__removed"); @@ -220,7 +220,7 @@ public class Upgrade2213to2214 implements DbUpgrade { } catch (SQLException e) { throw new CloudRuntimeException("Unable to insert index for removed column in async_job", e); } - + //Drop storage pool details keys (if exists) and insert one with correct name keys = new ArrayList(); keys.add("fk_storage_pool__pool_id"); @@ -234,7 +234,7 @@ public class Upgrade2213to2214 implements DbUpgrade { } catch (SQLException e) { throw new CloudRuntimeException("Unable to insert foreign key in storage_pool_details ", e); } - + //Drop securityGroup keys (if exists) and insert one with correct name keys = new ArrayList(); keys.add("fk_security_group___account_id"); @@ -248,21 +248,21 @@ public class Upgrade2213to2214 implements DbUpgrade { } catch (SQLException e) { throw new CloudRuntimeException("Unable to insert foreign key in security_group table ", e); } - + //Drop vmInstance keys (if exists) and insert one with correct name keys = new ArrayList(); keys.add("i_vm_instance__host_id"); keys.add("fk_vm_instance__host_id"); - + keys.add("fk_vm_instance__last_host_id"); keys.add("i_vm_instance__last_host_id"); - + keys.add("fk_vm_instance__service_offering_id"); keys.add("i_vm_instance__service_offering_id"); - + keys.add("fk_vm_instance__account_id"); keys.add("i_vm_instance__account_id"); - + DbUpgradeUtils.dropKeysIfExist(conn, "cloud.vm_instance", keys, true); DbUpgradeUtils.dropKeysIfExist(conn, "cloud.vm_instance", keys, false); try { @@ -278,18 +278,18 @@ public class Upgrade2213to2214 implements DbUpgrade { } catch (SQLException e) { throw new CloudRuntimeException("Unable to insert foreign key in vm_instance table ", e); } - + //Drop user_ip_address keys (if exists) and insert one with correct name keys = new ArrayList(); keys.add("fk_user_ip_address__account_id"); keys.add("i_user_ip_address__account_id"); - + keys.add("fk_user_ip_address__vlan_db_id"); keys.add("i_user_ip_address__vlan_db_id"); - + keys.add("fk_user_ip_address__data_center_id"); keys.add("i_user_ip_address__data_center_id"); - + DbUpgradeUtils.dropKeysIfExist(conn, "cloud.user_ip_address", keys, true); DbUpgradeUtils.dropKeysIfExist(conn, "cloud.user_ip_address", keys, false); try { diff --git a/server/src/com/cloud/upgrade/dao/Upgrade2214to30.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade2214to30.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade2214to30.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade2214to30.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade221to222.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade221to222.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade221to222.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade221to222.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade221to222Premium.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade221to222Premium.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade221to222Premium.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade221to222Premium.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade222to224.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade222to224.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade222to224.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade222to224.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade222to224Premium.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade222to224Premium.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade222to224Premium.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade222to224Premium.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade224to225.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade224to225.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade224to225.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade224to225.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade225to226.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade225to226.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade225to226.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade225to226.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade227to228.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade227to228.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade227to228.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade227to228.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade227to228Premium.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade227to228Premium.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade227to228Premium.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade227to228Premium.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade228to229.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade228to229.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade228to229.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade228to229.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade229to2210.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade229to2210.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade229to2210.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade229to2210.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade301to302.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade301to302.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade301to302.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade301to302.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade302to40.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade302to40.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade302to40.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade302to40.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade30to301.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade30to301.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade30to301.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade30to301.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade30xBase.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade30xBase.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade30xBase.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade30xBase.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade40to41.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade40to41.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade40to41.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade40to41.java diff --git a/server/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/Upgrade410to420.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java diff --git a/server/src/com/cloud/upgrade/dao/UpgradeSnapshot217to224.java b/engine/schema/src/com/cloud/upgrade/dao/UpgradeSnapshot217to224.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/UpgradeSnapshot217to224.java rename to engine/schema/src/com/cloud/upgrade/dao/UpgradeSnapshot217to224.java diff --git a/server/src/com/cloud/upgrade/dao/UpgradeSnapshot223to224.java b/engine/schema/src/com/cloud/upgrade/dao/UpgradeSnapshot223to224.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/UpgradeSnapshot223to224.java rename to engine/schema/src/com/cloud/upgrade/dao/UpgradeSnapshot223to224.java diff --git a/server/src/com/cloud/upgrade/dao/VersionDao.java b/engine/schema/src/com/cloud/upgrade/dao/VersionDao.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/VersionDao.java rename to engine/schema/src/com/cloud/upgrade/dao/VersionDao.java diff --git a/server/src/com/cloud/upgrade/dao/VersionDaoImpl.java b/engine/schema/src/com/cloud/upgrade/dao/VersionDaoImpl.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/VersionDaoImpl.java rename to engine/schema/src/com/cloud/upgrade/dao/VersionDaoImpl.java diff --git a/server/src/com/cloud/upgrade/dao/VersionVO.java b/engine/schema/src/com/cloud/upgrade/dao/VersionVO.java similarity index 100% rename from server/src/com/cloud/upgrade/dao/VersionVO.java rename to engine/schema/src/com/cloud/upgrade/dao/VersionVO.java diff --git a/server/src/com/cloud/usage/ExternalPublicIpStatisticsVO.java b/engine/schema/src/com/cloud/usage/ExternalPublicIpStatisticsVO.java similarity index 100% rename from server/src/com/cloud/usage/ExternalPublicIpStatisticsVO.java rename to engine/schema/src/com/cloud/usage/ExternalPublicIpStatisticsVO.java diff --git a/server/src/com/cloud/usage/UsageIPAddressVO.java b/engine/schema/src/com/cloud/usage/UsageIPAddressVO.java similarity index 100% rename from server/src/com/cloud/usage/UsageIPAddressVO.java rename to engine/schema/src/com/cloud/usage/UsageIPAddressVO.java diff --git a/server/src/com/cloud/usage/UsageJobVO.java b/engine/schema/src/com/cloud/usage/UsageJobVO.java similarity index 100% rename from server/src/com/cloud/usage/UsageJobVO.java rename to engine/schema/src/com/cloud/usage/UsageJobVO.java diff --git a/server/src/com/cloud/usage/UsageLoadBalancerPolicyVO.java b/engine/schema/src/com/cloud/usage/UsageLoadBalancerPolicyVO.java similarity index 100% rename from server/src/com/cloud/usage/UsageLoadBalancerPolicyVO.java rename to engine/schema/src/com/cloud/usage/UsageLoadBalancerPolicyVO.java diff --git a/server/src/com/cloud/usage/UsageNetworkOfferingVO.java b/engine/schema/src/com/cloud/usage/UsageNetworkOfferingVO.java similarity index 100% rename from server/src/com/cloud/usage/UsageNetworkOfferingVO.java rename to engine/schema/src/com/cloud/usage/UsageNetworkOfferingVO.java diff --git a/server/src/com/cloud/usage/UsageNetworkVO.java b/engine/schema/src/com/cloud/usage/UsageNetworkVO.java similarity index 100% rename from server/src/com/cloud/usage/UsageNetworkVO.java rename to engine/schema/src/com/cloud/usage/UsageNetworkVO.java diff --git a/server/src/com/cloud/usage/UsagePortForwardingRuleVO.java b/engine/schema/src/com/cloud/usage/UsagePortForwardingRuleVO.java similarity index 100% rename from server/src/com/cloud/usage/UsagePortForwardingRuleVO.java rename to engine/schema/src/com/cloud/usage/UsagePortForwardingRuleVO.java diff --git a/server/src/com/cloud/usage/UsageSecurityGroupVO.java b/engine/schema/src/com/cloud/usage/UsageSecurityGroupVO.java similarity index 100% rename from server/src/com/cloud/usage/UsageSecurityGroupVO.java rename to engine/schema/src/com/cloud/usage/UsageSecurityGroupVO.java diff --git a/server/src/com/cloud/usage/UsageStorageVO.java b/engine/schema/src/com/cloud/usage/UsageStorageVO.java similarity index 100% rename from server/src/com/cloud/usage/UsageStorageVO.java rename to engine/schema/src/com/cloud/usage/UsageStorageVO.java diff --git a/server/src/com/cloud/usage/UsageVMInstanceVO.java b/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java similarity index 100% rename from server/src/com/cloud/usage/UsageVMInstanceVO.java rename to engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java diff --git a/server/src/com/cloud/usage/UsageVO.java b/engine/schema/src/com/cloud/usage/UsageVO.java similarity index 100% rename from server/src/com/cloud/usage/UsageVO.java rename to engine/schema/src/com/cloud/usage/UsageVO.java diff --git a/server/src/com/cloud/usage/UsageVPNUserVO.java b/engine/schema/src/com/cloud/usage/UsageVPNUserVO.java similarity index 100% rename from server/src/com/cloud/usage/UsageVPNUserVO.java rename to engine/schema/src/com/cloud/usage/UsageVPNUserVO.java diff --git a/server/src/com/cloud/usage/UsageVolumeVO.java b/engine/schema/src/com/cloud/usage/UsageVolumeVO.java similarity index 100% rename from server/src/com/cloud/usage/UsageVolumeVO.java rename to engine/schema/src/com/cloud/usage/UsageVolumeVO.java diff --git a/server/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDao.java b/engine/schema/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDao.java similarity index 100% rename from server/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDao.java rename to engine/schema/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDao.java diff --git a/server/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDaoImpl.java similarity index 100% rename from server/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDaoImpl.java rename to engine/schema/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDaoImpl.java diff --git a/server/src/com/cloud/usage/dao/UsageDao.java b/engine/schema/src/com/cloud/usage/dao/UsageDao.java similarity index 70% rename from server/src/com/cloud/usage/dao/UsageDao.java rename to engine/schema/src/com/cloud/usage/dao/UsageDao.java index a25b0dc78ef..6d0c162b52b 100644 --- a/server/src/com/cloud/usage/dao/UsageDao.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageDao.java @@ -16,11 +16,8 @@ // under the License. package com.cloud.usage.dao; -import java.util.Date; import java.util.List; -import com.cloud.event.UsageEventVO; -import com.cloud.exception.UsageServerException; import com.cloud.usage.UsageVO; import com.cloud.user.AccountVO; import com.cloud.user.UserStatisticsVO; @@ -31,11 +28,12 @@ import com.cloud.utils.db.SearchCriteria; public interface UsageDao extends GenericDao { void deleteRecordsForAccount(Long accountId); List searchAllRecords(SearchCriteria sc, Filter filter); - void saveAccounts(List accounts) throws UsageServerException; - void updateAccounts(List accounts) throws UsageServerException; - void saveUserStats(List userStats) throws UsageServerException; - void updateUserStats(List userStats) throws UsageServerException; - Long getLastAccountId() throws UsageServerException; - Long getLastUserStatsId() throws UsageServerException; + + void saveAccounts(List accounts); + void updateAccounts(List accounts); + void saveUserStats(List userStats); + void updateUserStats(List userStats); + Long getLastAccountId(); + Long getLastUserStatsId(); List listPublicTemplatesByAccount(long accountId); } diff --git a/server/src/com/cloud/usage/dao/UsageDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java similarity index 94% rename from server/src/com/cloud/usage/dao/UsageDaoImpl.java rename to engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java index f9ae70c1f20..a5867f0656e 100644 --- a/server/src/com/cloud/usage/dao/UsageDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java @@ -29,7 +29,6 @@ import javax.ejb.Local; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.exception.UsageServerException; import com.cloud.usage.UsageVO; import com.cloud.user.AccountVO; import com.cloud.user.UserStatisticsVO; @@ -38,6 +37,7 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; @Component @Local(value={UsageDao.class}) @@ -60,7 +60,8 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage public UsageDaoImpl () {} - public void deleteRecordsForAccount(Long accountId) { + @Override + public void deleteRecordsForAccount(Long accountId) { String sql = ((accountId == null) ? DELETE_ALL : DELETE_ALL_BY_ACCOUNTID); Transaction txn = Transaction.open(Transaction.USAGE_DB); PreparedStatement pstmt = null; @@ -86,7 +87,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage } @Override - public void saveAccounts(List accounts) throws UsageServerException { + public void saveAccounts(List accounts) { Transaction txn = Transaction.currentTxn(); try { txn.start(); @@ -115,12 +116,12 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage } catch (Exception ex) { txn.rollback(); s_logger.error("error saving account to cloud_usage db", ex); - throw new UsageServerException(ex.getMessage()); + throw new CloudRuntimeException(ex.getMessage()); } } @Override - public void updateAccounts(List accounts) throws UsageServerException { + public void updateAccounts(List accounts) { Transaction txn = Transaction.currentTxn(); try { txn.start(); @@ -145,12 +146,12 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage } catch (Exception ex) { txn.rollback(); s_logger.error("error saving account to cloud_usage db", ex); - throw new UsageServerException(ex.getMessage()); + throw new CloudRuntimeException(ex.getMessage()); } } @Override - public void saveUserStats(List userStats) throws UsageServerException { + public void saveUserStats(List userStats) { Transaction txn = Transaction.currentTxn(); try { txn.start(); @@ -186,12 +187,12 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage } catch (Exception ex) { txn.rollback(); s_logger.error("error saving user stats to cloud_usage db", ex); - throw new UsageServerException(ex.getMessage()); + throw new CloudRuntimeException(ex.getMessage()); } } @Override - public void updateUserStats(List userStats) throws UsageServerException { + public void updateUserStats(List userStats) { Transaction txn = Transaction.currentTxn(); try { txn.start(); @@ -213,7 +214,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage } catch (Exception ex) { txn.rollback(); s_logger.error("error saving user stats to cloud_usage db", ex); - throw new UsageServerException(ex.getMessage()); + throw new CloudRuntimeException(ex.getMessage()); } } @@ -250,7 +251,7 @@ public class UsageDaoImpl extends GenericDaoBase implements Usage } return null; } - + @Override public List listPublicTemplatesByAccount(long accountId) { Transaction txn = Transaction.currentTxn(); diff --git a/server/src/com/cloud/usage/dao/UsageIPAddressDao.java b/engine/schema/src/com/cloud/usage/dao/UsageIPAddressDao.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageIPAddressDao.java rename to engine/schema/src/com/cloud/usage/dao/UsageIPAddressDao.java diff --git a/server/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java rename to engine/schema/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java diff --git a/server/src/com/cloud/usage/dao/UsageJobDao.java b/engine/schema/src/com/cloud/usage/dao/UsageJobDao.java similarity index 92% rename from server/src/com/cloud/usage/dao/UsageJobDao.java rename to engine/schema/src/com/cloud/usage/dao/UsageJobDao.java index 6921046610b..9ec391804f2 100644 --- a/server/src/com/cloud/usage/dao/UsageJobDao.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageJobDao.java @@ -18,7 +18,6 @@ package com.cloud.usage.dao; import java.util.Date; -import com.cloud.exception.UsageServerException; import com.cloud.usage.UsageJobVO; import com.cloud.utils.db.GenericDao; @@ -30,5 +29,6 @@ public interface UsageJobDao extends GenericDao { long getLastJobSuccessDateMillis(); Date getLastHeartbeat(); UsageJobVO isOwner(String hostname, int pid); - void updateJobSuccess(Long jobId, long startMillis, long endMillis, long execTime, boolean success) throws UsageServerException; + + void updateJobSuccess(Long jobId, long startMillis, long endMillis, long execTime, boolean success); } diff --git a/server/src/com/cloud/usage/dao/UsageJobDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageJobDaoImpl.java similarity index 97% rename from server/src/com/cloud/usage/dao/UsageJobDaoImpl.java rename to engine/schema/src/com/cloud/usage/dao/UsageJobDaoImpl.java index 3c7a3dc110d..783300faeed 100644 --- a/server/src/com/cloud/usage/dao/UsageJobDaoImpl.java +++ b/engine/schema/src/com/cloud/usage/dao/UsageJobDaoImpl.java @@ -26,12 +26,12 @@ import javax.ejb.Local; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.exception.UsageServerException; import com.cloud.usage.UsageJobVO; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; @Component @Local(value={UsageJobDao.class}) @@ -60,7 +60,7 @@ public class UsageJobDaoImpl extends GenericDaoBase implements } @Override - public void updateJobSuccess(Long jobId, long startMillis, long endMillis, long execTime, boolean success) throws UsageServerException { + public void updateJobSuccess(Long jobId, long startMillis, long endMillis, long execTime, boolean success) { Transaction txn = Transaction.open(Transaction.USAGE_DB); try { txn.start(); @@ -79,7 +79,7 @@ public class UsageJobDaoImpl extends GenericDaoBase implements } catch (Exception ex) { txn.rollback(); s_logger.error("error updating job success date", ex); - throw new UsageServerException(ex.getMessage()); + throw new CloudRuntimeException(ex.getMessage()); } finally { txn.close(); } diff --git a/server/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDao.java b/engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDao.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDao.java rename to engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDao.java diff --git a/server/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java rename to engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java diff --git a/server/src/com/cloud/usage/dao/UsageNetworkDao.java b/engine/schema/src/com/cloud/usage/dao/UsageNetworkDao.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageNetworkDao.java rename to engine/schema/src/com/cloud/usage/dao/UsageNetworkDao.java diff --git a/server/src/com/cloud/usage/dao/UsageNetworkDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageNetworkDaoImpl.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageNetworkDaoImpl.java rename to engine/schema/src/com/cloud/usage/dao/UsageNetworkDaoImpl.java diff --git a/server/src/com/cloud/usage/dao/UsageNetworkOfferingDao.java b/engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDao.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageNetworkOfferingDao.java rename to engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDao.java diff --git a/server/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java rename to engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java diff --git a/server/src/com/cloud/usage/dao/UsagePortForwardingRuleDao.java b/engine/schema/src/com/cloud/usage/dao/UsagePortForwardingRuleDao.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsagePortForwardingRuleDao.java rename to engine/schema/src/com/cloud/usage/dao/UsagePortForwardingRuleDao.java diff --git a/server/src/com/cloud/usage/dao/UsagePortForwardingRuleDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsagePortForwardingRuleDaoImpl.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsagePortForwardingRuleDaoImpl.java rename to engine/schema/src/com/cloud/usage/dao/UsagePortForwardingRuleDaoImpl.java diff --git a/server/src/com/cloud/usage/dao/UsageSecurityGroupDao.java b/engine/schema/src/com/cloud/usage/dao/UsageSecurityGroupDao.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageSecurityGroupDao.java rename to engine/schema/src/com/cloud/usage/dao/UsageSecurityGroupDao.java diff --git a/server/src/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java rename to engine/schema/src/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java diff --git a/server/src/com/cloud/usage/dao/UsageStorageDao.java b/engine/schema/src/com/cloud/usage/dao/UsageStorageDao.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageStorageDao.java rename to engine/schema/src/com/cloud/usage/dao/UsageStorageDao.java diff --git a/server/src/com/cloud/usage/dao/UsageStorageDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageStorageDaoImpl.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageStorageDaoImpl.java rename to engine/schema/src/com/cloud/usage/dao/UsageStorageDaoImpl.java diff --git a/server/src/com/cloud/usage/dao/UsageVMInstanceDao.java b/engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDao.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageVMInstanceDao.java rename to engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDao.java diff --git a/server/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java rename to engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java diff --git a/server/src/com/cloud/usage/dao/UsageVPNUserDao.java b/engine/schema/src/com/cloud/usage/dao/UsageVPNUserDao.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageVPNUserDao.java rename to engine/schema/src/com/cloud/usage/dao/UsageVPNUserDao.java diff --git a/server/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java rename to engine/schema/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java diff --git a/server/src/com/cloud/usage/dao/UsageVolumeDao.java b/engine/schema/src/com/cloud/usage/dao/UsageVolumeDao.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageVolumeDao.java rename to engine/schema/src/com/cloud/usage/dao/UsageVolumeDao.java diff --git a/server/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java similarity index 100% rename from server/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java rename to engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java diff --git a/server/src/com/cloud/user/AccountDetailVO.java b/engine/schema/src/com/cloud/user/AccountDetailVO.java similarity index 100% rename from server/src/com/cloud/user/AccountDetailVO.java rename to engine/schema/src/com/cloud/user/AccountDetailVO.java diff --git a/server/src/com/cloud/user/AccountDetailsDao.java b/engine/schema/src/com/cloud/user/AccountDetailsDao.java similarity index 100% rename from server/src/com/cloud/user/AccountDetailsDao.java rename to engine/schema/src/com/cloud/user/AccountDetailsDao.java diff --git a/server/src/com/cloud/user/AccountDetailsDaoImpl.java b/engine/schema/src/com/cloud/user/AccountDetailsDaoImpl.java similarity index 100% rename from server/src/com/cloud/user/AccountDetailsDaoImpl.java rename to engine/schema/src/com/cloud/user/AccountDetailsDaoImpl.java diff --git a/server/src/com/cloud/user/dao/AccountDao.java b/engine/schema/src/com/cloud/user/dao/AccountDao.java similarity index 100% rename from server/src/com/cloud/user/dao/AccountDao.java rename to engine/schema/src/com/cloud/user/dao/AccountDao.java diff --git a/server/src/com/cloud/user/dao/AccountDaoImpl.java b/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java similarity index 100% rename from server/src/com/cloud/user/dao/AccountDaoImpl.java rename to engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java diff --git a/server/src/com/cloud/user/dao/SSHKeyPairDao.java b/engine/schema/src/com/cloud/user/dao/SSHKeyPairDao.java similarity index 100% rename from server/src/com/cloud/user/dao/SSHKeyPairDao.java rename to engine/schema/src/com/cloud/user/dao/SSHKeyPairDao.java diff --git a/server/src/com/cloud/user/dao/SSHKeyPairDaoImpl.java b/engine/schema/src/com/cloud/user/dao/SSHKeyPairDaoImpl.java similarity index 100% rename from server/src/com/cloud/user/dao/SSHKeyPairDaoImpl.java rename to engine/schema/src/com/cloud/user/dao/SSHKeyPairDaoImpl.java diff --git a/server/src/com/cloud/user/dao/UserAccountDao.java b/engine/schema/src/com/cloud/user/dao/UserAccountDao.java similarity index 100% rename from server/src/com/cloud/user/dao/UserAccountDao.java rename to engine/schema/src/com/cloud/user/dao/UserAccountDao.java diff --git a/server/src/com/cloud/user/dao/UserAccountDaoImpl.java b/engine/schema/src/com/cloud/user/dao/UserAccountDaoImpl.java similarity index 100% rename from server/src/com/cloud/user/dao/UserAccountDaoImpl.java rename to engine/schema/src/com/cloud/user/dao/UserAccountDaoImpl.java diff --git a/server/src/com/cloud/user/dao/UserDao.java b/engine/schema/src/com/cloud/user/dao/UserDao.java similarity index 100% rename from server/src/com/cloud/user/dao/UserDao.java rename to engine/schema/src/com/cloud/user/dao/UserDao.java diff --git a/server/src/com/cloud/user/dao/UserDaoImpl.java b/engine/schema/src/com/cloud/user/dao/UserDaoImpl.java similarity index 100% rename from server/src/com/cloud/user/dao/UserDaoImpl.java rename to engine/schema/src/com/cloud/user/dao/UserDaoImpl.java diff --git a/server/src/com/cloud/user/dao/UserStatisticsDao.java b/engine/schema/src/com/cloud/user/dao/UserStatisticsDao.java similarity index 100% rename from server/src/com/cloud/user/dao/UserStatisticsDao.java rename to engine/schema/src/com/cloud/user/dao/UserStatisticsDao.java diff --git a/server/src/com/cloud/user/dao/UserStatisticsDaoImpl.java b/engine/schema/src/com/cloud/user/dao/UserStatisticsDaoImpl.java similarity index 100% rename from server/src/com/cloud/user/dao/UserStatisticsDaoImpl.java rename to engine/schema/src/com/cloud/user/dao/UserStatisticsDaoImpl.java diff --git a/server/src/com/cloud/user/dao/UserStatsLogDao.java b/engine/schema/src/com/cloud/user/dao/UserStatsLogDao.java similarity index 100% rename from server/src/com/cloud/user/dao/UserStatsLogDao.java rename to engine/schema/src/com/cloud/user/dao/UserStatsLogDao.java diff --git a/server/src/com/cloud/user/dao/UserStatsLogDaoImpl.java b/engine/schema/src/com/cloud/user/dao/UserStatsLogDaoImpl.java similarity index 100% rename from server/src/com/cloud/user/dao/UserStatsLogDaoImpl.java rename to engine/schema/src/com/cloud/user/dao/UserStatsLogDaoImpl.java diff --git a/engine/schema/src/com/cloud/vm/ConsoleProxyVO.java b/engine/schema/src/com/cloud/vm/ConsoleProxyVO.java new file mode 100644 index 00000000000..5c1da4855cd --- /dev/null +++ b/engine/schema/src/com/cloud/vm/ConsoleProxyVO.java @@ -0,0 +1,287 @@ +// 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; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; + +import com.cloud.hypervisor.Hypervisor.HypervisorType; + +/** + * ConsoleProxyVO domain object + */ + +@Entity +@Table(name = "console_proxy") +@PrimaryKeyJoinColumn(name = "id") +@DiscriminatorValue(value = "ConsoleProxy") +public class ConsoleProxyVO extends VMInstanceVO implements ConsoleProxy { + public static final String keyContent = + "-----BEGIN PRIVATE KEY-----\n" + + "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCDT9AtEfs+s/I8QXp6rrCw0iNJ\n" + + "0+GgsybNHheU+JpL39LMTZykCrZhZnyDvwdxCoOfE38Sa32baHKNds+y2SHnMNsOkw8OcNucHEBX\n" + + "1FIpOBGph9D6xC+umx9od6xMWETUv7j6h2u+WC3OhBM8fHCBqIiAol31/IkcqDxxsHlQ8S/oCfTl\n" + + "XJUY6Yn628OA1XijKdRnadV0hZ829cv/PZKljjwQUTyrd0KHQeksBH+YAYSo2JUl8ekNLsOi8/cP\n" + + "tfojnltzRI1GXi0ZONs8VnDzJ0a2gqZY+uxlz+CGbLnGnlN4j9cBpE+MfUE+35Dq121sTpsSgF85\n" + + "Mz+pVhn2S633AgMBAAECggEAH/Szd9RxbVADenCA6wxKSa3KErRyq1YN8ksJeCKMAj0FIt0caruE\n" + + "qO11DebWW8cwQu1Otl/cYI6pmg24/BBldMrp9IELX/tNJo+lhPpRyGAxxC0eSXinFfoASb8d+jJd\n" + + "Bd1mmemM6fSxqRlxSP4LrzIhjhR1g2CiyYuTsiM9UtoVKGyHwe7KfFwirUOJo3Mr18zUVNm7YqY4\n" + + "IVhOSq59zkH3ULBlYq4bG50jpxa5mNSCZ7IpafPY/kE/CbR+FWNt30+rk69T+qb5abg6+XGm+OAm\n" + + "bnQ18yZEqX6nJLk7Ch0cfA5orGgrTMOrM71wK7tBBDQ308kOxDGebx6j0qD36QKBgQDTRDr8kuhA\n" + + "9sUyKr9vk2DQCMpNvEeiwI3JRMqmmxpNAtg01aJ3Ya57vX5Fc+zcuV87kP6FM1xgpHQvnw5LWo2J\n" + + "s7ANwQcP8ricEW5zkZhSjI4ssMeAubmsHOloGxmLFYZqwx0JI7CWViGTLMcUlqKblmHcjeQDeDfP\n" + + "P1TaCItFmwKBgQCfHZwVvIcaDs5vxVpZ4ftvflIrW8qq0uOVK6QIf9A/YTGhCXl2qxxTg2A6+0rg\n" + + "ZqI7zKzUDxIbVv0KlgCbpHDC9d5+sdtDB3wW2pimuJ3p1z4/RHb4n/lDwXCACZl1S5l24yXX2pFZ\n" + + "wdPCXmy5PYkHMssFLNhI24pprUIQs66M1QKBgQDQwjAjWisD3pRXESSfZRsaFkWJcM28hdbVFhPF\n" + + "c6gWhwQLmTp0CuL2RPXcPUPFi6sN2iWWi3zxxi9Eyz+9uBn6AsOpo56N5MME/LiOnETO9TKb+Ib6\n" + + "rQtKhjshcv3XkIqFPo2XdVvOAgglPO7vajX91iiXXuH7h7RmJud6l0y/lwKBgE+bi90gLuPtpoEr\n" + + "VzIDKz40ED5bNYHT80NNy0rpT7J2GVN9nwStRYXPBBVeZq7xCpgqpgmO5LtDAWULeZBlbHlOdBwl\n" + + "NhNKKl5wzdEUKwW0yBL1WSS5PQgWPwgARYP25/ggW22sj+49WIo1neXsEKPGWObk8e050f1fTt92\n" + + "Vo1lAoGAb1gCoyBCzvi7sqFxm4V5oapnJeiQQJFjhoYWqGa26rQ+AvXXNuBcigIeDXNJPctSF0Uc\n" + + "p11KbbCgiruBbckvM1vGsk6Sx4leRk+IFHRpJktFUek4o0eUg0shOsyyvyet48Dfg0a8FvcxROs0\n" + + "gD+IYds5doiob/hcm1hnNB/3vk4=\n" + + "-----END PRIVATE KEY-----\n"; + + public static final String certContent = + "-----BEGIN CERTIFICATE-----\n" + + "MIIFZTCCBE2gAwIBAgIHKBCduBUoKDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE\n" + + "BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY\n" + + "BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm\n" + + "aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5\n" + + "IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky\n" + + "ODcwHhcNMTIwMjAzMDMzMDQwWhcNMTcwMjA3MDUxMTIzWjBZMRkwFwYDVQQKDBAq\n" + + "LnJlYWxob3N0aXAuY29tMSEwHwYDVQQLDBhEb21haW4gQ29udHJvbCBWYWxpZGF0\n" + + "ZWQxGTAXBgNVBAMMECoucmVhbGhvc3RpcC5jb20wggEiMA0GCSqGSIb3DQEBAQUA\n" + + "A4IBDwAwggEKAoIBAQCDT9AtEfs+s/I8QXp6rrCw0iNJ0+GgsybNHheU+JpL39LM\n" + + "TZykCrZhZnyDvwdxCoOfE38Sa32baHKNds+y2SHnMNsOkw8OcNucHEBX1FIpOBGp\n" + + "h9D6xC+umx9od6xMWETUv7j6h2u+WC3OhBM8fHCBqIiAol31/IkcqDxxsHlQ8S/o\n" + + "CfTlXJUY6Yn628OA1XijKdRnadV0hZ829cv/PZKljjwQUTyrd0KHQeksBH+YAYSo\n" + + "2JUl8ekNLsOi8/cPtfojnltzRI1GXi0ZONs8VnDzJ0a2gqZY+uxlz+CGbLnGnlN4\n" + + "j9cBpE+MfUE+35Dq121sTpsSgF85Mz+pVhn2S633AgMBAAGjggG+MIIBujAPBgNV\n" + + "HRMBAf8EBTADAQEAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNV\n" + + "HQ8BAf8EBAMCBaAwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5\n" + + "LmNvbS9nZHMxLTY0LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcBMDkwNwYI\n" + + "KwYBBQUHAgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3Np\n" + + "dG9yeS8wgYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au\n" + + "Z29kYWRkeS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdv\n" + + "ZGFkZHkuY29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSME\n" + + "GDAWgBT9rGEyk2xF1uLuhV+auud2mWjM5zArBgNVHREEJDAighAqLnJlYWxob3N0\n" + + "aXAuY29tgg5yZWFsaG9zdGlwLmNvbTAdBgNVHQ4EFgQUZyJz9/QLy5TWIIscTXID\n" + + "E8Xk47YwDQYJKoZIhvcNAQEFBQADggEBAKiUV3KK16mP0NpS92fmQkCLqm+qUWyN\n" + + "BfBVgf9/M5pcT8EiTZlS5nAtzAE/eRpBeR3ubLlaAogj4rdH7YYVJcDDLLoB2qM3\n" + + "qeCHu8LFoblkb93UuFDWqRaVPmMlJRnhsRkL1oa2gM2hwQTkBDkP7w5FG1BELCgl\n" + + "gZI2ij2yxjge6pOEwSyZCzzbCcg9pN+dNrYyGEtB4k+BBnPA3N4r14CWbk+uxjrQ\n" + + "6j2Ip+b7wOc5IuMEMl8xwTyjuX3lsLbAZyFI9RCyofwA9NqIZ1GeB6Zd196rubQp\n" + + "93cmBqGGjZUs3wMrGlm7xdjlX6GQ9UvmvkMub9+lL99A5W50QgCmFeI=\n" + + "-----END CERTIFICATE-----\n"; + + public static final String rootCa = + "-----BEGIN CERTIFICATE-----\n" + + "MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx\n" + + "ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g\n" + + "RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw\n" + + "MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH\n" + + "QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j\n" + + "b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j\n" + + "b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj\n" + + "YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN\n" + + "AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H\n" + + "KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm\n" + + "VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR\n" + + "SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT\n" + + "cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ\n" + + "6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu\n" + + "MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS\n" + + "kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB\n" + + "BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f\n" + + "BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv\n" + + "c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH\n" + + "AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO\n" + + "BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG\n" + + "OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU\n" + + "A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o\n" + + "0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX\n" + + "RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH\n" + + "qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV\n" + + "U+4=\n" + + "-----END CERTIFICATE-----\n" + + "-----BEGIN CERTIFICATE-----\n" + + "MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh\n" + + "bGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu\n" + + "Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g\n" + + "QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe\n" + + "BgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MDYyMFoX\n" + + "DTI0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBE\n" + + "YWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0\n" + + "aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgC\n" + + "ggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv\n" + + "2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+q\n" + + "N1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiO\n" + + "r18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lN\n" + + "f4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+YihfukEH\n" + + "U1jPEX44dMX4/7VpkI+EdOqXG68CAQOjggHhMIIB3TAdBgNVHQ4EFgQU0sSw0pHU\n" + + "TBFxs2HLPaH+3ahq1OMwgdIGA1UdIwSByjCBx6GBwaSBvjCBuzEkMCIGA1UEBxMb\n" + + "VmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2VydCwg\n" + + "SW5jLjE1MDMGA1UECxMsVmFsaUNlcnQgQ2xhc3MgMiBQb2xpY3kgVmFsaWRhdGlv\n" + + "biBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQuY29tLzEg\n" + + "MB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CAQEwDwYDVR0TAQH/BAUw\n" + + "AwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmdv\n" + + "ZGFkZHkuY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jZXJ0aWZpY2F0ZXMu\n" + + "Z29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybDBLBgNVHSAERDBCMEAGBFUd\n" + + "IAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv\n" + + "bS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQC1\n" + + "QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+Sn1eocSxI0YGyeR+sBjUZsE4O\n" + + "WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf\n" + + "SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw==\n" + + "-----END CERTIFICATE-----\n" + + "-----BEGIN CERTIFICATE-----\n" + + "MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0\n" + + "IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz\n" + + "BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y\n" + + "aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG\n" + + "9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy\n" + + "NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y\n" + + "azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs\n" + + "YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw\n" + + "Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl\n" + + "cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY\n" + + "dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9\n" + + "WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS\n" + + "v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v\n" + + "UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu\n" + + "IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC\n" + + "W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd\n" + + "-----END CERTIFICATE-----\n"; + + @Column(name = "public_ip_address", nullable = false) + private String publicIpAddress; + + @Column(name = "public_mac_address", nullable = false) + private String publicMacAddress; + + @Column(name = "public_netmask", nullable = false) + private String publicNetmask; + + @Column(name = "active_session", updatable = true, nullable = false) + private int activeSession; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "last_update", updatable = true, nullable = true) + private Date lastUpdateTime; + + @Column(name = "session_details", updatable = true, nullable = true) + private byte[] sessionDetails; + + @Transient + private boolean sslEnabled = false; + + @Transient + private int port; + + /** + * Correct constructor to use. + * + */ + public ConsoleProxyVO(long id, long serviceOfferingId, String name, long templateId, HypervisorType hypervisorType, long guestOSId, long dataCenterId, long domainId, long accountId, + int activeSession, boolean haEnabled) { + super(id, serviceOfferingId, name, name, Type.ConsoleProxy, templateId, hypervisorType, guestOSId, domainId, accountId, haEnabled); + this.activeSession = activeSession; + } + + protected ConsoleProxyVO() { + super(); + } + + public void setPublicIpAddress(String publicIpAddress) { + this.publicIpAddress = publicIpAddress; + } + + public void setPublicNetmask(String publicNetmask) { + this.publicNetmask = publicNetmask; + } + + public void setPublicMacAddress(String publicMacAddress) { + this.publicMacAddress = publicMacAddress; + } + + public void setActiveSession(int activeSession) { + this.activeSession = activeSession; + } + + public void setLastUpdateTime(Date time) { + this.lastUpdateTime = time; + } + + public void setSessionDetails(byte[] details) { + this.sessionDetails = details; + } + + @Override + public String getPublicIpAddress() { + return this.publicIpAddress; + } + + @Override + public String getPublicNetmask() { + return this.publicNetmask; + } + + @Override + public String getPublicMacAddress() { + return this.publicMacAddress; + } + + @Override + public int getActiveSession() { + return this.activeSession; + } + + @Override + public Date getLastUpdateTime() { + return this.lastUpdateTime; + } + + @Override + public byte[] getSessionDetails() { + return this.sessionDetails; + } + + public boolean isSslEnabled() { + return sslEnabled; + } + + public void setSslEnabled(boolean sslEnabled) { + this.sslEnabled = sslEnabled; + } + + public void setPort(int port) { + this.port = port; + } + + public int getPort() { + return port; + } + +} diff --git a/core/src/com/cloud/vm/DomainRouterVO.java b/engine/schema/src/com/cloud/vm/DomainRouterVO.java similarity index 100% rename from core/src/com/cloud/vm/DomainRouterVO.java rename to engine/schema/src/com/cloud/vm/DomainRouterVO.java diff --git a/core/src/com/cloud/vm/InstanceGroupVMMapVO.java b/engine/schema/src/com/cloud/vm/InstanceGroupVMMapVO.java similarity index 100% rename from core/src/com/cloud/vm/InstanceGroupVMMapVO.java rename to engine/schema/src/com/cloud/vm/InstanceGroupVMMapVO.java diff --git a/core/src/com/cloud/vm/InstanceGroupVO.java b/engine/schema/src/com/cloud/vm/InstanceGroupVO.java similarity index 100% rename from core/src/com/cloud/vm/InstanceGroupVO.java rename to engine/schema/src/com/cloud/vm/InstanceGroupVO.java diff --git a/server/src/com/cloud/vm/ItWorkDao.java b/engine/schema/src/com/cloud/vm/ItWorkDao.java similarity index 100% rename from server/src/com/cloud/vm/ItWorkDao.java rename to engine/schema/src/com/cloud/vm/ItWorkDao.java diff --git a/server/src/com/cloud/vm/ItWorkDaoImpl.java b/engine/schema/src/com/cloud/vm/ItWorkDaoImpl.java similarity index 100% rename from server/src/com/cloud/vm/ItWorkDaoImpl.java rename to engine/schema/src/com/cloud/vm/ItWorkDaoImpl.java diff --git a/server/src/com/cloud/vm/ItWorkVO.java b/engine/schema/src/com/cloud/vm/ItWorkVO.java similarity index 100% rename from server/src/com/cloud/vm/ItWorkVO.java rename to engine/schema/src/com/cloud/vm/ItWorkVO.java diff --git a/server/src/com/cloud/vm/NicVO.java b/engine/schema/src/com/cloud/vm/NicVO.java similarity index 100% rename from server/src/com/cloud/vm/NicVO.java rename to engine/schema/src/com/cloud/vm/NicVO.java diff --git a/core/src/com/cloud/vm/SecondaryStorageVmVO.java b/engine/schema/src/com/cloud/vm/SecondaryStorageVmVO.java similarity index 100% rename from core/src/com/cloud/vm/SecondaryStorageVmVO.java rename to engine/schema/src/com/cloud/vm/SecondaryStorageVmVO.java diff --git a/core/src/com/cloud/vm/UserVmCloneSettingVO.java b/engine/schema/src/com/cloud/vm/UserVmCloneSettingVO.java similarity index 100% rename from core/src/com/cloud/vm/UserVmCloneSettingVO.java rename to engine/schema/src/com/cloud/vm/UserVmCloneSettingVO.java diff --git a/core/src/com/cloud/vm/UserVmDetailVO.java b/engine/schema/src/com/cloud/vm/UserVmDetailVO.java similarity index 100% rename from core/src/com/cloud/vm/UserVmDetailVO.java rename to engine/schema/src/com/cloud/vm/UserVmDetailVO.java diff --git a/core/src/com/cloud/vm/UserVmVO.java b/engine/schema/src/com/cloud/vm/UserVmVO.java similarity index 100% rename from core/src/com/cloud/vm/UserVmVO.java rename to engine/schema/src/com/cloud/vm/UserVmVO.java diff --git a/server/src/com/cloud/vm/dao/ConsoleProxyDao.java b/engine/schema/src/com/cloud/vm/dao/ConsoleProxyDao.java similarity index 100% rename from server/src/com/cloud/vm/dao/ConsoleProxyDao.java rename to engine/schema/src/com/cloud/vm/dao/ConsoleProxyDao.java diff --git a/server/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java similarity index 100% rename from server/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java rename to engine/schema/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java diff --git a/server/src/com/cloud/vm/dao/DomainRouterDao.java b/engine/schema/src/com/cloud/vm/dao/DomainRouterDao.java similarity index 100% rename from server/src/com/cloud/vm/dao/DomainRouterDao.java rename to engine/schema/src/com/cloud/vm/dao/DomainRouterDao.java diff --git a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java similarity index 100% rename from server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java rename to engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java diff --git a/server/src/com/cloud/vm/dao/InstanceGroupDao.java b/engine/schema/src/com/cloud/vm/dao/InstanceGroupDao.java similarity index 100% rename from server/src/com/cloud/vm/dao/InstanceGroupDao.java rename to engine/schema/src/com/cloud/vm/dao/InstanceGroupDao.java diff --git a/server/src/com/cloud/vm/dao/InstanceGroupDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/InstanceGroupDaoImpl.java similarity index 100% rename from server/src/com/cloud/vm/dao/InstanceGroupDaoImpl.java rename to engine/schema/src/com/cloud/vm/dao/InstanceGroupDaoImpl.java diff --git a/server/src/com/cloud/vm/dao/InstanceGroupVMMapDao.java b/engine/schema/src/com/cloud/vm/dao/InstanceGroupVMMapDao.java similarity index 100% rename from server/src/com/cloud/vm/dao/InstanceGroupVMMapDao.java rename to engine/schema/src/com/cloud/vm/dao/InstanceGroupVMMapDao.java diff --git a/server/src/com/cloud/vm/dao/InstanceGroupVMMapDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/InstanceGroupVMMapDaoImpl.java similarity index 100% rename from server/src/com/cloud/vm/dao/InstanceGroupVMMapDaoImpl.java rename to engine/schema/src/com/cloud/vm/dao/InstanceGroupVMMapDaoImpl.java diff --git a/server/src/com/cloud/vm/dao/NicDao.java b/engine/schema/src/com/cloud/vm/dao/NicDao.java similarity index 100% rename from server/src/com/cloud/vm/dao/NicDao.java rename to engine/schema/src/com/cloud/vm/dao/NicDao.java diff --git a/server/src/com/cloud/vm/dao/NicDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java similarity index 100% rename from server/src/com/cloud/vm/dao/NicDaoImpl.java rename to engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java diff --git a/server/src/com/cloud/vm/dao/NicSecondaryIpDao.java b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java similarity index 100% rename from server/src/com/cloud/vm/dao/NicSecondaryIpDao.java rename to engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java diff --git a/server/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java similarity index 100% rename from server/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java rename to engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java diff --git a/server/src/com/cloud/vm/dao/NicSecondaryIpVO.java b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpVO.java similarity index 100% rename from server/src/com/cloud/vm/dao/NicSecondaryIpVO.java rename to engine/schema/src/com/cloud/vm/dao/NicSecondaryIpVO.java diff --git a/server/src/com/cloud/vm/dao/SecondaryStorageVmDao.java b/engine/schema/src/com/cloud/vm/dao/SecondaryStorageVmDao.java similarity index 100% rename from server/src/com/cloud/vm/dao/SecondaryStorageVmDao.java rename to engine/schema/src/com/cloud/vm/dao/SecondaryStorageVmDao.java diff --git a/server/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java similarity index 100% rename from server/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java rename to engine/schema/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java diff --git a/server/src/com/cloud/vm/dao/UserVmCloneSettingDao.java b/engine/schema/src/com/cloud/vm/dao/UserVmCloneSettingDao.java similarity index 100% rename from server/src/com/cloud/vm/dao/UserVmCloneSettingDao.java rename to engine/schema/src/com/cloud/vm/dao/UserVmCloneSettingDao.java diff --git a/server/src/com/cloud/vm/dao/UserVmCloneSettingDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/UserVmCloneSettingDaoImpl.java similarity index 100% rename from server/src/com/cloud/vm/dao/UserVmCloneSettingDaoImpl.java rename to engine/schema/src/com/cloud/vm/dao/UserVmCloneSettingDaoImpl.java diff --git a/server/src/com/cloud/vm/dao/UserVmDao.java b/engine/schema/src/com/cloud/vm/dao/UserVmDao.java similarity index 100% rename from server/src/com/cloud/vm/dao/UserVmDao.java rename to engine/schema/src/com/cloud/vm/dao/UserVmDao.java diff --git a/server/src/com/cloud/vm/dao/UserVmDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java similarity index 100% rename from server/src/com/cloud/vm/dao/UserVmDaoImpl.java rename to engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java diff --git a/server/src/com/cloud/vm/dao/UserVmData.java b/engine/schema/src/com/cloud/vm/dao/UserVmData.java similarity index 100% rename from server/src/com/cloud/vm/dao/UserVmData.java rename to engine/schema/src/com/cloud/vm/dao/UserVmData.java diff --git a/server/src/com/cloud/vm/dao/UserVmDetailsDao.java b/engine/schema/src/com/cloud/vm/dao/UserVmDetailsDao.java similarity index 100% rename from server/src/com/cloud/vm/dao/UserVmDetailsDao.java rename to engine/schema/src/com/cloud/vm/dao/UserVmDetailsDao.java diff --git a/server/src/com/cloud/vm/dao/UserVmDetailsDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/UserVmDetailsDaoImpl.java similarity index 100% rename from server/src/com/cloud/vm/dao/UserVmDetailsDaoImpl.java rename to engine/schema/src/com/cloud/vm/dao/UserVmDetailsDaoImpl.java diff --git a/server/src/com/cloud/vm/dao/VMInstanceDao.java b/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java similarity index 100% rename from server/src/com/cloud/vm/dao/VMInstanceDao.java rename to engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java similarity index 100% rename from server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java rename to engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java diff --git a/server/src/com/cloud/vm/snapshot/dao/VMSnapshotDao.java b/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDao.java similarity index 100% rename from server/src/com/cloud/vm/snapshot/dao/VMSnapshotDao.java rename to engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDao.java diff --git a/server/src/com/cloud/vm/snapshot/dao/VMSnapshotDaoImpl.java b/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDaoImpl.java similarity index 100% rename from server/src/com/cloud/vm/snapshot/dao/VMSnapshotDaoImpl.java rename to engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDaoImpl.java diff --git a/server/src/org/apache/cloudstack/affinity/AffinityGroupVMMapVO.java b/engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupVMMapVO.java similarity index 100% rename from server/src/org/apache/cloudstack/affinity/AffinityGroupVMMapVO.java rename to engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupVMMapVO.java diff --git a/server/src/org/apache/cloudstack/affinity/AffinityGroupVO.java b/engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupVO.java similarity index 100% rename from server/src/org/apache/cloudstack/affinity/AffinityGroupVO.java rename to engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupVO.java diff --git a/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java b/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java similarity index 100% rename from server/src/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java rename to engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java diff --git a/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java b/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java similarity index 100% rename from server/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java rename to engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java diff --git a/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDao.java b/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDao.java similarity index 100% rename from server/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDao.java rename to engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDao.java diff --git a/server/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java b/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java similarity index 100% rename from server/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java rename to engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java diff --git a/server/src/org/apache/cloudstack/region/RegionSyncVO.java b/engine/schema/src/org/apache/cloudstack/region/RegionSyncVO.java similarity index 100% rename from server/src/org/apache/cloudstack/region/RegionSyncVO.java rename to engine/schema/src/org/apache/cloudstack/region/RegionSyncVO.java diff --git a/server/src/org/apache/cloudstack/region/RegionVO.java b/engine/schema/src/org/apache/cloudstack/region/RegionVO.java similarity index 100% rename from server/src/org/apache/cloudstack/region/RegionVO.java rename to engine/schema/src/org/apache/cloudstack/region/RegionVO.java diff --git a/server/src/org/apache/cloudstack/region/dao/RegionDao.java b/engine/schema/src/org/apache/cloudstack/region/dao/RegionDao.java similarity index 100% rename from server/src/org/apache/cloudstack/region/dao/RegionDao.java rename to engine/schema/src/org/apache/cloudstack/region/dao/RegionDao.java diff --git a/server/src/org/apache/cloudstack/region/dao/RegionDaoImpl.java b/engine/schema/src/org/apache/cloudstack/region/dao/RegionDaoImpl.java similarity index 100% rename from server/src/org/apache/cloudstack/region/dao/RegionDaoImpl.java rename to engine/schema/src/org/apache/cloudstack/region/dao/RegionDaoImpl.java diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java similarity index 100% rename from server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java rename to engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDao.java b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDao.java similarity index 100% rename from server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDao.java rename to engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDao.java diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDaoImpl.java b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDaoImpl.java similarity index 100% rename from server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDaoImpl.java rename to engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDaoImpl.java diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java similarity index 100% rename from server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java rename to engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleDao.java b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleDao.java similarity index 100% rename from server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleDao.java rename to engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleDao.java diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java similarity index 100% rename from server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java rename to engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java diff --git a/server/src/com/cloud/cluster/CheckPointVO.java b/server/src/com/cloud/cluster/CheckPointVO.java deleted file mode 100644 index db4f828721a..00000000000 --- a/server/src/com/cloud/cluster/CheckPointVO.java +++ /dev/null @@ -1,121 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.cluster; - -import java.util.Date; - -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 com.cloud.utils.db.GenericDao; -import org.apache.cloudstack.api.InternalIdentity; - -@Entity -@Table(name="stack_maid") -public class CheckPointVO implements InternalIdentity { - - @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") - private long id; - - @Column(name="msid") - private long msid; - - @Column(name="thread_id") - private long threadId; - - @Column(name="seq") - private long seq; - - @Column(name="cleanup_delegate", length=128) - private String delegate; - - @Column(name="cleanup_context", length=65535) - private String context; - - @Column(name=GenericDao.CREATED_COLUMN) - private Date created; - - public CheckPointVO() { - } - - public CheckPointVO(long seq) { - this.seq = seq; - } - - public long getId() { - return id; - } - - public long getMsid() { - return msid; - } - - public void setMsid(long msid) { - this.msid = msid; - } - - public long getThreadId() { - return threadId; - } - - public void setThreadId(long threadId) { - this.threadId = threadId; - } - - public long getSeq() { - return seq; - } - - public void setSeq(long seq) { - this.seq = seq; - } - - public String getDelegate() { - return delegate; - } - - public void setDelegate(String delegate) { - this.delegate = delegate; - } - - public String getContext() { - return context; - } - - public void setContext(String context) { - this.context = context; - } - - public Date getCreated() { - return this.created; - } - - public void setCreated(Date created) { - this.created = created; - } - - @Override - public String toString() { - return new StringBuilder("Task[").append(id).append("-").append(context).append("-").append(delegate).append("]").toString(); - } -} diff --git a/server/src/com/cloud/cluster/dao/StackMaidDao.java b/server/src/com/cloud/cluster/dao/StackMaidDao.java deleted file mode 100644 index eb13b5cb2c2..00000000000 --- a/server/src/com/cloud/cluster/dao/StackMaidDao.java +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.cluster.dao; - -import java.util.Date; -import java.util.List; - -import com.cloud.cluster.CheckPointVO; -import com.cloud.utils.db.GenericDao; - -public interface StackMaidDao extends GenericDao { - public long pushCleanupDelegate(long msid, int seq, String delegateClzName, Object context); - public CheckPointVO popCleanupDelegate(long msid); - public void clearStack(long msid); - - public List listLeftoversByMsid(long msid); - public List listLeftoversByCutTime(Date cutTime); - - /** - * Take over the task items of another management server and clean them up. - * - * @param takeOverMsid management server id to take over. - * @param selfId the management server id of this node. - * @return list of tasks to take over. - */ - boolean takeover(long takeOverMsid, long selfId); - - List listCleanupTasks(long selfId); - List listLeftoversByCutTime(Date cutTime, long msid); -} diff --git a/server/src/com/cloud/cluster/dao/StackMaidDaoImpl.java b/server/src/com/cloud/cluster/dao/StackMaidDaoImpl.java deleted file mode 100644 index 243b00ff4a3..00000000000 --- a/server/src/com/cloud/cluster/dao/StackMaidDaoImpl.java +++ /dev/null @@ -1,208 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.cluster.dao; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.TimeZone; - -import javax.ejb.Local; - -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import com.cloud.cluster.CheckPointVO; -import com.cloud.serializer.SerializerHelper; -import com.cloud.utils.DateUtil; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; - -@Component -@Local(value = { StackMaidDao.class }) @DB(txn=false) -public class StackMaidDaoImpl extends GenericDaoBase implements StackMaidDao { - private static final Logger s_logger = Logger.getLogger(StackMaidDaoImpl.class); - - private SearchBuilder popSearch; - private SearchBuilder clearSearch; - private final SearchBuilder AllFieldsSearch; - - public StackMaidDaoImpl() { - popSearch = createSearchBuilder(); - popSearch.and("msid", popSearch.entity().getMsid(), SearchCriteria.Op.EQ); - popSearch.and("threadId", popSearch.entity().getThreadId(), SearchCriteria.Op.EQ); - - clearSearch = createSearchBuilder(); - clearSearch.and("msid", clearSearch.entity().getMsid(), SearchCriteria.Op.EQ); - - AllFieldsSearch = createSearchBuilder(); - AllFieldsSearch.and("msid", AllFieldsSearch.entity().getMsid(), Op.EQ); - AllFieldsSearch.and("thread", AllFieldsSearch.entity().getThreadId(), Op.EQ); - AllFieldsSearch.done(); - } - - @Override - public boolean takeover(long takeOverMsid, long selfId) { - CheckPointVO task = createForUpdate(); - task.setMsid(selfId); - task.setThreadId(0); - - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("msid", takeOverMsid); - return update(task, sc) > 0; - - } - - @Override - public List listCleanupTasks(long msId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("msid", msId); - sc.setParameters("thread", 0); - - return this.search(sc, null); - } - - @Override - public long pushCleanupDelegate(long msid, int seq, String delegateClzName, Object context) { - CheckPointVO delegateItem = new CheckPointVO(); - delegateItem.setMsid(msid); - delegateItem.setThreadId(Thread.currentThread().getId()); - delegateItem.setSeq(seq); - delegateItem.setDelegate(delegateClzName); - delegateItem.setContext(SerializerHelper.toSerializedStringOld(context)); - delegateItem.setCreated(DateUtil.currentGMTTime()); - - super.persist(delegateItem); - return delegateItem.getId(); - } - - @Override - public CheckPointVO popCleanupDelegate(long msid) { - SearchCriteria sc = popSearch.create(); - sc.setParameters("msid", msid); - sc.setParameters("threadId", Thread.currentThread().getId()); - - Filter filter = new Filter(CheckPointVO.class, "seq", false, 0L, (long)1); - List l = listIncludingRemovedBy(sc, filter); - if(l != null && l.size() > 0) { - expunge(l.get(0).getId()); - return l.get(0); - } - - return null; - } - - @Override - public void clearStack(long msid) { - SearchCriteria sc = clearSearch.create(); - sc.setParameters("msid", msid); - - expunge(sc); - } - - @Override - @DB - public List listLeftoversByMsid(long msid) { - List l = new ArrayList(); - String sql = "select * from stack_maid where msid=? order by msid asc, thread_id asc, seq desc"; - - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, msid); - - ResultSet rs = pstmt.executeQuery(); - while(rs.next()) { - l.add(toEntityBean(rs, false)); - } - } catch (SQLException e) { - s_logger.error("unexcpected exception " + e.getMessage(), e); - } catch (Throwable e) { - s_logger.error("unexcpected exception " + e.getMessage(), e); - } finally { - txn.close(); - } - return l; - } - - @Override - @DB - public List listLeftoversByCutTime(Date cutTime) { - - List l = new ArrayList(); - String sql = "select * from stack_maid where created < ? order by msid asc, thread_id asc, seq desc"; - - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql); - String gmtCutTime = DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime); - pstmt.setString(1, gmtCutTime); - - ResultSet rs = pstmt.executeQuery(); - while(rs.next()) { - l.add(toEntityBean(rs, false)); - } - } catch (SQLException e) { - s_logger.error("unexcpected exception " + e.getMessage(), e); - } catch (Throwable e) { - s_logger.error("unexcpected exception " + e.getMessage(), e); - } finally { - txn.close(); - } - return l; - } - - @Override - @DB - public List listLeftoversByCutTime(Date cutTime, long msid) { - - List l = new ArrayList(); - String sql = "select * from stack_maid where created < ? and msid = ? order by msid asc, thread_id asc, seq desc"; - - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql); - String gmtCutTime = DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime); - pstmt.setString(1, gmtCutTime); - pstmt.setLong(2, msid); - - ResultSet rs = pstmt.executeQuery(); - while(rs.next()) { - l.add(toEntityBean(rs, false)); - } - } catch (SQLException e) { - s_logger.error("unexcpected exception " + e.getMessage(), e); - } catch (Throwable e) { - s_logger.error("unexcpected exception " + e.getMessage(), e); - } finally { - txn.close(); - } - return l; - } -} - diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index c4ad8170d6d..9a7a46faf3d 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -5,7 +5,7 @@ // 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, @@ -23,7 +23,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.UUID; import javax.ejb.Local; import javax.inject.Inject; @@ -98,7 +97,6 @@ import com.cloud.resource.UnableDeleteHostException; import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.servlet.ConsoleProxyPasswordBasedEncryptor; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.VMTemplateHostVO; @@ -263,186 +261,6 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy private final GlobalLock _allocProxyLock = GlobalLock.getInternLock(getAllocProxyLockName()); - /* - * private final String keyContent = - * "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALV5vGlkiWwoZX4hTRplPXP8qtST\n" - * + "hwZhko8noeY5vf8ECwmd+vrCTw/JvnOtkx/8oYNbg/SeUt1EfOsk6gqJdBblGFBZRMcUJlIpqE9z\n" + - * "uv68U9G8Gfi/qvRSY336hibw0J5bZ4vn1QqmyHDB+Czea9AjFUV7AEVG15+vED7why+/AgMBAAEC\n" - * + "gYBmFBPnNKYYMKDmUdUNA+WNWJK/ADzzWe8WlzR6TACTcbLDthl289WFC/YVG42mcHRpbxDKiEQU\n" + - * "MnIR0rHTO34Qb/2HcuyweStU2gqR6omxBvMnFpJr90nD1HcOMJzeLHsphau0/EmKKey+gk4PyieD\n" - * + "KqTM7LTjjHv8xPM4n+WAAQJBAOMNCeFKlJ4kMokWhU74B5/w/NGyT1BHUN0VmilHSiJC8JqS4BiI\n" + - * "ZpAeET3VmilO6QTGh2XVhEDGteu3uZR6ipUCQQDMnRzMgQ/50LFeIQo4IBtwlEouczMlPQF4c21R\n" - * + "1d720moxILVPT0NJZTQUDDmmgbL+B7CgtcCR2NlP5sKPZVADAkEAh4Xq1cy8dMBKYcVNgNtPQcqI\n" + - * "PWpfKR3ISI5yXB0vRNAL6Vet5zbTcUZhKDVtNSbis3UEsGYH8NorEC2z2cpjGQJANhJi9Ow6c5Mh\n" - * + "/DURBUn+1l5pyCKrZnDbvaALSLATLvjmFTuGjoHszy2OeKnOZmEqExWnKKE/VYuPyhy6V7i3TwJA\n" + - * "f8skDgtPK0OsBCa6IljPaHoWBjPc4kFkSTSS1d56hUcWSikTmiuKdLyBb85AADSZYsvHWrte4opN\n" + "dhNukMJuRA==\n"; - * - * private final String certContent = "-----BEGIN CERTIFICATE-----\n" + - * "MIIE3jCCA8agAwIBAgIFAqv56tIwDQYJKoZIhvcNAQEFBQAwgcoxCzAJBgNVBAYT\n" - * + "AlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYD\n" + - * "VQQKExFHb0RhZGR5LmNvbSwgSW5jLjEzMDEGA1UECxMqaHR0cDovL2NlcnRpZmlj\n" - * + "YXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5MTAwLgYDVQQDEydHbyBEYWRkeSBT\n" + - * "ZWN1cmUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxETAPBgNVBAUTCDA3OTY5Mjg3\n" - * + "MB4XDTA5MDIxMTA0NTc1NloXDTEyMDIwNzA1MTEyM1owWTEZMBcGA1UECgwQKi5y\n" + - * "ZWFsaG9zdGlwLmNvbTEhMB8GA1UECwwYRG9tYWluIENvbnRyb2wgVmFsaWRhdGVk\n" - * + "MRkwFwYDVQQDDBAqLnJlYWxob3N0aXAuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GN\n" + - * "ADCBiQKBgQC1ebxpZIlsKGV+IU0aZT1z/KrUk4cGYZKPJ6HmOb3/BAsJnfr6wk8P\n" - * + "yb5zrZMf/KGDW4P0nlLdRHzrJOoKiXQW5RhQWUTHFCZSKahPc7r+vFPRvBn4v6r0\n" + - * "UmN9+oYm8NCeW2eL59UKpshwwfgs3mvQIxVFewBFRtefrxA+8IcvvwIDAQABo4IB\n" - * + "vTCCAbkwDwYDVR0TAQH/BAUwAwEBADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB\n" + - * "BQUHAwIwDgYDVR0PAQH/BAQDAgWgMDIGA1UdHwQrMCkwJ6AloCOGIWh0dHA6Ly9j\n" - * + "cmwuZ29kYWRkeS5jb20vZ2RzMS0yLmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0B\n" + - * "BxcBMDkwNwYIKwYBBQUHAgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j\n" - * + "b20vcmVwb3NpdG9yeS8wgYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0\n" + - * "cDovL29jc3AuZ29kYWRkeS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlm\n" - * + "aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNy\n" + - * "dDAfBgNVHSMEGDAWgBT9rGEyk2xF1uLuhV+auud2mWjM5zArBgNVHREEJDAighAq\n" - * + "LnJlYWxob3N0aXAuY29tgg5yZWFsaG9zdGlwLmNvbTAdBgNVHQ4EFgQUHxwmdK5w\n" + - * "9/YVeZ/3fHyi6nQfzoYwDQYJKoZIhvcNAQEFBQADggEBABv/XinvId6oWXJtmku+\n" - * + "7m90JhSVH0ycoIGjgdaIkcExQGP08MCilbUsPcbhLheSFdgn/cR4e1MP083lacoj\n" + - * "OGauY7b8f/cuquGkT49Ns14awPlEzRjjycQEjjLxFEuL5CFWa2t2gKRE1dSfhDQ+\n" - * + "fJ6GBCs1XgZLuhkKS8fPf+YmG2ZjHzYDjYoSx7paDXgEm+kbYIZdCK51lA0BUAjP\n" + - * "9ZMGhsu/PpAbh5U/DtcIqxY0xeqD4TeGsBzXg6uLhv+jKHDtXg5fYPe+z0n5DCEL\n" - * + "k0fLF4+i/pt9hVCz0QrZ28RUhXf825+EOL0Gw+Uzt+7RV2cCaJrlu4cDrDom2FRy\n" + "E8I=\n" + - * "-----END CERTIFICATE-----\n"; - */ - public static final String keyContent = - "-----BEGIN PRIVATE KEY-----\n" + - "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCDT9AtEfs+s/I8QXp6rrCw0iNJ\n" + - "0+GgsybNHheU+JpL39LMTZykCrZhZnyDvwdxCoOfE38Sa32baHKNds+y2SHnMNsOkw8OcNucHEBX\n" + - "1FIpOBGph9D6xC+umx9od6xMWETUv7j6h2u+WC3OhBM8fHCBqIiAol31/IkcqDxxsHlQ8S/oCfTl\n" + - "XJUY6Yn628OA1XijKdRnadV0hZ829cv/PZKljjwQUTyrd0KHQeksBH+YAYSo2JUl8ekNLsOi8/cP\n" + - "tfojnltzRI1GXi0ZONs8VnDzJ0a2gqZY+uxlz+CGbLnGnlN4j9cBpE+MfUE+35Dq121sTpsSgF85\n" + - "Mz+pVhn2S633AgMBAAECggEAH/Szd9RxbVADenCA6wxKSa3KErRyq1YN8ksJeCKMAj0FIt0caruE\n" + - "qO11DebWW8cwQu1Otl/cYI6pmg24/BBldMrp9IELX/tNJo+lhPpRyGAxxC0eSXinFfoASb8d+jJd\n" + - "Bd1mmemM6fSxqRlxSP4LrzIhjhR1g2CiyYuTsiM9UtoVKGyHwe7KfFwirUOJo3Mr18zUVNm7YqY4\n" + - "IVhOSq59zkH3ULBlYq4bG50jpxa5mNSCZ7IpafPY/kE/CbR+FWNt30+rk69T+qb5abg6+XGm+OAm\n" + - "bnQ18yZEqX6nJLk7Ch0cfA5orGgrTMOrM71wK7tBBDQ308kOxDGebx6j0qD36QKBgQDTRDr8kuhA\n" + - "9sUyKr9vk2DQCMpNvEeiwI3JRMqmmxpNAtg01aJ3Ya57vX5Fc+zcuV87kP6FM1xgpHQvnw5LWo2J\n" + - "s7ANwQcP8ricEW5zkZhSjI4ssMeAubmsHOloGxmLFYZqwx0JI7CWViGTLMcUlqKblmHcjeQDeDfP\n" + - "P1TaCItFmwKBgQCfHZwVvIcaDs5vxVpZ4ftvflIrW8qq0uOVK6QIf9A/YTGhCXl2qxxTg2A6+0rg\n" + - "ZqI7zKzUDxIbVv0KlgCbpHDC9d5+sdtDB3wW2pimuJ3p1z4/RHb4n/lDwXCACZl1S5l24yXX2pFZ\n" + - "wdPCXmy5PYkHMssFLNhI24pprUIQs66M1QKBgQDQwjAjWisD3pRXESSfZRsaFkWJcM28hdbVFhPF\n" + - "c6gWhwQLmTp0CuL2RPXcPUPFi6sN2iWWi3zxxi9Eyz+9uBn6AsOpo56N5MME/LiOnETO9TKb+Ib6\n" + - "rQtKhjshcv3XkIqFPo2XdVvOAgglPO7vajX91iiXXuH7h7RmJud6l0y/lwKBgE+bi90gLuPtpoEr\n" + - "VzIDKz40ED5bNYHT80NNy0rpT7J2GVN9nwStRYXPBBVeZq7xCpgqpgmO5LtDAWULeZBlbHlOdBwl\n" + - "NhNKKl5wzdEUKwW0yBL1WSS5PQgWPwgARYP25/ggW22sj+49WIo1neXsEKPGWObk8e050f1fTt92\n" + - "Vo1lAoGAb1gCoyBCzvi7sqFxm4V5oapnJeiQQJFjhoYWqGa26rQ+AvXXNuBcigIeDXNJPctSF0Uc\n" + - "p11KbbCgiruBbckvM1vGsk6Sx4leRk+IFHRpJktFUek4o0eUg0shOsyyvyet48Dfg0a8FvcxROs0\n" + - "gD+IYds5doiob/hcm1hnNB/3vk4=\n" + - "-----END PRIVATE KEY-----\n"; - - public static final String certContent = - "-----BEGIN CERTIFICATE-----\n" + - "MIIFZTCCBE2gAwIBAgIHKBCduBUoKDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE\n" + - "BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY\n" + - "BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm\n" + - "aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5\n" + - "IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky\n" + - "ODcwHhcNMTIwMjAzMDMzMDQwWhcNMTcwMjA3MDUxMTIzWjBZMRkwFwYDVQQKDBAq\n" + - "LnJlYWxob3N0aXAuY29tMSEwHwYDVQQLDBhEb21haW4gQ29udHJvbCBWYWxpZGF0\n" + - "ZWQxGTAXBgNVBAMMECoucmVhbGhvc3RpcC5jb20wggEiMA0GCSqGSIb3DQEBAQUA\n" + - "A4IBDwAwggEKAoIBAQCDT9AtEfs+s/I8QXp6rrCw0iNJ0+GgsybNHheU+JpL39LM\n" + - "TZykCrZhZnyDvwdxCoOfE38Sa32baHKNds+y2SHnMNsOkw8OcNucHEBX1FIpOBGp\n" + - "h9D6xC+umx9od6xMWETUv7j6h2u+WC3OhBM8fHCBqIiAol31/IkcqDxxsHlQ8S/o\n" + - "CfTlXJUY6Yn628OA1XijKdRnadV0hZ829cv/PZKljjwQUTyrd0KHQeksBH+YAYSo\n" + - "2JUl8ekNLsOi8/cPtfojnltzRI1GXi0ZONs8VnDzJ0a2gqZY+uxlz+CGbLnGnlN4\n" + - "j9cBpE+MfUE+35Dq121sTpsSgF85Mz+pVhn2S633AgMBAAGjggG+MIIBujAPBgNV\n" + - "HRMBAf8EBTADAQEAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNV\n" + - "HQ8BAf8EBAMCBaAwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5\n" + - "LmNvbS9nZHMxLTY0LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcBMDkwNwYI\n" + - "KwYBBQUHAgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3Np\n" + - "dG9yeS8wgYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au\n" + - "Z29kYWRkeS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdv\n" + - "ZGFkZHkuY29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSME\n" + - "GDAWgBT9rGEyk2xF1uLuhV+auud2mWjM5zArBgNVHREEJDAighAqLnJlYWxob3N0\n" + - "aXAuY29tgg5yZWFsaG9zdGlwLmNvbTAdBgNVHQ4EFgQUZyJz9/QLy5TWIIscTXID\n" + - "E8Xk47YwDQYJKoZIhvcNAQEFBQADggEBAKiUV3KK16mP0NpS92fmQkCLqm+qUWyN\n" + - "BfBVgf9/M5pcT8EiTZlS5nAtzAE/eRpBeR3ubLlaAogj4rdH7YYVJcDDLLoB2qM3\n" + - "qeCHu8LFoblkb93UuFDWqRaVPmMlJRnhsRkL1oa2gM2hwQTkBDkP7w5FG1BELCgl\n" + - "gZI2ij2yxjge6pOEwSyZCzzbCcg9pN+dNrYyGEtB4k+BBnPA3N4r14CWbk+uxjrQ\n" + - "6j2Ip+b7wOc5IuMEMl8xwTyjuX3lsLbAZyFI9RCyofwA9NqIZ1GeB6Zd196rubQp\n" + - "93cmBqGGjZUs3wMrGlm7xdjlX6GQ9UvmvkMub9+lL99A5W50QgCmFeI=\n" + - "-----END CERTIFICATE-----\n"; - - public static final String rootCa = - "-----BEGIN CERTIFICATE-----\n" + - "MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx\n" + - "ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g\n" + - "RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw\n" + - "MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH\n" + - "QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j\n" + - "b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j\n" + - "b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj\n" + - "YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN\n" + - "AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H\n" + - "KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm\n" + - "VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR\n" + - "SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT\n" + - "cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ\n" + - "6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu\n" + - "MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS\n" + - "kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB\n" + - "BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f\n" + - "BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv\n" + - "c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH\n" + - "AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO\n" + - "BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG\n" + - "OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU\n" + - "A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o\n" + - "0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX\n" + - "RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH\n" + - "qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV\n" + - "U+4=\n" + - "-----END CERTIFICATE-----\n" + - "-----BEGIN CERTIFICATE-----\n" + - "MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh\n" + - "bGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu\n" + - "Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g\n" + - "QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe\n" + - "BgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MDYyMFoX\n" + - "DTI0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBE\n" + - "YWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0\n" + - "aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgC\n" + - "ggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv\n" + - "2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+q\n" + - "N1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiO\n" + - "r18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lN\n" + - "f4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+YihfukEH\n" + - "U1jPEX44dMX4/7VpkI+EdOqXG68CAQOjggHhMIIB3TAdBgNVHQ4EFgQU0sSw0pHU\n" + - "TBFxs2HLPaH+3ahq1OMwgdIGA1UdIwSByjCBx6GBwaSBvjCBuzEkMCIGA1UEBxMb\n" + - "VmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2VydCwg\n" + - "SW5jLjE1MDMGA1UECxMsVmFsaUNlcnQgQ2xhc3MgMiBQb2xpY3kgVmFsaWRhdGlv\n" + - "biBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQuY29tLzEg\n" + - "MB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CAQEwDwYDVR0TAQH/BAUw\n" + - "AwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmdv\n" + - "ZGFkZHkuY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jZXJ0aWZpY2F0ZXMu\n" + - "Z29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybDBLBgNVHSAERDBCMEAGBFUd\n" + - "IAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv\n" + - "bS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQC1\n" + - "QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+Sn1eocSxI0YGyeR+sBjUZsE4O\n" + - "WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf\n" + - "SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw==\n" + - "-----END CERTIFICATE-----\n" + - "-----BEGIN CERTIFICATE-----\n" + - "MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0\n" + - "IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz\n" + - "BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y\n" + - "aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG\n" + - "9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy\n" + - "NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y\n" + - "azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs\n" + - "YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw\n" + - "Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl\n" + - "cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY\n" + - "dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9\n" + - "WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS\n" + - "v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v\n" + - "UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu\n" + - "IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC\n" + - "W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd\n" + - "-----END CERTIFICATE-----\n"; - @Inject private KeystoreDao _ksDao; @Inject @@ -781,7 +599,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy if(proxy.getActiveSession() >= _capacityPerProxy){ it.remove(); } - } + } if (s_logger.isTraceEnabled()) { s_logger.trace("Running proxy pool size : " + runningList.size()); for (ConsoleProxyVO proxy : runningList) { @@ -1338,7 +1156,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy //expunge the vm boolean result = _itMgr.expunge(proxy, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); if (result) { - HostVO host = _hostDao.findByTypeNameAndZoneId(proxy.getDataCenterId(), proxy.getHostName(), + HostVO host = _hostDao.findByTypeNameAndZoneId(proxy.getDataCenterId(), proxy.getHostName(), Host.Type.ConsoleProxy); if (host != null) { s_logger.debug("Removing host entry for proxy id=" + vmId); @@ -1363,9 +1181,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy if (lock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) { KeystoreVO ksVo = _ksDao.findByName(CERTIFICATE_NAME); if (ksVo == null) { - _ksDao.save(CERTIFICATE_NAME, certContent, keyContent, "realhostip.com"); + _ksDao.save(CERTIFICATE_NAME, ConsoleProxyVO.certContent, ConsoleProxyVO.keyContent, "realhostip.com"); KeystoreVO caRoot = new KeystoreVO(); - caRoot.setCertificate(rootCa); + caRoot.setCertificate(ConsoleProxyVO.rootCa); caRoot.setDomainSuffix("realhostip.com"); caRoot.setName("root"); caRoot.setIndex(0); @@ -1906,5 +1724,5 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy @Override public void prepareStop(VirtualMachineProfile profile) { } - + } diff --git a/server/src/com/cloud/maint/AgentUpgradeVO.java b/server/src/com/cloud/maint/AgentUpgradeVO.java deleted file mode 100644 index b36f5b7dd6c..00000000000 --- a/server/src/com/cloud/maint/AgentUpgradeVO.java +++ /dev/null @@ -1,63 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.maint; - -import org.apache.cloudstack.api.InternalIdentity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Id; -import javax.persistence.Table; - - -@Entity -@Table(name="op_host_upgrade") -public class AgentUpgradeVO implements InternalIdentity { - @Id - @Column(name="host_id") - private long id; - - @Column(name="version") - private String version; - - @Column(name="state") - @Enumerated(value=EnumType.STRING) - private UpgradeManager.State state; - - protected AgentUpgradeVO() { - } - - public AgentUpgradeVO(long id, String version, UpgradeManager.State state) { - this.id = id; - this.version = version; - this.state = state; - } - - public long getId() { - return id; - } - - public String getVersion() { - return version; - } - - public UpgradeManager.State getState() { - return state; - } -} diff --git a/server/src/com/cloud/maint/UpgradeManager.java b/server/src/com/cloud/maint/UpgradeManager.java deleted file mode 100644 index 71bca225b32..00000000000 --- a/server/src/com/cloud/maint/UpgradeManager.java +++ /dev/null @@ -1,47 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.maint; - -import com.cloud.utils.component.Manager; - -/** - * Upgrade Manager manages the upgrade of agents. - * - */ -public interface UpgradeManager extends Manager { - enum State { - RequiresUpdate, - WaitingForUpdate, - UpToDate; - }; - - /** - * Checks if the agent requires an upgrade before it can process - * any commands. - * - * @param hostId host id. - * @return state of the agent. - */ - State registerForUpgrade(long hostId, String version); - - /** - * @return the URL to download the new agent. - */ -// String getAgentUrl(); - - -} diff --git a/server/src/com/cloud/maint/UpgradeManagerImpl.java b/server/src/com/cloud/maint/UpgradeManagerImpl.java deleted file mode 100644 index 54e1ff4401e..00000000000 --- a/server/src/com/cloud/maint/UpgradeManagerImpl.java +++ /dev/null @@ -1,189 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.maint; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.nio.channels.WritableByteChannel; -import java.util.Date; -import java.util.Map; -import java.util.Properties; - -import javax.ejb.Local; -import javax.inject.Inject; -import javax.naming.ConfigurationException; - -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.maint.dao.AgentUpgradeDao; -import com.cloud.utils.PropertiesUtil; -import com.cloud.utils.component.ManagerBase; - -/** - * - * UpgradeManagerImpl implements the upgrade process. It's functionalities - * include - * 1. Identifying agents that require an upgrade before it can connect. - * 2. Spread out a release update to agents so that the entire system - * does not come down at the same time. - */ -@Component -@Local(UpgradeManager.class) -public class UpgradeManagerImpl extends ManagerBase implements UpgradeManager { - private final static Logger s_logger = Logger.getLogger(UpgradeManagerImpl.class); - private static final MultiThreadedHttpConnectionManager s_httpClientManager = new MultiThreadedHttpConnectionManager(); - - String _minimalVersion; - String _recommendedVersion; -// String _upgradeUrl; - String _agentPath; - long _checkInterval; - - @Inject AgentUpgradeDao _upgradeDao; - @Inject ConfigurationDao _configDao; - - @Override - public State registerForUpgrade(long hostId, String version) { - State state = State.UpToDate; - s_logger.debug("Minimal version is " + _minimalVersion + "; version is " + version + "; recommended version is " + _recommendedVersion); - if (Version.compare(version, _minimalVersion) < 0) { - state = State.RequiresUpdate; - } else if (Version.compare(version, _recommendedVersion) < 0) { - state = State.WaitingForUpdate; - } else { - state = State.UpToDate; - } - - /* - if (state != State.UpToDate) { - AgentUpgradeVO vo = _upgradeDao.findById(hostId); - if (vo == null) { - vo = new AgentUpgradeVO(hostId, version, state); - _upgradeDao.persist(vo); - } - } - */ - - return state; - } - - public String deployNewAgent(String url) { - s_logger.info("Updating agent with binary from " + url); - - final HttpClient client = new HttpClient(s_httpClientManager); - final GetMethod method = new GetMethod(url); - int response; - File file = null; - try { - response = client.executeMethod(method); - if (response != HttpURLConnection.HTTP_OK) { - s_logger.warn("Retrieving the agent gives response code: " + response); - return "Retrieving the file from " + url + " got response code: " + response; - } - - final InputStream is = method.getResponseBodyAsStream(); - file = File.createTempFile("agent-", "-" + Long.toString(new Date().getTime())); - file.deleteOnExit(); - - s_logger.debug("Retrieving new agent into " + file.getAbsolutePath()); - - final FileOutputStream fos = new FileOutputStream(file); - - final ByteBuffer buffer = ByteBuffer.allocate(2048); - final ReadableByteChannel in = Channels.newChannel(is); - final WritableByteChannel out = fos.getChannel(); - - while (in.read(buffer) != -1) { - buffer.flip(); - out.write(buffer); - buffer.clear(); - } - - in.close(); - out.close(); - - s_logger.debug("New Agent zip file is now retrieved"); - } catch (final HttpException e) { - return "Unable to retrieve the file from " + url; - } catch (final IOException e) { - return "Unable to retrieve the file from " + url; - } finally { - method.releaseConnection(); - } - - file.delete(); - - return "File will be deployed."; - } - -// @Override -// public String getAgentUrl() { -// return _upgradeUrl; -// } - - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - - final Map configs = _configDao.getConfiguration("UpgradeManager", params); - - File agentUpgradeFile = PropertiesUtil.findConfigFile("agent-update.properties"); - Properties agentUpgradeProps = new Properties(); - try { - if (agentUpgradeFile != null) { - agentUpgradeProps.load(new FileInputStream(agentUpgradeFile)); - } - - _minimalVersion = agentUpgradeProps.getProperty("agent.minimal.version"); - _recommendedVersion = agentUpgradeProps.getProperty("agent.recommended.version"); - - if (_minimalVersion == null) { - _minimalVersion = "0.0.0.0"; - } - - if (_recommendedVersion == null) { - _recommendedVersion = _minimalVersion; - } - - //_upgradeUrl = configs.get("upgrade.url"); - -// if (_upgradeUrl == null) { -// s_logger.debug("There is no upgrade url found in configuration table"); -// // _upgradeUrl = "http://updates.vmops.com/releases/rss.xml"; -// } - - return true; - } catch (IOException ex) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Error reading agent-update.properties: " + ex); - } - } - return false; - } -} diff --git a/server/src/com/cloud/maint/UpgradeManagerMBean.java b/server/src/com/cloud/maint/UpgradeManagerMBean.java deleted file mode 100644 index 1c7cb310b18..00000000000 --- a/server/src/com/cloud/maint/UpgradeManagerMBean.java +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.maint; - -import com.cloud.utils.mgmt.ManagementBean; - -public interface UpgradeManagerMBean extends ManagementBean { - public String deployNewAgent(String location); -} diff --git a/server/src/com/cloud/maint/UpgradeMonitor.java b/server/src/com/cloud/maint/UpgradeMonitor.java deleted file mode 100644 index ca78fe22ece..00000000000 --- a/server/src/com/cloud/maint/UpgradeMonitor.java +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.maint; - -/** - * has been released. - * - */ -public class UpgradeMonitor implements Runnable { - private String _url; - private long _period; - - public UpgradeMonitor(String url, long period) { - _url = url; - } - - public void run() { - - } -} diff --git a/server/src/com/cloud/maint/dao/AgentUpgradeDao.java b/server/src/com/cloud/maint/dao/AgentUpgradeDao.java deleted file mode 100644 index e9763db5804..00000000000 --- a/server/src/com/cloud/maint/dao/AgentUpgradeDao.java +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.maint.dao; - -import com.cloud.maint.AgentUpgradeVO; -import com.cloud.utils.db.GenericDao; - -public interface AgentUpgradeDao extends GenericDao { -} diff --git a/server/src/com/cloud/maint/dao/AgentUpgradeDaoImpl.java b/server/src/com/cloud/maint/dao/AgentUpgradeDaoImpl.java deleted file mode 100644 index 80c6d851aef..00000000000 --- a/server/src/com/cloud/maint/dao/AgentUpgradeDaoImpl.java +++ /dev/null @@ -1,29 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.maint.dao; - -import javax.ejb.Local; - -import org.springframework.stereotype.Component; - -import com.cloud.maint.AgentUpgradeVO; -import com.cloud.utils.db.GenericDaoBase; - -@Component -@Local(AgentUpgradeDao.class) -public class AgentUpgradeDaoImpl extends GenericDaoBase implements AgentUpgradeDao { -} diff --git a/server/src/com/cloud/migration/Db21to22MigrationUtil.java b/server/src/com/cloud/migration/Db21to22MigrationUtil.java deleted file mode 100755 index 66a7d59f53a..00000000000 --- a/server/src/com/cloud/migration/Db21to22MigrationUtil.java +++ /dev/null @@ -1,228 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.migration; - -import java.io.File; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.util.List; - -import javax.inject.Inject; - -import org.apache.log4j.xml.DOMConfigurator; - -import com.cloud.configuration.Resource; -import com.cloud.configuration.Resource.ResourceType; -import com.cloud.configuration.ResourceCountVO; -import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.configuration.dao.ResourceCountDao; -import com.cloud.dc.DataCenter.NetworkType; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.domain.DomainVO; -import com.cloud.domain.dao.DomainDao; -import com.cloud.host.dao.HostDao; -import com.cloud.resource.ResourceManager; -import com.cloud.user.Account; -import com.cloud.user.dao.AccountDao; -import com.cloud.utils.PropertiesUtil; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; -import com.cloud.vm.InstanceGroupVMMapVO; -import com.cloud.vm.InstanceGroupVO; -import com.cloud.vm.dao.InstanceGroupDao; -import com.cloud.vm.dao.InstanceGroupVMMapDao; - -public class Db21to22MigrationUtil { - - @Inject private ClusterDao _clusterDao; - @Inject private HostDao _hostDao; - @Inject private AccountDao _accountDao; - @Inject private DomainDao _domainDao; - @Inject private ResourceCountDao _resourceCountDao; - @Inject private InstanceGroupDao _vmGroupDao; - @Inject private InstanceGroupVMMapDao _groupVMMapDao; - @Inject private ConfigurationDao _configurationDao; - @Inject private DataCenterDao _zoneDao; - @Inject private ResourceManager _resourceMgr; - - private void doMigration() { - setupComponents(); - - migrateResourceCounts(); - - setupInstanceGroups(); - - migrateZones(); - - setupClusterGuid(); - - System.out.println("Migration done"); - } - - /* add guid in cluster table */ - private void setupClusterGuid() { - - //FIXME moving out XenServer code out of server. This upgrade step need to be taken care of - /* - XenServerConnectionPool _connPool = XenServerConnectionPool.getInstance(); - List clusters = _clusterDao.listByHyTypeWithoutGuid(HypervisorType.XenServer.toString()); - for (ClusterVO cluster : clusters) { - List hosts = _resourceMgr.listAllHostsInCluster(cluster.getId()); - for (HostVO host : hosts) { - String ip = host.getPrivateIpAddress(); - String username = host.getDetail("username"); - String password = host.getDetail("password"); - if (ip == null || ip.isEmpty() || username == null || username.isEmpty() || password == null - || password.isEmpty()) { - continue; - } - Queue pass=new LinkedList(); - pass.add(password); - Connection conn = _connPool.slaveConnect(ip, username, pass); - if (conn == null) - continue; - Pool.Record pr = null; - try { - pr = XenServerConnectionPool.getPoolRecord(conn); - } catch (Exception e) { - continue; - } finally { - try { - Session.localLogout(conn); - } catch (Exception e) { - } - } - cluster.setGuid(pr.uuid); - _clusterDao.update(cluster.getId(), cluster); - break; - } - } - */ - } - - - /** - * This method migrates the zones based on bug: 7204 - * based on the param direct.attach.untagged.vlan.enabled, we update zone to basic or advanced for 2.2 - */ - private void migrateZones(){ - try { - System.out.println("Migrating zones"); - String val = _configurationDao.getValue("direct.attach.untagged.vlan.enabled"); - NetworkType networkType; - if(val == null || val.equalsIgnoreCase("true")){ - networkType = NetworkType.Basic; - }else{ - networkType = NetworkType.Advanced; - } - List existingZones = _zoneDao.listAll(); - for(DataCenterVO zone : existingZones){ - zone.setNetworkType(networkType); - _zoneDao.update(zone.getId(), zone); - } - } catch (Exception e) { - System.out.println("Unhandled exception in migrateZones()" + e); - } - } - - private void migrateResourceCounts() { - System.out.println("migrating resource counts"); - SearchBuilder sb = _resourceCountDao.createSearchBuilder(); - sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ); - - for (ResourceType type : Resource.ResourceType.values()) { - SearchCriteria sc = sb.create(); - sc.setParameters("type", type); - - List resourceCounts = _resourceCountDao.search(sc, null); - for (ResourceCountVO resourceCount : resourceCounts) { - if (resourceCount.getAccountId() != null) { - Account acct = _accountDao.findById(resourceCount.getAccountId()); - Long domainId = acct.getDomainId(); - while (domainId != null) { - _resourceCountDao.updateDomainCount(domainId, type, true, resourceCount.getCount()); - DomainVO domain = _domainDao.findById(domainId); - domainId = domain.getParent(); - } - } - } - } - System.out.println("done migrating resource counts"); - } - - private void setupComponents() { - } - - private void setupInstanceGroups() { - System.out.println("setting up vm instance groups"); - - //Search for all the vms that have not null groups - Long vmId = 0L; - Long accountId = 0L; - String groupName; - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - txn.start(); - try { - String request = "SELECT vm.id, uservm.account_id, vm.group from vm_instance vm, user_vm uservm where vm.group is not null and vm.removed is null and vm.id=uservm.id order by id"; - System.out.println(request); - PreparedStatement statement = txn.prepareStatement(request); - ResultSet result = statement.executeQuery(); - while (result.next()) { - vmId = result.getLong(1); - accountId = result.getLong(2); - groupName = result.getString(3); - InstanceGroupVO group = _vmGroupDao.findByAccountAndName(accountId, groupName); - //Create vm group if the group doesn't exist for this account - if (group == null) { - group = new InstanceGroupVO(groupName, accountId); - group = _vmGroupDao.persist(group); - System.out.println("Created new isntance group with name " + groupName + " for account id=" + accountId); - } - - if (group != null) { - InstanceGroupVMMapVO groupVmMapVO = new InstanceGroupVMMapVO(group.getId(), vmId); - _groupVMMapDao.persist(groupVmMapVO); - System.out.println("Assigned vm id=" + vmId + " to group with name " + groupName + " for account id=" + accountId); - } - } - txn.commit(); - statement.close(); - } catch (Exception e) { - System.out.println("Unhandled exception: " + e); - } finally { - txn.close(); - } - } - - - public static void main(String[] args) { - File file = PropertiesUtil.findConfigFile("log4j-cloud.xml"); - - if (file != null) { - System.out.println("Log4j configuration from : " + file.getAbsolutePath()); - DOMConfigurator.configureAndWatch(file.getAbsolutePath(), 10000); - } else { - System.out.println("Configure log4j with default properties"); - } - - new Db21to22MigrationUtil().doMigration(); - System.exit(0); - } -} diff --git a/server/src/com/cloud/migration/Db22beta4to22GAMigrationUtil.java b/server/src/com/cloud/migration/Db22beta4to22GAMigrationUtil.java deleted file mode 100644 index 4487d654571..00000000000 --- a/server/src/com/cloud/migration/Db22beta4to22GAMigrationUtil.java +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.migration; - -import java.io.File; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.apache.log4j.xml.DOMConfigurator; - -import com.cloud.utils.PropertiesUtil; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; - -@DB(txn=false) -public class Db22beta4to22GAMigrationUtil { - - private Map pfRuleIdToIpAddressIdMap = new HashMap(); - private final String FindPfIdToPublicIpId = "SELECT id,ip_address_id from firewall_rules where is_static_nat=1"; - private final String FindVmIdPerPfRule = "SELECT instance_id from port_forwarding_rules where id = ?"; - private final String WriteVmIdToIpAddrTable = "UPDATE user_ip_address set vm_id = ? where id = ?"; - protected Db22beta4to22GAMigrationUtil() { - } - - @DB - //This method gets us a map of pf/firewall id <-> ip address id - //Using the keyset, we will iterate over the pf table to find corresponding vm id - //When we get the vm id, we will use the val for each key to update the corresponding ip addr row with the vm id - public void populateMap(){ - Long key = null; - Long val = null; - - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - - StringBuilder sql = new StringBuilder(FindPfIdToPublicIpId); - - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - key = rs.getLong("id"); - val = rs.getLong("ip_address_id"); - pfRuleIdToIpAddressIdMap.put(key, val); - } - - } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); - } - - } - - @DB - public void updateVmIdForIpAddresses(){ - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - Set pfIds = pfRuleIdToIpAddressIdMap.keySet(); - StringBuilder sql = new StringBuilder(FindVmIdPerPfRule); - Long vmId = null; - Long ipAddressId = null; - PreparedStatement pstmt = null; - for(Long pfId : pfIds){ - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - pstmt.setLong(1, pfId); - ResultSet rs = pstmt.executeQuery(); - while(rs.next()) { - vmId = rs.getLong("instance_id"); - } - ipAddressId = pfRuleIdToIpAddressIdMap.get(pfId); - finallyUpdate(ipAddressId, vmId, txn); - } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); - } - } - } - - @DB - public void finallyUpdate(Long ipAddressId, Long vmId, Transaction txn){ - - StringBuilder sql = new StringBuilder(WriteVmIdToIpAddrTable); - - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - pstmt.setLong(1, vmId); - pstmt.setLong(2, ipAddressId); - int rs = pstmt.executeUpdate(); - } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); - } - } - - public static void main(String[] args) { - - File file = PropertiesUtil.findConfigFile("log4j-cloud.xml"); - - if(file != null) { - System.out.println("Log4j configuration from : " + file.getAbsolutePath()); - DOMConfigurator.configureAndWatch(file.getAbsolutePath(), 10000); - } else { - System.out.println("Configure log4j with default properties"); - } - - Db22beta4to22GAMigrationUtil util = new Db22beta4to22GAMigrationUtil(); - util.populateMap(); - util.updateVmIdForIpAddresses(); - } -} diff --git a/server/src/com/cloud/maint/Version.java b/utils/src/com/cloud/maint/Version.java similarity index 100% rename from server/src/com/cloud/maint/Version.java rename to utils/src/com/cloud/maint/Version.java From 074df0b4157b9e68e5d4775b3efc0ff79a1ecc04 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Thu, 2 May 2013 15:20:49 -0700 Subject: [PATCH 08/71] Fixed an incorrect unit test for affinity group. Removed some useless pom.xml. --- client/tomcatconf/applicationContext.xml.in | 3 - framework/events/pom.xml | 51 +-- pom.xml | 1 - .../AffinityApiTestConfiguration.java | 366 ------------------ .../affinity/AffinityApiUnitTest.java | 20 +- server/test/resources/affinityContext.xml | 7 +- services/console-proxy/plugin/pom.xml | 8 +- services/console-proxy/pom.xml | 6 +- services/console-proxy/server/pom.xml | 2 +- services/pom.xml | 37 -- services/secondary-storage/pom.xml | 6 +- utils/pom.xml | 3 +- 12 files changed, 44 insertions(+), 466 deletions(-) delete mode 100644 server/test/org/apache/cloudstack/affinity/AffinityApiTestConfiguration.java delete mode 100644 services/pom.xml diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index d78700b4b64..36f232c737c 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -167,7 +167,6 @@ - @@ -303,7 +302,6 @@ - @@ -705,7 +703,6 @@ - diff --git a/framework/events/pom.xml b/framework/events/pom.xml index 7c788c35bbd..747c5a1a667 100644 --- a/framework/events/pom.xml +++ b/framework/events/pom.xml @@ -1,23 +1,14 @@ - + + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 cloud-framework-events Apache CloudStack Framework - Event Notification @@ -30,18 +21,18 @@ org.apache.cloudstack - cloud-utils - ${project.version} - + cloud-utils + ${project.version} + - com.google.code.gson - gson - ${cs.gson.version} + com.google.code.gson + gson + ${cs.gson.version} + + + com.google.guava + guava + ${cs.guava.version} - - install - src - test - diff --git a/pom.xml b/pom.xml index 7f4a74664e0..f20e4af5a4c 100644 --- a/pom.xml +++ b/pom.xml @@ -169,7 +169,6 @@ plugins patches framework - services test client diff --git a/server/test/org/apache/cloudstack/affinity/AffinityApiTestConfiguration.java b/server/test/org/apache/cloudstack/affinity/AffinityApiTestConfiguration.java deleted file mode 100644 index a1224db62c3..00000000000 --- a/server/test/org/apache/cloudstack/affinity/AffinityApiTestConfiguration.java +++ /dev/null @@ -1,366 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package org.apache.cloudstack.affinity; - -import java.io.IOException; - -import com.cloud.server.ConfigurationServer; -import com.cloud.user.AccountDetailsDao; -import com.cloud.user.AccountManager; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.UserContextInitializer; -import org.apache.cloudstack.acl.SecurityChecker; -import org.apache.cloudstack.affinity.dao.AffinityGroupDao; -import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; -import org.mockito.Mockito; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.FilterType; -import org.springframework.context.annotation.ComponentScan.Filter; -import org.springframework.core.type.classreading.MetadataReader; -import org.springframework.core.type.classreading.MetadataReaderFactory; -import org.springframework.core.type.filter.TypeFilter; -import com.cloud.utils.component.ComponentContext; -import com.cloud.agent.AgentManager; -import com.cloud.alert.AlertManager; -import com.cloud.api.query.dao.UserAccountJoinDaoImpl; -import com.cloud.capacity.dao.CapacityDaoImpl; -import com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl; -import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.ClusterDetailsDao; -import com.cloud.dc.dao.DcDetailsDao; -import com.cloud.dc.dao.AccountVlanMapDaoImpl; -import com.cloud.dc.dao.ClusterDaoImpl; -import com.cloud.dc.dao.DataCenterDaoImpl; -import com.cloud.dc.dao.DataCenterIpAddressDaoImpl; -import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDao; -import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDaoImpl; -import com.cloud.dc.dao.DataCenterVnetDaoImpl; -import com.cloud.dc.dao.DcDetailsDaoImpl; -import com.cloud.dc.dao.HostPodDaoImpl; -import com.cloud.dc.dao.PodVlanDaoImpl; -import com.cloud.dc.dao.PodVlanMapDaoImpl; -import com.cloud.dc.dao.VlanDaoImpl; -import com.cloud.domain.dao.DomainDaoImpl; -import com.cloud.event.EventUtils; -import com.cloud.event.dao.EventDao; -import com.cloud.event.dao.EventDaoImpl; -import com.cloud.event.dao.UsageEventDaoImpl; -import com.cloud.host.dao.HostDaoImpl; -import com.cloud.host.dao.HostDetailsDaoImpl; -import com.cloud.host.dao.HostTagsDaoImpl; -import com.cloud.network.Ipv6AddressManager; -import com.cloud.network.NetworkManager; -import com.cloud.network.NetworkModel; -import com.cloud.network.NetworkService; -import com.cloud.network.StorageNetworkManager; -import com.cloud.network.dao.AccountGuestVlanMapDaoImpl; -import com.cloud.network.dao.FirewallRulesCidrsDaoImpl; -import com.cloud.network.dao.FirewallRulesDaoImpl; -import com.cloud.network.dao.IPAddressDaoImpl; -import com.cloud.network.dao.LoadBalancerDaoImpl; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.NetworkDomainDaoImpl; -import com.cloud.network.dao.NetworkServiceMapDaoImpl; -import com.cloud.network.dao.PhysicalNetworkDaoImpl; -import com.cloud.network.dao.PhysicalNetworkServiceProviderDaoImpl; -import com.cloud.network.dao.PhysicalNetworkTrafficTypeDaoImpl; -import com.cloud.network.dao.UserIpv6AddressDaoImpl; -import com.cloud.network.element.DhcpServiceProvider; -import com.cloud.network.element.IpDeployer; -import com.cloud.network.element.NetworkElement; -import com.cloud.network.guru.NetworkGuru; -import com.cloud.network.lb.LoadBalancingRulesManager; -import com.cloud.network.rules.FirewallManager; -import com.cloud.network.rules.RulesManager; -import com.cloud.network.rules.dao.PortForwardingRulesDaoImpl; -import com.cloud.network.vpc.NetworkACLManager; -import com.cloud.network.vpc.VpcManager; -import com.cloud.network.vpc.dao.PrivateIpDaoImpl; -import com.cloud.network.vpn.RemoteAccessVpnService; -import com.cloud.offerings.dao.NetworkOfferingDao; -import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; -import com.cloud.projects.ProjectManager; -import com.cloud.service.dao.ServiceOfferingDaoImpl; -import com.cloud.storage.dao.DiskOfferingDaoImpl; -import com.cloud.storage.dao.S3DaoImpl; -import com.cloud.storage.dao.SnapshotDaoImpl; -import com.cloud.storage.dao.StoragePoolDetailsDaoImpl; -import com.cloud.storage.dao.SwiftDaoImpl; -import com.cloud.storage.dao.VolumeDaoImpl; -import com.cloud.storage.s3.S3Manager; -import com.cloud.storage.secondary.SecondaryStorageVmManager; -import com.cloud.storage.swift.SwiftManager; -import com.cloud.tags.dao.ResourceTagsDaoImpl; -import com.cloud.user.dao.AccountDao; -import com.cloud.user.dao.AccountDaoImpl; -import com.cloud.user.dao.UserDaoImpl; -import com.cloud.utils.component.SpringComponentScanUtils; -import com.cloud.utils.db.GenericDao; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.dao.InstanceGroupDaoImpl; -import com.cloud.vm.dao.NicDaoImpl; -import com.cloud.vm.dao.NicSecondaryIpDaoImpl; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.dao.VMInstanceDaoImpl; - -@Configuration -@ComponentScan(basePackageClasses = { AccountVlanMapDaoImpl.class, VolumeDaoImpl.class, HostPodDaoImpl.class, - DomainDaoImpl.class, SwiftDaoImpl.class, ServiceOfferingDaoImpl.class, VlanDaoImpl.class, - IPAddressDaoImpl.class, ResourceTagsDaoImpl.class, InstanceGroupDaoImpl.class, - UserAccountJoinDaoImpl.class, CapacityDaoImpl.class, SnapshotDaoImpl.class, HostDaoImpl.class, - VMInstanceDaoImpl.class, HostTransferMapDaoImpl.class, PortForwardingRulesDaoImpl.class, - PrivateIpDaoImpl.class, UsageEventDaoImpl.class, PodVlanMapDaoImpl.class, DiskOfferingDaoImpl.class, - DataCenterDaoImpl.class, DataCenterIpAddressDaoImpl.class, - DataCenterVnetDaoImpl.class, PodVlanDaoImpl.class, DcDetailsDaoImpl.class, NicSecondaryIpDaoImpl.class, - UserIpv6AddressDaoImpl.class, S3DaoImpl.class, UserDaoImpl.class, NicDaoImpl.class, NetworkDomainDaoImpl.class, - HostDetailsDaoImpl.class, HostTagsDaoImpl.class, ClusterDaoImpl.class, FirewallRulesDaoImpl.class, - FirewallRulesCidrsDaoImpl.class, PhysicalNetworkDaoImpl.class, PhysicalNetworkTrafficTypeDaoImpl.class, - PhysicalNetworkServiceProviderDaoImpl.class, LoadBalancerDaoImpl.class, NetworkServiceMapDaoImpl.class, - PrimaryDataStoreDaoImpl.class, StoragePoolDetailsDaoImpl.class, AffinityGroupServiceImpl.class, - ComponentContext.class, AffinityGroupProcessor.class, UserVmVO.class, EventUtils.class, UserVmVO.class, AccountGuestVlanMapDaoImpl.class - }, includeFilters = { @Filter(value = AffinityApiTestConfiguration.Library.class, type = FilterType.CUSTOM) }, useDefaultFilters = false) -public class AffinityApiTestConfiguration { - - @Bean - public AccountDao accountDao() { - return Mockito.mock(AccountDao.class); - } - - @Bean - public EventUtils eventUtils() { - return Mockito.mock(EventUtils.class); - } - - @Bean - public AffinityGroupProcessor affinityGroupProcessor() { - return Mockito.mock(AffinityGroupProcessor.class); - } - - @Bean - public ComponentContext componentContext() { - return Mockito.mock(ComponentContext.class); - } - - - @Bean - public UserContextInitializer userContextInitializer() { - return Mockito.mock(UserContextInitializer.class); - } - - @Bean - public UserVmVO userVmVO() { - return Mockito.mock(UserVmVO.class); - } - - @Bean - public AffinityGroupDao affinityGroupDao() { - return Mockito.mock(AffinityGroupDao.class); - } - - @Bean - public AffinityGroupVMMapDao affinityGroupVMMapDao() { - return Mockito.mock(AffinityGroupVMMapDao.class); - } - - @Bean - public AccountManager acctMgr() { - return Mockito.mock(AccountManager.class); - } - - @Bean - public NetworkService ntwkSvc() { - return Mockito.mock(NetworkService.class); - } - - @Bean - public NetworkModel ntwkMdl() { - return Mockito.mock(NetworkModel.class); - } - - @Bean - public AlertManager alertMgr() { - return Mockito.mock(AlertManager.class); - } - - @Bean - public SecurityChecker securityChkr() { - return Mockito.mock(SecurityChecker.class); - } - - @Bean - public ResourceLimitService resourceSvc() { - return Mockito.mock(ResourceLimitService.class); - } - - @Bean - public ProjectManager projectMgr() { - return Mockito.mock(ProjectManager.class); - } - - @Bean - public SecondaryStorageVmManager ssvmMgr() { - return Mockito.mock(SecondaryStorageVmManager.class); - } - - @Bean - public SwiftManager swiftMgr() { - return Mockito.mock(SwiftManager.class); - } - - @Bean - public S3Manager s3Mgr() { - return Mockito.mock(S3Manager.class); - } - - @Bean - public VpcManager vpcMgr() { - return Mockito.mock(VpcManager.class); - } - - @Bean - public UserVmDao userVMDao() { - return Mockito.mock(UserVmDao.class); - } - - @Bean - public RulesManager rulesMgr() { - return Mockito.mock(RulesManager.class); - } - - @Bean - public LoadBalancingRulesManager lbRulesMgr() { - return Mockito.mock(LoadBalancingRulesManager.class); - } - - @Bean - public RemoteAccessVpnService vpnMgr() { - return Mockito.mock(RemoteAccessVpnService.class); - } - - @Bean - public NetworkGuru ntwkGuru() { - return Mockito.mock(NetworkGuru.class); - } - - @Bean - public NetworkElement ntwkElement() { - return Mockito.mock(NetworkElement.class); - } - - @Bean - public IpDeployer ipDeployer() { - return Mockito.mock(IpDeployer.class); - } - - @Bean - public DhcpServiceProvider dhcpProvider() { - return Mockito.mock(DhcpServiceProvider.class); - } - - @Bean - public FirewallManager firewallMgr() { - return Mockito.mock(FirewallManager.class); - } - - @Bean - public AgentManager agentMgr() { - return Mockito.mock(AgentManager.class); - } - - @Bean - public StorageNetworkManager storageNtwkMgr() { - return Mockito.mock(StorageNetworkManager.class); - } - - @Bean - public NetworkACLManager ntwkAclMgr() { - return Mockito.mock(NetworkACLManager.class); - } - - @Bean - public Ipv6AddressManager ipv6Mgr() { - return Mockito.mock(Ipv6AddressManager.class); - } - - @Bean - public ConfigurationDao configDao() { - return Mockito.mock(ConfigurationDao.class); - } - - @Bean - public NetworkManager networkManager() { - return Mockito.mock(NetworkManager.class); - } - - @Bean - public NetworkOfferingDao networkOfferingDao() { - return Mockito.mock(NetworkOfferingDao.class); - } - - @Bean - public EventDao eventDao() { - return Mockito.mock(EventDao.class); - } - - @Bean - public NetworkDao networkDao() { - return Mockito.mock(NetworkDao.class); - } - - @Bean - public NetworkOfferingServiceMapDao networkOfferingServiceMapDao() { - return Mockito.mock(NetworkOfferingServiceMapDao.class); - } - - @Bean - public DataCenterLinkLocalIpAddressDao datacenterLinkLocalIpAddressDao() { - return Mockito.mock(DataCenterLinkLocalIpAddressDao.class); - } - - @Bean - public ConfigurationServer configurationServer() { - return Mockito.mock(ConfigurationServer.class); - } - - @Bean - public ClusterDetailsDao clusterDetailsDao() { - return Mockito.mock(ClusterDetailsDao.class); - } - - @Bean - public AccountDetailsDao accountDetailsDao() { - return Mockito.mock(AccountDetailsDao.class); - } - - - public static class Library implements TypeFilter { - - @Override - public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { - mdr.getClassMetadata().getClassName(); - ComponentScan cs = AffinityApiTestConfiguration.class.getAnnotation(ComponentScan.class); - return SpringComponentScanUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); - } - - } -} diff --git a/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java b/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java index a5e6d15bf0b..f9c5728c4c2 100644 --- a/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java +++ b/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java @@ -16,13 +16,20 @@ // under the License. package org.apache.cloudstack.affinity; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyLong; -import static org.mockito.Mockito.*; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + import org.apache.cloudstack.affinity.dao.AffinityGroupDao; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.junit.Before; @@ -49,15 +56,12 @@ import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.UserVmDao; -import javax.inject.Inject; -import javax.naming.ConfigurationException; - @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:/affinityContext.xml") public class AffinityApiUnitTest { @Inject - AffinityGroupServiceImpl _affinityService; + AffinityGroupService _affinityService; @Inject AccountManager _acctMgr; @@ -82,7 +86,7 @@ public class AffinityApiUnitTest { @Inject AccountDao _accountDao; - + @Inject EventDao _eventDao; @@ -91,7 +95,6 @@ public class AffinityApiUnitTest { @BeforeClass public static void setUp() throws ConfigurationException { - } @Before @@ -119,6 +122,7 @@ public class AffinityApiUnitTest { @Test public void createAffinityGroupTest() { + when(_groupDao.isNameInUse(anyLong(), anyLong(), eq("group1"))).thenReturn(false); AffinityGroup group = _affinityService.createAffinityGroup("user", domainId, "group1", "mock", "affinity group one"); assertNotNull("Affinity group 'group1' of type 'mock' failed to create ", group); diff --git a/server/test/resources/affinityContext.xml b/server/test/resources/affinityContext.xml index 15476c1a1b3..d41a63d648b 100644 --- a/server/test/resources/affinityContext.xml +++ b/server/test/resources/affinityContext.xml @@ -26,7 +26,7 @@ - + @@ -35,12 +35,7 @@ - - - - - diff --git a/services/console-proxy/plugin/pom.xml b/services/console-proxy/plugin/pom.xml index 4cbe6d1c8f4..55db33bd951 100644 --- a/services/console-proxy/plugin/pom.xml +++ b/services/console-proxy/plugin/pom.xml @@ -20,16 +20,10 @@ 4.0.0 cloud-plugin-console-proxy Apache CloudStack Console Proxy Plugin - pom org.apache.cloudstack - cloud-service-console-proxy + cloudstack-service-console-proxy 4.2.0-SNAPSHOT ../pom.xml - - install - src - test - diff --git a/services/console-proxy/pom.xml b/services/console-proxy/pom.xml index 1453e8cc264..2c9e2e6e2c7 100644 --- a/services/console-proxy/pom.xml +++ b/services/console-proxy/pom.xml @@ -18,14 +18,14 @@ --> 4.0.0 - cloud-service-console-proxy + cloudstack-service-console-proxy Apache CloudStack Console Proxy Service pom org.apache.cloudstack - cloud-services + cloudstack 4.2.0-SNAPSHOT - ../pom.xml + ../../pom.xml install diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml index 3ac5d5957f7..c3e360b079f 100644 --- a/services/console-proxy/server/pom.xml +++ b/services/console-proxy/server/pom.xml @@ -22,7 +22,7 @@ Apache CloudStack Console Proxy org.apache.cloudstack - cloud-service-console-proxy + cloudstack-service-console-proxy 4.2.0-SNAPSHOT ../pom.xml diff --git a/services/pom.xml b/services/pom.xml deleted file mode 100644 index 54b22bbbf62..00000000000 --- a/services/pom.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - 4.0.0 - cloud-services - Apache CloudStack Cloud Services - pom - - org.apache.cloudstack - cloudstack - 4.2.0-SNAPSHOT - ../pom.xml - - - install - - - console-proxy - secondary-storage - - diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml index 2c8a1d0b9b8..0797c9895f7 100644 --- a/services/secondary-storage/pom.xml +++ b/services/secondary-storage/pom.xml @@ -18,13 +18,13 @@ --> 4.0.0 - cloud-secondary-storage + cloudstack-service-secondary-storage Apache CloudStack Secondary Storage Service org.apache.cloudstack - cloud-services + cloudstack 4.2.0-SNAPSHOT - ../pom.xml + ../../pom.xml diff --git a/utils/pom.xml b/utils/pom.xml index 27430267cfe..0690c35c57b 100644 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -73,11 +73,12 @@ commons-discovery ${cs.discovery.version} - + commons-logging commons-logging From 3722d66aae90c26bb315dfbebf8489256c7f46e9 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Mon, 6 May 2013 06:29:59 -0700 Subject: [PATCH 09/71] Fixed up unit testing to use only an in class TestConfiguration --- engine/api/pom.xml | 10 +- .../com/cloud/storage/StoragePoolHostVO.java | 4 +- .../StorageAllocatorTestConfiguration.java | 4 +- .../storage/test/ChildTestConfiguration.java | 4 +- .../agent/manager/SimulatorManagerImpl.java | 78 +++- pom.xml | 62 +-- server/pom.xml | 5 + .../com/cloud/network/NetworkServiceImpl.java | 399 ++++++++++-------- .../cloud/servlet/ConsoleProxyServlet.java | 29 +- ...SecurityGroupManagerTestConfiguration.java | 4 +- .../SnapshotDaoTestConfiguration.java | 4 +- .../dao/StoragePoolDaoTestConfiguration.java | 4 +- ...serVmCloneSettingDaoTestConfiguration.java | 4 +- .../vm/dao/UserVmDaoTestConfiguration.java | 4 +- .../com/cloud/vpc/VpcTestConfiguration.java | 4 +- .../affinity/AffinityApiUnitTest.java | 67 ++- .../ChildTestConfiguration.java | 4 +- server/test/resources/affinityContext.xml | 42 -- services/console-proxy/pom.xml | 4 +- services/secondary-storage/pom.xml | 6 +- tools/marvin/pom.xml | 49 ++- .../usage/UsageManagerTestConfiguration.java | 5 +- .../src/com/cloud/utils/AnnotationHelper.java | 28 +- .../component/SpringComponentScanUtils.java | 41 -- .../cloudstack/test/utils/SpringUtils.java | 113 +++++ 25 files changed, 611 insertions(+), 367 deletions(-) delete mode 100644 server/test/resources/affinityContext.xml delete mode 100644 utils/src/com/cloud/utils/component/SpringComponentScanUtils.java create mode 100644 utils/src/org/apache/cloudstack/test/utils/SpringUtils.java diff --git a/engine/api/pom.xml b/engine/api/pom.xml index 1e8e8c3eb38..1b8f26c2320 100644 --- a/engine/api/pom.xml +++ b/engine/api/pom.xml @@ -30,11 +30,6 @@ cloud-api ${project.version} - - org.apache.cloudstack - cloud-framework-api - ${project.version} - org.apache.cxf cxf-bundle-jaxrs @@ -55,6 +50,11 @@ cloud-framework-rest ${project.version} + + org.apache.cloudstack + cloud-framework-ipc + ${project.version} + install diff --git a/engine/schema/src/com/cloud/storage/StoragePoolHostVO.java b/engine/schema/src/com/cloud/storage/StoragePoolHostVO.java index 1a4b9b87dce..1b02f6d9754 100644 --- a/engine/schema/src/com/cloud/storage/StoragePoolHostVO.java +++ b/engine/schema/src/com/cloud/storage/StoragePoolHostVO.java @@ -50,11 +50,11 @@ public class StoragePoolHostVO implements StoragePoolHostAssoc { private String localPath; @Column(name=GenericDaoBase.CREATED_COLUMN) - private final Date created = null; + private Date created = null; @Column(name="last_updated") @Temporal(value=TemporalType.TIMESTAMP) - private final Date lastUpdated = null; + private Date lastUpdated = null; public StoragePoolHostVO() { diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java index b815fc13446..4790086b2e1 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java @@ -20,6 +20,7 @@ import java.io.IOException; import org.apache.cloudstack.storage.allocator.StorageAllocatorTestConfiguration.Library; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl; +import org.apache.cloudstack.test.utils.SpringUtils; import org.mockito.Mockito; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -36,7 +37,6 @@ import com.cloud.host.dao.HostDaoImpl; import com.cloud.storage.StorageManager; import com.cloud.storage.dao.StoragePoolDetailsDaoImpl; import com.cloud.storage.dao.VMTemplateDaoImpl; -import com.cloud.utils.component.SpringComponentScanUtils; import com.cloud.vm.UserVmManager; @@ -67,7 +67,7 @@ public class StorageAllocatorTestConfiguration { public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { mdr.getClassMetadata().getClassName(); ComponentScan cs = StorageAllocatorTestConfiguration.class.getAnnotation(ComponentScan.class); - return SpringComponentScanUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); } } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java index a063bdda8ad..0dcdebd6553 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java @@ -24,6 +24,7 @@ import org.apache.cloudstack.framework.rpc.RpcProvider; import org.apache.cloudstack.storage.HostEndpointRpcServer; import org.apache.cloudstack.storage.endpoint.EndPointSelector; import org.apache.cloudstack.storage.test.ChildTestConfiguration.Library; +import org.apache.cloudstack.test.utils.SpringUtils; import org.mockito.Mockito; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -75,7 +76,6 @@ import com.cloud.storage.swift.SwiftManager; import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.template.TemplateManager; import com.cloud.user.dao.UserDaoImpl; -import com.cloud.utils.component.SpringComponentScanUtils; import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.dao.ConsoleProxyDaoImpl; import com.cloud.vm.dao.DomainRouterDao; @@ -222,7 +222,7 @@ public class ChildTestConfiguration extends TestConfiguration { public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { mdr.getClassMetadata().getClassName(); ComponentScan cs = ChildTestConfiguration.class.getAnnotation(ComponentScan.class); - return SpringComponentScanUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); } } diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java index c234cc5cb2e..ab6eec3394a 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java @@ -16,12 +16,74 @@ // under the License. package com.cloud.agent.manager; -import com.cloud.agent.api.*; +import java.util.HashMap; +import java.util.Map; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.AttachIsoCommand; +import com.cloud.agent.api.AttachVolumeCommand; +import com.cloud.agent.api.BackupSnapshotCommand; +import com.cloud.agent.api.BumpUpPriorityCommand; +import com.cloud.agent.api.CheckHealthCommand; +import com.cloud.agent.api.CheckNetworkCommand; +import com.cloud.agent.api.CheckRouterCommand; +import com.cloud.agent.api.CheckVirtualMachineCommand; +import com.cloud.agent.api.CleanupNetworkRulesCmd; +import com.cloud.agent.api.ClusterSyncCommand; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.ComputeChecksumCommand; +import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; +import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; +import com.cloud.agent.api.CreateStoragePoolCommand; +import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; +import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.DeleteStoragePoolCommand; +import com.cloud.agent.api.GetDomRVersionCmd; +import com.cloud.agent.api.GetHostStatsCommand; +import com.cloud.agent.api.GetStorageStatsCommand; +import com.cloud.agent.api.GetVmStatsCommand; +import com.cloud.agent.api.GetVncPortCommand; +import com.cloud.agent.api.MaintainCommand; +import com.cloud.agent.api.ManageSnapshotCommand; +import com.cloud.agent.api.MigrateCommand; +import com.cloud.agent.api.ModifyStoragePoolCommand; +import com.cloud.agent.api.NetworkUsageCommand; +import com.cloud.agent.api.PingTestCommand; +import com.cloud.agent.api.PrepareForMigrationCommand; +import com.cloud.agent.api.RebootCommand; +import com.cloud.agent.api.SecStorageSetupCommand; +import com.cloud.agent.api.SecStorageVMSetupCommand; +import com.cloud.agent.api.SecurityGroupRulesCmd; +import com.cloud.agent.api.StartCommand; +import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.StoragePoolInfo; import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; -import com.cloud.agent.api.routing.*; -import com.cloud.agent.api.storage.*; +import com.cloud.agent.api.routing.DhcpEntryCommand; +import com.cloud.agent.api.routing.IpAssocCommand; +import com.cloud.agent.api.routing.LoadBalancerConfigCommand; +import com.cloud.agent.api.routing.SavePasswordCommand; +import com.cloud.agent.api.routing.SetFirewallRulesCommand; +import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; +import com.cloud.agent.api.routing.SetStaticNatRulesCommand; +import com.cloud.agent.api.routing.VmDataCommand; +import com.cloud.agent.api.storage.CopyVolumeCommand; +import com.cloud.agent.api.storage.CreateCommand; +import com.cloud.agent.api.storage.DeleteTemplateCommand; +import com.cloud.agent.api.storage.DestroyCommand; +import com.cloud.agent.api.storage.DownloadCommand; +import com.cloud.agent.api.storage.DownloadProgressCommand; +import com.cloud.agent.api.storage.ListTemplateCommand; +import com.cloud.agent.api.storage.ListVolumeCommand; +import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.simulator.MockConfigurationVO; import com.cloud.simulator.MockHost; import com.cloud.simulator.MockVMVO; @@ -34,14 +96,6 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine.State; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import javax.ejb.Local; -import javax.inject.Inject; -import javax.naming.ConfigurationException; -import java.util.HashMap; -import java.util.Map; @Component @Local(value = { SimulatorManager.class }) @@ -256,7 +310,7 @@ public class SimulatorManagerImpl extends ManagerBase implements SimulatorManage return Answer.createUnsupportedCommandAnswer(cmd); } } catch(Exception e) { - s_logger.error("Failed execute cmd: " + e.toString()); + s_logger.error("Failed execute cmd: ", e); txn.rollback(); return new Answer(cmd, false, e.toString()); } finally { diff --git a/pom.xml b/pom.xml index f20e4af5a4c..9dbd1bf8d7a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,13 +1,12 @@ + 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. --> 4.0.0 @@ -171,6 +170,7 @@ framework test client + services @@ -206,22 +206,18 @@ ${org.springframework.version} org.mockito @@ -265,6 +261,20 @@ ${basedir}/${cs.target.dir}/test-classes + + maven-clean-plugin + + true + + + target + + **/* + + + + + org.apache.maven.plugins maven-release-plugin @@ -504,7 +514,7 @@ target-eclipse - + developer tools/devcloud/devcloud.cfg @@ -521,7 +531,7 @@ developer - + diff --git a/server/pom.xml b/server/pom.xml index 808dd3eee0a..429d60819e3 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -95,6 +95,11 @@ cloud-framework-events ${project.version} + + org.apache.cloudstack + cloud-utils + ${project.version} + install diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 230d907aaa3..5e8be92fdb5 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -5,7 +5,7 @@ // 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, @@ -16,13 +16,55 @@ // under the License. package com.cloud.network; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.security.InvalidParameterException; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.UUID; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.acl.ControlledEntity.ACLType; +import org.apache.cloudstack.acl.SecurityChecker; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; +import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; +import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd; +import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; +import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; +import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; +import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.*; +import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.DataCenterVnetVO; +import com.cloud.dc.Pod; import com.cloud.dc.Vlan.VlanType; -import com.cloud.dc.dao.*; +import com.cloud.dc.VlanVO; +import com.cloud.dc.dao.AccountVlanMapDao; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.DataCenterVnetDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DeployDestination; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; @@ -32,7 +74,14 @@ import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; import com.cloud.event.dao.EventDao; import com.cloud.event.dao.UsageEventDao; -import com.cloud.exception.*; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.UnsupportedServiceException; import com.cloud.host.dao.HostDao; import com.cloud.network.IpAddress.State; import com.cloud.network.Network.Capability; @@ -44,7 +93,22 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetwork.BroadcastDomainRange; import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; import com.cloud.network.addr.PublicIp; -import com.cloud.network.dao.*; +import com.cloud.network.dao.AccountGuestVlanMapDao; +import com.cloud.network.dao.AccountGuestVlanMapVO; +import com.cloud.network.dao.FirewallRulesDao; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkDomainDao; +import com.cloud.network.dao.NetworkDomainVO; +import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; +import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao; +import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO; +import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.network.element.NetworkElement; import com.cloud.network.element.VirtualRouterElement; import com.cloud.network.element.VpcVirtualRouterElement; @@ -68,7 +132,14 @@ import com.cloud.projects.ProjectManager; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; -import com.cloud.user.*; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; +import com.cloud.user.DomainManager; +import com.cloud.user.ResourceLimitService; +import com.cloud.user.User; +import com.cloud.user.UserContext; +import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; import com.cloud.utils.AnnotationHelper; @@ -76,36 +147,29 @@ import com.cloud.utils.Journal; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.component.ManagerBase; -import com.cloud.utils.db.*; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; -import com.cloud.vm.*; -import com.cloud.vm.dao.*; -import org.apache.cloudstack.acl.ControlledEntity.ACLType; -import org.apache.cloudstack.acl.SecurityChecker; -import org.apache.cloudstack.acl.SecurityChecker.AccessType; -import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; -import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; -import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd; -import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; -import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; -import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; -import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import javax.ejb.Local; -import javax.inject.Inject; -import javax.naming.ConfigurationException; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.security.InvalidParameterException; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; +import com.cloud.vm.Nic; +import com.cloud.vm.NicSecondaryIp; +import com.cloud.vm.NicVO; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.ReservationContextImpl; +import com.cloud.vm.SecondaryStorageVmVO; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.NicSecondaryIpDao; +import com.cloud.vm.dao.NicSecondaryIpVO; +import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.dao.VMInstanceDao; /** * NetworkServiceImpl implements NetworkService. @@ -151,9 +215,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { @Inject UsageEventDao _usageEventDao; - + @Inject List _networkGurus; - + @Inject NetworkDomainDao _networkDomainDao; @Inject @@ -161,10 +225,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { @Inject FirewallRulesDao _firewallDao; - + @Inject ResourceLimitService _resourceLimitMgr; - + @Inject DomainManager _domainMgr; @Inject @@ -175,7 +239,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { PhysicalNetworkDao _physicalNetworkDao; @Inject PhysicalNetworkServiceProviderDao _pNSPDao; - + @Inject PhysicalNetworkTrafficTypeDao _pNTrafficTypeDao; @@ -255,7 +319,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (purposes == null || purposes.isEmpty()) { // since no active rules are there check if any rules are applied on the public IP but are in // revoking state - + purposes = getPublicIpPurposeInRules(ip, true, includingFirewall); if (ip.isOneToOneNat()) { if (purposes == null) { @@ -372,9 +436,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } return true; } - - + + private Set getPublicIpPurposeInRules(PublicIp ip, boolean includeRevoked, boolean includingFirewall) { Set result = new HashSet(); @@ -403,15 +467,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return _networksDao.listByZoneAndGuestType(owner.getId(), zoneId, Network.GuestType.Isolated, false); } - + @Override public List getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner) { return _networksDao.listSourceNATEnabledNetworks(owner.getId(), zoneId, Network.GuestType.Isolated); } - - + + @Override @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "allocating Ip", create = true) @@ -457,7 +521,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { _accountMgr.checkAccess(caller, null, false, ipOwner); long callerUserId = UserContext.current().getCallerUserId(); DataCenter zone = _configMgr.getZone(zoneId); - + return _networkMgr.allocateIp(ipOwner, isSystem, caller, callerUserId, zone); } @@ -489,6 +553,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } + @Override public NicSecondaryIp allocateSecondaryGuestIP (Account ipOwner, long zoneId, Long nicId, Long networkId, String requestedIp) throws InsufficientAddressCapacityException { Long accountId = null; @@ -596,6 +661,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } } + @Override @DB public boolean releaseSecondaryIpFromNic (long ipAddressId) { Account caller = UserContext.current().getCaller(); @@ -757,7 +823,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { public Network getNetwork(long id) { return _networksDao.findById(id); } - + private void checkSharedNetworkCidrOverlap(Long zoneId, long physicalNetworkId, String cidr) { if (zoneId == null || cidr == null) { @@ -808,7 +874,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } } } - + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NETWORK_CREATE, eventDescription = "creating network") @@ -840,15 +906,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (ntwkOff == null || ntwkOff.isSystemOnly()) { InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find network offering by specified id"); if (ntwkOff != null) { - ex.addProxyObject(ntwkOff, networkOfferingId, "networkOfferingId"); + ex.addProxyObject(ntwkOff, networkOfferingId, "networkOfferingId"); // Get the VO object's table name. String tablename = AnnotationHelper.getTableName(ntwkOff); if (tablename != null) { ex.addProxyObject(tablename, networkOfferingId, "networkOfferingId"); - } else { - s_logger.info("\nCould not retrieve table name (annotation) from " + tablename + " VO proxy object\n"); } - throw ex; } throw ex; } @@ -870,12 +933,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (zone == null) { throw new InvalidParameterValueException("Specified zone id was not found"); } - + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) { // See DataCenterVO.java PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation since specified Zone is currently disabled"); ex.addProxyObject(zone, zoneId, "zoneId"); - throw ex; + throw ex; } // Only domain and account ACL types are supported in Acton. @@ -895,7 +958,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } } else if (ntwkOff.getGuestType() == GuestType.Shared) { if (!(aclType == ACLType.Domain || aclType == ACLType.Account)) { - throw new InvalidParameterValueException("AclType should be " + ACLType.Domain + " or " + + throw new InvalidParameterValueException("AclType should be " + ACLType.Domain + " or " + ACLType.Account + " for network of type " + Network.GuestType.Shared); } } @@ -931,7 +994,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } DomainVO domain = _domainDao.findById(domainId); - if (domain == null) { + if (domain == null) { throw new InvalidParameterValueException("Unable to find domain by specified id"); } _accountMgr.checkAccess(caller, domain); @@ -957,7 +1020,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (startIPv6 != null) { ipv6 = true; } - + if (gateway != null) { try { // getByName on a literal representation will only check validity of the address @@ -974,8 +1037,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Gateway parameter is invalid"); } } - - + + String cidr = null; if (ipv4) { // if end ip is not specified, default it to startIp @@ -1008,18 +1071,18 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } } - + if (ipv6) { if (endIPv6 == null) { endIPv6 = startIPv6; } _networkModel.checkIp6Parameters(startIPv6, endIPv6, ip6Gateway, ip6Cidr); - + if (zone.getNetworkType() != NetworkType.Advanced || ntwkOff.getGuestType() != Network.GuestType.Shared) { throw new InvalidParameterValueException("Can only support create IPv6 network with advance shared network!"); } } - + // Regular user can create Guest Isolated Source Nat enabled network only if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL && (ntwkOff.getTrafficType() != TrafficType.Guest || ntwkOff.getGuestType() != Network.GuestType.Isolated @@ -1033,7 +1096,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL && (ntwkOff.getSpecifyVlan() || vlanId != null)) { throw new InvalidParameterValueException("Regular user is not allowed to specify vlanId"); } - + if (ipv4) { // For non-root admins check cidr limit - if it's allowed by global config value if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN && cidr != null) { @@ -1051,7 +1114,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (ipv6 && providersConfiguredForExternalNetworking(ntwkProviders)) { throw new InvalidParameterValueException("Cannot support IPv6 on network offering with external devices!"); } - + if (cidr != null && providersConfiguredForExternalNetworking(ntwkProviders)) { if (ntwkOff.getGuestType() == GuestType.Shared && (zone.getNetworkType() == NetworkType.Advanced) && isSharedNetworkOfferingWithServices(networkOfferingId)) { @@ -1067,9 +1130,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { // 2) GuestType is Isolated, but SourceNat service is disabled boolean createVlan = (startIP != null && endIP != null && zone.getNetworkType() == NetworkType.Advanced && ((ntwkOff.getGuestType() == Network.GuestType.Shared) - || (ntwkOff.getGuestType() == GuestType.Isolated && + || (ntwkOff.getGuestType() == GuestType.Isolated && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)))); - + if (!createVlan) { // Only support advance shared network in IPv6, which means createVlan is a must if (ipv6) { @@ -1087,7 +1150,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } else { s_logger.info("\nCould not retrieve table name (annotation) from " + tablename + " VO proxy object\n"); } - throw ex; + throw ex; } Transaction txn = Transaction.currentTxn(); @@ -1114,15 +1177,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (!_configMgr.isOfferingForVpc(ntwkOff)){ throw new InvalidParameterValueException("Network offering can't be used for VPC networks"); } - network = _vpcMgr.createVpcGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, + network = _vpcMgr.createVpcGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, caller); } else { if (_configMgr.isOfferingForVpc(ntwkOff)){ throw new InvalidParameterValueException("Network offering can be used for VPC networks only"); } - network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, + network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr); - } + } if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN && createVlan) { // Create vlan ip range @@ -1232,13 +1295,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } else { permittedAccounts.clear(); Project project = _projectMgr.getProject(projectId); - if (project == null) { + if (project == null) { throw new InvalidParameterValueException("Unable to find project by specified id"); } if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) { // getProject() returns type ProjectVO. InvalidParameterValueException ex = new InvalidParameterValueException("Account " + caller + " cannot access specified project id"); - ex.addProxyObject(project, projectId, "projectId"); + ex.addProxyObject(project, projectId, "projectId"); throw ex; } permittedAccounts.add(project.getProjectAccountId()); @@ -1250,15 +1313,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { path = _domainDao.findById(domainId).getPath(); } else { path = _domainDao.findById(caller.getDomainId()).getPath(); - } - + } + if (listAll && domainId == null) { isRecursive = true; } Filter searchFilter = new Filter(NetworkVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _networksDao.createSearchBuilder(); - + if (forVpc != null) { if (forVpc) { sb.and("vpc", sb.entity().getVpcId(), Op.NNULL); @@ -1302,8 +1365,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { SearchBuilder accountSearch = _accountDao.createSearchBuilder(); accountSearch.and("typeNEQ", accountSearch.entity().getType(), SearchCriteria.Op.NEQ); accountSearch.and("typeEQ", accountSearch.entity().getType(), SearchCriteria.Op.EQ); - - + + sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER); List networksToReturn = new ArrayList(); @@ -1312,7 +1375,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (!permittedAccounts.isEmpty()) { //get account level networks networksToReturn.addAll(listAccountSpecificNetworks( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, zoneType), searchFilter, permittedAccounts)); //get domain level networks @@ -1326,12 +1389,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } else { //add account specific networks networksToReturn.addAll(listAccountSpecificNetworksByDomainPath( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, zoneType), searchFilter, path, isRecursive)); //add domain specific networks of domain + parent domains networksToReturn.addAll(listDomainSpecificNetworksByDomainPath( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, zoneType), searchFilter, path, isRecursive)); //add networks of subdomains @@ -1371,7 +1434,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { networksToReturn=supportedNetworks; } - + if (canUseForDeploy != null) { List networksForDeploy = new ArrayList(); for (NetworkVO network : networksToReturn) { @@ -1379,16 +1442,16 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { networksForDeploy.add(network); } } - + networksToReturn=networksForDeploy; } - + return networksToReturn; } - - private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, + + private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId, Map tags, String zoneType) { @@ -1413,9 +1476,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } if(zoneType != null) { - sc.setJoinParameters("zoneSearch", "networkType", zoneType); + sc.setJoinParameters("zoneSearch", "networkType", zoneType); } - + if (guestIpType != null) { sc.addAnd("guestType", SearchCriteria.Op.EQ, guestIpType); } @@ -1445,11 +1508,11 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (specifyIpRanges != null) { sc.addAnd("specifyIpRanges", SearchCriteria.Op.EQ, specifyIpRanges); } - + if (vpcId != null) { sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId); } - + if (tags != null && !tags.isEmpty()) { int count = 0; sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Network.toString()); @@ -1532,7 +1595,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } List networkIds = new ArrayList(); - + List maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray()); for (NetworkDomainVO map : maps) { @@ -1561,16 +1624,16 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { NetworkVO network = _networksDao.findById(networkId); if (network == null) { // see NetworkVO.java - + InvalidParameterValueException ex = new InvalidParameterValueException("unable to find network with specified id"); - ex.addProxyObject(network, networkId, "networkId"); + ex.addProxyObject(network, networkId, "networkId"); throw ex; } // don't allow to delete system network if (isNetworkSystem(network)) { InvalidParameterValueException ex = new InvalidParameterValueException("Network with specified id is system and can't be removed"); - ex.addProxyObject(network, network.getId(), "networkId"); + ex.addProxyObject(network, network.getId(), "networkId"); throw ex; } @@ -1585,7 +1648,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return _networkMgr.destroyNetwork(networkId, context); } - + @Override @ActionEvent(eventType = EventTypes.EVENT_NETWORK_RESTART, eventDescription = "restarting network", async = true) public boolean restartNetwork(RestartNetworkCmd cmd, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { @@ -1597,7 +1660,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { // Check if network exists NetworkVO network = _networksDao.findById(networkId); - if (network == null) { + if (network == null) { InvalidParameterValueException ex = new InvalidParameterValueException("Network with specified id doesn't exist"); ex.addProxyObject("networks", networkId, "networkId"); throw ex; @@ -1607,9 +1670,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (!(network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup)) { throw new InvalidParameterValueException("Network is not in the right state to be restarted. Correct states are: " + Network.State.Implemented + ", " + Network.State.Setup); } - + if (network.getBroadcastDomainType() == BroadcastDomainType.Lswitch ) { - /** + /** * Unable to restart these networks now. * TODO Restarting a SDN based network requires updating the nics and the configuration * in the controller. This requires a non-trivial rewrite of the restart procedure. @@ -1635,15 +1698,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return _networksDao.getActiveNicsIn(networkId); } - - - + + + protected Map getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) { if (!areServicesSupportedByNetworkOffering(offering.getId(), service)) { - // TBD: We should be sending networkOfferingId and not the offering object itself. + // TBD: We should be sending networkOfferingId and not the offering object itself. throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the network offering " + offering); } @@ -1676,14 +1739,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return serviceCapabilities; } - - + + @Override public IpAddress getIp(long ipAddressId) { return _ipAddressDao.findById(ipAddressId); } - + protected boolean providersConfiguredForExternalNetworking(Collection providers) { for(String providerStr : providers){ Provider provider = Network.Provider.getProvider(providerStr); @@ -1707,32 +1770,32 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return false; } - + protected boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services) { return (_ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(networkOfferingId, services)); } - + protected boolean areServicesSupportedInNetwork(long networkId, Service... services) { return (_ntwkSrvcDao.areServicesSupportedInNetwork(networkId, services)); } - - - - + + + + private boolean checkForNonStoppedVmInNetwork(long networkId) { - List vms = _userVmDao.listByNetworkIdAndStates(networkId, VirtualMachine.State.Starting, + List vms = _userVmDao.listByNetworkIdAndStates(networkId, VirtualMachine.State.Starting, VirtualMachine.State.Running, VirtualMachine.State.Migrating, VirtualMachine.State.Stopping); return vms.isEmpty(); } - + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NETWORK_UPDATE, eventDescription = "updating network", async = true) - public Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, + public Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, User callerUser, String domainSuffix, Long networkOfferingId, Boolean changeCidr, String guestVmCidr) { boolean restartNetwork = false; @@ -1744,7 +1807,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { ex.addProxyObject("networks", networkId, "networkId"); throw ex; } - + //perform below validation if the network is vpc network if (network.getVpcId() != null && networkOfferingId != null) { Vpc vpc = _vpcMgr.getVpc(network.getVpcId()); @@ -1766,7 +1829,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (network.getTrafficType() != Networks.TrafficType.Guest) { throw new InvalidParameterValueException("Can't allow networks which traffic type is not " + TrafficType.Guest); } - + _accountMgr.checkAccess(callerAccount, null, true, network); if (name != null) { @@ -1790,14 +1853,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (networkOfferingId != null) { if (networkOffering == null || networkOffering.isSystemOnly()) { InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find network offering with specified id"); - ex.addProxyObject(networkOffering, networkOfferingId, "networkOfferingId"); + ex.addProxyObject(networkOffering, networkOfferingId, "networkOfferingId"); throw ex; } - + // network offering should be in Enabled state if (networkOffering.getState() != NetworkOffering.State.Enabled) { InvalidParameterValueException ex = new InvalidParameterValueException("Network offering with specified id is not in " + NetworkOffering.State.Enabled + " state, can't upgrade to it"); - ex.addProxyObject(networkOffering, networkOfferingId, "networkOfferingId"); + ex.addProxyObject(networkOffering, networkOfferingId, "networkOfferingId"); throw ex; } //can't update from vpc to non-vpc network offering @@ -1811,7 +1874,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (networkOfferingId != oldNetworkOfferingId) { Collection newProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(networkOffering, network.getPhysicalNetworkId()).values(); Collection oldProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(oldNtwkOff, network.getPhysicalNetworkId()).values(); - + if (providersConfiguredForExternalNetworking(newProviders) != providersConfiguredForExternalNetworking(oldProviders) && !changeCidr) { throw new InvalidParameterValueException("Updating network failed since guest CIDR needs to be changed!"); @@ -1819,7 +1882,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (changeCidr) { if (!checkForNonStoppedVmInNetwork(network.getId())) { InvalidParameterValueException ex = new InvalidParameterValueException("All user vm of network of specified id should be stopped before changing CIDR!"); - ex.addProxyObject(network, networkId, "networkId"); + ex.addProxyObject(network, networkId, "networkId"); throw ex; } } @@ -1952,7 +2015,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (!_networkMgr.shutdownNetworkElementsAndResources(context, true, network)) { s_logger.warn("Failed to shutdown the network elements and resources as a part of network restart: " + network); CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of update to network of specified id"); - ex.addProxyObject(network, networkId, "networkId"); + ex.addProxyObject(network, networkId, "networkId"); throw ex; } } else { @@ -1971,13 +2034,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (!_networkMgr.shutdownNetwork(network.getId(), context, true)) { s_logger.warn("Failed to shutdown the network as a part of update to network with specified id"); CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network as a part of update of specified network id"); - ex.addProxyObject(network, networkId, "networkId"); + ex.addProxyObject(network, networkId, "networkId"); throw ex; } } } else { CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of update to network with specified id; network is in wrong state: " + network.getState()); - ex.addProxyObject(network, networkId, "networkId"); + ex.addProxyObject(network, networkId, "networkId"); throw ex; } } @@ -2039,7 +2102,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } catch (Exception ex) { s_logger.warn("Failed to implement network " + network + " elements and resources as a part of network update due to ", ex); CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id) elements and resources as a part of network update"); - e.addProxyObject(network, networkId, "networkId"); + e.addProxyObject(network, networkId, "networkId"); throw e; } } @@ -2072,7 +2135,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { protected Set getAvailableIps(Network network, String requestedIp) { String[] cidr = network.getCidr().split("/"); List ips = _nicDao.listIpAddressInNetwork(network.getId()); - Set usedIps = new TreeSet(); + Set usedIps = new TreeSet(); for (String ip : ips) { if (requestedIp != null && requestedIp.equals(ip)) { @@ -2092,7 +2155,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } - + protected boolean canUpgrade(Network network, long oldNetworkOfferingId, long newNetworkOfferingId) { NetworkOffering oldNetworkOffering = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId); NetworkOffering newNetworkOffering = _networkOfferingDao.findById(newNetworkOfferingId); @@ -2162,12 +2225,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return canIpsUseOffering(publicIps, newNetworkOfferingId); } - + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_CREATE, eventDescription = "Creating Physical Network", create = true) - public PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List + public PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List isolationMethods, String broadcastDomainRangeStr, Long domainId, List tags, String name) { // Check if zone exists @@ -2272,13 +2335,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { // add security group provider to the physical network addDefaultSecurityGroupProviderToPhysicalNetwork(pNetwork.getId()); - + // add VPCVirtualRouter as the defualt network service provider addDefaultVpcVirtualRouterToPhysicalNetwork(pNetwork.getId()); // add baremetal as the defualt network service provider /* addDefaultBaremetalProvidersToPhysicalNetwork(pNetwork.getId()); */ - + txn.commit(); return pNetwork; } catch (Exception ex) { @@ -2317,7 +2380,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { PhysicalNetworkVO network = _physicalNetworkDao.findById(id); if (network == null) { InvalidParameterValueException ex = new InvalidParameterValueException("Physical Network with specified id doesn't exist in the system"); - ex.addProxyObject(network, id, "physicalNetworkId"); + ex.addProxyObject(network, id, "physicalNetworkId"); throw ex; } @@ -2325,7 +2388,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { DataCenter zone = _dcDao.findById(network.getDataCenterId()); if (zone == null) { InvalidParameterValueException ex = new InvalidParameterValueException("Zone with id=" + network.getDataCenterId() + " doesn't exist in the system"); - ex.addProxyObject(zone, network.getDataCenterId(), "dataCenterId"); + ex.addProxyObject(zone, network.getDataCenterId(), "dataCenterId"); throw ex; } if (newVnetRangeString != null) { @@ -2598,7 +2661,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId); if (pNetwork == null) { InvalidParameterValueException ex = new InvalidParameterValueException("Physical Network with specified id doesn't exist in the system"); - ex.addProxyObject(pNetwork, physicalNetworkId, "physicalNetworkId"); + ex.addProxyObject(pNetwork, physicalNetworkId, "physicalNetworkId"); throw ex; } @@ -2625,7 +2688,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { // delete service providers List providers = _pNSPDao.listBy(physicalNetworkId); - + for(PhysicalNetworkServiceProviderVO provider : providers){ try { deleteNetworkServiceProvider(provider.getId()); @@ -2642,7 +2705,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { _pNTrafficTypeDao.deleteTrafficTypes(physicalNetworkId); boolean success = _physicalNetworkDao.remove(physicalNetworkId); - + txn.commit(); return success; @@ -2994,7 +3057,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } } - + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_SERVICE_PROVIDER_CREATE, eventDescription = "Creating Physical Network ServiceProvider", create = true) @@ -3013,7 +3076,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { PhysicalNetworkVO destNetwork = _physicalNetworkDao.findById(destinationPhysicalNetworkId); if (destNetwork == null) { InvalidParameterValueException ex = new InvalidParameterValueException("Destination Physical Network with specified id doesn't exist in the system"); - ex.addProxyObject(destNetwork, destinationPhysicalNetworkId, "destinationPhysicalNetworkId"); + ex.addProxyObject(destNetwork, destinationPhysicalNetworkId, "destinationPhysicalNetworkId"); throw ex; } } @@ -3255,7 +3318,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } else { pNtwks = _physicalNetworkDao.listByZone(zoneId); } - + if (pNtwks.isEmpty()) { throw new InvalidParameterValueException("Unable to find physical network in zone id=" + zoneId); } @@ -3282,8 +3345,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } } - - + + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_CREATE, eventDescription = "Creating Physical Network TrafficType", create = true) @@ -3448,7 +3511,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return new Pair, Integer>(result.first(), result.second()); } - + @@ -3475,23 +3538,23 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (networkElement == null) { throw new CloudRuntimeException("Unable to find the Network Element implementing the VirtualRouter Provider"); } - + VirtualRouterElement element = (VirtualRouterElement)networkElement; element.addElement(nsp.getId(), VirtualRouterProviderType.VirtualRouter); return nsp; } - + protected PhysicalNetworkServiceProvider addDefaultVpcVirtualRouterToPhysicalNetwork(long physicalNetworkId) { - PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, + PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.VPCVirtualRouter.getName(), null, null); - + NetworkElement networkElement = _networkModel.getElementImplementingProvider(Network.Provider.VPCVirtualRouter.getName()); if (networkElement == null) { throw new CloudRuntimeException("Unable to find the Network Element implementing the VPCVirtualRouter Provider"); } - + VpcVirtualRouterElement element = (VpcVirtualRouterElement)networkElement; element.addElement(nsp.getId(), VirtualRouterProviderType.VPCVirtualRouter); @@ -3500,7 +3563,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { protected PhysicalNetworkServiceProvider addDefaultSecurityGroupProviderToPhysicalNetwork(long physicalNetworkId) { - PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, + PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.SecurityGroupProvider.getName(), null, null); return nsp; @@ -3510,13 +3573,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { PhysicalNetworkVO pvo = _physicalNetworkDao.findById(physicalNetworkId); DataCenterVO dvo = _dcDao.findById(pvo.getDataCenterId()); if (dvo.getNetworkType() == NetworkType.Basic) { - + // Baremetal is currently disabled /* addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalDhcpProvider", null, null); addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalPxeProvider", null, null); addProviderToPhysicalNetwork(physicalNetworkId, "BaremetaUserdataProvider", null, null); -*/ +*/ } return null; } @@ -3530,13 +3593,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } } - - + + private boolean getAllowSubdomainAccessGlobal() { return _allowSubdomainNetworkAccess; } - + @Override public List> listTrafficTypeImplementor(ListTrafficTypeImplementorsCmd cmd) { @@ -3561,7 +3624,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return results; } - + @Override @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true) public IpAddress associateIPToNetwork(long ipId, long networkId) throws InsufficientAddressCapacityException, @@ -3577,20 +3640,20 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { " to VPC.Specify vpcId to associate ip address to VPC"); } return _networkMgr.associateIPToGuestNetwork(ipId, networkId, true); - + } - + @Override @DB public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan, String startIp, String endIp, String gateway, String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat) throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { - + Account owner = _accountMgr.getAccount(networkOwnerId); - + // Get system network offeirng NetworkOfferingVO ntwkOff = findSystemNetworkOffering(NetworkOffering.SystemPrivateGatewayNetworkOffering); - + // Validate physical network PhysicalNetwork pNtwk = _physicalNetworkDao.findById(physicalNetworkId); if (pNtwk == null) { @@ -3599,7 +3662,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { ex.addProxyObject("physical_network", physicalNetworkId, "physicalNetworkId"); throw ex; } - + // VALIDATE IP INFO // if end ip is not specified, default it to startIp if (!NetUtils.isValidIp(startIp)) { @@ -3620,49 +3683,49 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask); - - + + Transaction txn = Transaction.currentTxn(); txn.start(); - + //lock datacenter as we need to get mac address seq from there DataCenterVO dc = _dcDao.lockRow(pNtwk.getDataCenterId(), true); - + //check if we need to create guest network Network privateNetwork = _networksDao.getPrivateNetwork(BroadcastDomainType.Vlan.toUri(vlan).toString(), cidr, networkOwnerId, pNtwk.getDataCenterId()); if (privateNetwork == null) { //create Guest network - privateNetwork = _networkMgr.createGuestNetwork(ntwkOff.getId(), networkName, displayText, gateway, cidr, vlan, + privateNetwork = _networkMgr.createGuestNetwork(ntwkOff.getId(), networkName, displayText, gateway, cidr, vlan, null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, null, null, null); s_logger.debug("Created private network " + privateNetwork); } else { s_logger.debug("Private network already exists: " + privateNetwork); } - + //add entry to private_ip_address table PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkId(privateNetwork.getId(), startIp); if (privateIp != null) { throw new InvalidParameterValueException("Private ip address " + startIp + " already used for private gateway" + " in zone " + _configMgr.getZone(pNtwk.getDataCenterId()).getName()); } - + Long mac = dc.getMacAddress(); Long nextMac = mac + 1; dc.setMacAddress(nextMac); privateIp = new PrivateIpVO(startIp, privateNetwork.getId(), nextMac, vpcId, sourceNat); _privateIpDao.persist(privateIp); - + _dcDao.update(dc.getId(), dc); - + txn.commit(); s_logger.debug("Private network " + privateNetwork + " is created"); return privateNetwork; } - + private NetworkOfferingVO findSystemNetworkOffering(String offeringName) { List allOfferings = _networkOfferingDao.listSystemNetworkOfferings(); for (NetworkOfferingVO offer: allOfferings){ diff --git a/server/src/com/cloud/servlet/ConsoleProxyServlet.java b/server/src/com/cloud/servlet/ConsoleProxyServlet.java index ebb91746268..097986bda62 100644 --- a/server/src/com/cloud/servlet/ConsoleProxyServlet.java +++ b/server/src/com/cloud/servlet/ConsoleProxyServlet.java @@ -73,7 +73,7 @@ public class ConsoleProxyServlet extends HttpServlet { @Inject AccountManager _accountMgr; @Inject VirtualMachineManager _vmMgr; @Inject ManagementServer _ms; - @Inject IdentityService _identityService; + @Inject IdentityService _identityService; static ManagementServer s_ms; @@ -81,13 +81,13 @@ public class ConsoleProxyServlet extends HttpServlet { public ConsoleProxyServlet() { } - + @Override public void init(ServletConfig config) throws ServletException { - SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext()); + SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext()); s_ms = _ms; } - + @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) { doGet(req, resp); @@ -274,7 +274,7 @@ public class ConsoleProxyServlet extends HttpServlet { private void handleAuthRequest(HttpServletRequest req, HttpServletResponse resp, long vmId) { - // TODO authentication channel between console proxy VM and management server needs to be secured, + // TODO authentication channel between console proxy VM and management server needs to be secured, // the data is now being sent through private network, but this is apparently not enough VMInstanceVO vm = _vmMgr.findById(vmId); if(vm == null) { @@ -334,11 +334,11 @@ public class ConsoleProxyServlet extends HttpServlet { private String getEncryptorPassword() { String key = _ms.getEncryptionKey(); String iv = _ms.getEncryptionIV(); - + ConsoleProxyPasswordBasedEncryptor.KeyIVPair keyIvPair = new ConsoleProxyPasswordBasedEncryptor.KeyIVPair(key, iv); return _gson.toJson(keyIvPair); } - + private String composeThumbnailUrl(String rootUrl, VMInstanceVO vm, HostVO hostVo, int w, int h) { StringBuffer sb = new StringBuffer(rootUrl); @@ -385,8 +385,7 @@ public class ConsoleProxyServlet extends HttpServlet { Ternary parsedHostInfo = parseHostInfo(portInfo.first()); String sid = vm.getVncPassword(); - String tag = String.valueOf(vm.getId()); - tag = _identityService.getIdentityUuid("vm_instance", tag); + String tag = vm.getUuid(); String ticket = genAccessTicket(host, String.valueOf(portInfo.second()), sid, tag); ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor(getEncryptorPassword()); ConsoleProxyClientParam param = new ConsoleProxyClientParam(); @@ -473,12 +472,12 @@ public class ConsoleProxyServlet extends HttpServlet { } catch (PermissionDeniedException ex) { if (accountObj.getType() == Account.ACCOUNT_TYPE_NORMAL) { if (s_logger.isDebugEnabled()) { - s_logger.debug("VM access is denied. VM owner account " + vm.getAccountId() + s_logger.debug("VM access is denied. VM owner account " + vm.getAccountId() + " does not match the account id in session " + accountObj.getId() + " and caller is a normal user"); } } else if(accountObj.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || accountObj.getType() == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN) { if(s_logger.isDebugEnabled()) { - s_logger.debug("VM access is denied. VM owner account " + vm.getAccountId() + s_logger.debug("VM access is denied. VM owner account " + vm.getAccountId() + " does not match the account id in session " + accountObj.getId() + " and the domain-admin caller does not manage the target domain"); } } @@ -515,7 +514,7 @@ public class ConsoleProxyServlet extends HttpServlet { account = _accountMgr.getAccount(user.getAccountId()); } - if ((user == null) || (user.getRemoved() != null) || !user.getState().equals(Account.State.enabled) + if ((user == null) || (user.getRemoved() != null) || !user.getState().equals(Account.State.enabled) || (account == null) || !account.getState().equals(Account.State.enabled)) { s_logger.warn("Deleted/Disabled/Locked user with id=" + userId + " attempting to access public API"); return false; @@ -586,7 +585,7 @@ public class ConsoleProxyServlet extends HttpServlet { if (!user.getState().equals(Account.State.enabled) || !account.getState().equals(Account.State.enabled)) { s_logger.debug("disabled or locked user accessing the api, userid = " + user.getId() + "; name = " + user.getUsername() + "; state: " + user.getState() + "; accountState: " + account.getState()); return false; - } + } // verify secret key exists secretKey = user.getSecretKey(); @@ -632,10 +631,10 @@ public class ConsoleProxyServlet extends HttpServlet { case '>': sb.append(">"); break; case '&': sb.append("&"); break; case '"': sb.append("""); break; - case ' ': sb.append(" ");break; + case ' ': sb.append(" ");break; default: sb.append(c); break; } } return sb.toString(); - } + } } diff --git a/server/test/com/cloud/network/security/SecurityGroupManagerTestConfiguration.java b/server/test/com/cloud/network/security/SecurityGroupManagerTestConfiguration.java index b3a9ff12dab..e2e9d68c013 100644 --- a/server/test/com/cloud/network/security/SecurityGroupManagerTestConfiguration.java +++ b/server/test/com/cloud/network/security/SecurityGroupManagerTestConfiguration.java @@ -19,6 +19,7 @@ package com.cloud.network.security; import java.io.IOException; +import org.apache.cloudstack.test.utils.SpringUtils; import org.mockito.Mockito; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -60,7 +61,6 @@ import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; import com.cloud.user.dao.AccountDaoImpl; -import com.cloud.utils.component.SpringComponentScanUtils; import com.cloud.vm.UserVmManager; import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.dao.NicDaoImpl; @@ -151,7 +151,7 @@ public class SecurityGroupManagerTestConfiguration { public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { mdr.getClassMetadata().getClassName(); ComponentScan cs = SecurityGroupManagerTestConfiguration.class.getAnnotation(ComponentScan.class); - return SpringComponentScanUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); } } diff --git a/server/test/com/cloud/snapshot/SnapshotDaoTestConfiguration.java b/server/test/com/cloud/snapshot/SnapshotDaoTestConfiguration.java index cc410dbc4ca..6695edc0225 100644 --- a/server/test/com/cloud/snapshot/SnapshotDaoTestConfiguration.java +++ b/server/test/com/cloud/snapshot/SnapshotDaoTestConfiguration.java @@ -19,6 +19,7 @@ package com.cloud.snapshot; import java.io.IOException; +import org.apache.cloudstack.test.utils.SpringUtils; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; @@ -36,7 +37,6 @@ import com.cloud.host.dao.HostTagsDaoImpl; import com.cloud.storage.dao.SnapshotDaoImpl; import com.cloud.storage.dao.VolumeDaoImpl; import com.cloud.tags.dao.ResourceTagsDaoImpl; -import com.cloud.utils.component.SpringComponentScanUtils; import com.cloud.vm.dao.NicDaoImpl; import com.cloud.vm.dao.VMInstanceDaoImpl; @@ -65,7 +65,7 @@ public class SnapshotDaoTestConfiguration { public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { mdr.getClassMetadata().getClassName(); ComponentScan cs = SnapshotDaoTestConfiguration.class.getAnnotation(ComponentScan.class); - return SpringComponentScanUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); } } diff --git a/server/test/com/cloud/storage/dao/StoragePoolDaoTestConfiguration.java b/server/test/com/cloud/storage/dao/StoragePoolDaoTestConfiguration.java index 58de4d2730b..2f79ff04258 100644 --- a/server/test/com/cloud/storage/dao/StoragePoolDaoTestConfiguration.java +++ b/server/test/com/cloud/storage/dao/StoragePoolDaoTestConfiguration.java @@ -20,6 +20,7 @@ package com.cloud.storage.dao; import java.io.IOException; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl; +import org.apache.cloudstack.test.utils.SpringUtils; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; @@ -28,7 +29,6 @@ import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.filter.TypeFilter; -import com.cloud.utils.component.SpringComponentScanUtils; @Configuration @ComponentScan(basePackageClasses={ @@ -46,7 +46,7 @@ public class StoragePoolDaoTestConfiguration { public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { mdr.getClassMetadata().getClassName(); ComponentScan cs = StoragePoolDaoTestConfiguration.class.getAnnotation(ComponentScan.class); - return SpringComponentScanUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); } } diff --git a/server/test/com/cloud/vm/dao/UserVmCloneSettingDaoTestConfiguration.java b/server/test/com/cloud/vm/dao/UserVmCloneSettingDaoTestConfiguration.java index 6e22e174f58..3bd4df8543f 100644 --- a/server/test/com/cloud/vm/dao/UserVmCloneSettingDaoTestConfiguration.java +++ b/server/test/com/cloud/vm/dao/UserVmCloneSettingDaoTestConfiguration.java @@ -19,6 +19,7 @@ package com.cloud.vm.dao; import java.io.IOException; +import org.apache.cloudstack.test.utils.SpringUtils; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; @@ -27,7 +28,6 @@ import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.filter.TypeFilter; -import com.cloud.utils.component.SpringComponentScanUtils; import com.cloud.vm.dao.UserVmCloneSettingDaoImpl; @Configuration @@ -45,7 +45,7 @@ public class UserVmCloneSettingDaoTestConfiguration { public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { mdr.getClassMetadata().getClassName(); ComponentScan cs = UserVmCloneSettingDaoTestConfiguration.class.getAnnotation(ComponentScan.class); - return SpringComponentScanUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); } } diff --git a/server/test/com/cloud/vm/dao/UserVmDaoTestConfiguration.java b/server/test/com/cloud/vm/dao/UserVmDaoTestConfiguration.java index 6a63fabd44b..7af772c1b17 100644 --- a/server/test/com/cloud/vm/dao/UserVmDaoTestConfiguration.java +++ b/server/test/com/cloud/vm/dao/UserVmDaoTestConfiguration.java @@ -19,6 +19,7 @@ package com.cloud.vm.dao; import java.io.IOException; +import org.apache.cloudstack.test.utils.SpringUtils; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; @@ -27,7 +28,6 @@ import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.filter.TypeFilter; -import com.cloud.utils.component.SpringComponentScanUtils; @Configuration @ComponentScan(basePackageClasses={ @@ -43,7 +43,7 @@ public class UserVmDaoTestConfiguration { public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { mdr.getClassMetadata().getClassName(); ComponentScan cs = UserVmDaoTestConfiguration.class.getAnnotation(ComponentScan.class); - return SpringComponentScanUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); } } diff --git a/server/test/com/cloud/vpc/VpcTestConfiguration.java b/server/test/com/cloud/vpc/VpcTestConfiguration.java index b1f2f80c076..7ae83f3a9c9 100644 --- a/server/test/com/cloud/vpc/VpcTestConfiguration.java +++ b/server/test/com/cloud/vpc/VpcTestConfiguration.java @@ -19,6 +19,7 @@ package com.cloud.vpc; import java.io.IOException; +import org.apache.cloudstack.test.utils.SpringUtils; import org.mockito.Mockito; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -91,7 +92,6 @@ import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.user.AccountManager; import com.cloud.user.dao.AccountDaoImpl; import com.cloud.user.dao.UserStatisticsDaoImpl; -import com.cloud.utils.component.SpringComponentScanUtils; import com.cloud.vm.UserVmManager; import com.cloud.vm.dao.DomainRouterDaoImpl; import com.cloud.vm.dao.NicDaoImpl; @@ -236,7 +236,7 @@ public class VpcTestConfiguration { public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { mdr.getClassMetadata().getClassName(); ComponentScan cs = VpcTestConfiguration.class.getAnnotation(ComponentScan.class); - return SpringComponentScanUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); } } } diff --git a/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java b/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java index f9c5728c4c2..484b044e28e 100644 --- a/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java +++ b/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java @@ -24,6 +24,7 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.when; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -32,13 +33,23 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.affinity.dao.AffinityGroupDao; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; +import org.apache.cloudstack.test.utils.SpringUtils; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.ComponentScan.Filter; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.classreading.MetadataReaderFactory; +import org.springframework.core.type.filter.TypeFilter; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; import com.cloud.event.EventUtils; import com.cloud.event.EventVO; @@ -48,6 +59,7 @@ import com.cloud.exception.ResourceInUseException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.AccountService; import com.cloud.user.AccountVO; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; @@ -57,7 +69,7 @@ import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.UserVmDao; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations = "classpath:/affinityContext.xml") +@ContextConfiguration(loader = AnnotationConfigContextLoader.class) public class AffinityApiUnitTest { @Inject @@ -188,4 +200,57 @@ public class AffinityApiUnitTest { _affinityService.updateVMAffinityGroups(10L, affinityGroupIds); } + @Configuration + @ComponentScan(basePackageClasses = {AffinityGroupServiceImpl.class, EventUtils.class}, includeFilters = {@Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)}, useDefaultFilters = false) + public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration { + + @Bean + public AccountDao accountDao() { + return Mockito.mock(AccountDao.class); + } + + @Bean + public AccountService accountService() { + return Mockito.mock(AccountService.class); + } + + @Bean + public AffinityGroupProcessor affinityGroupProcessor() { + return Mockito.mock(AffinityGroupProcessor.class); + } + + @Bean + public AffinityGroupDao affinityGroupDao() { + return Mockito.mock(AffinityGroupDao.class); + } + + @Bean + public AffinityGroupVMMapDao affinityGroupVMMapDao() { + return Mockito.mock(AffinityGroupVMMapDao.class); + } + + @Bean + public AccountManager accountManager() { + return Mockito.mock(AccountManager.class); + } + + @Bean + public EventDao eventDao() { + return Mockito.mock(EventDao.class); + } + + @Bean + public UserVmDao userVMDao() { + return Mockito.mock(UserVmDao.class); + } + + public static class Library implements TypeFilter { + + @Override + public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { + ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + } + } + } } diff --git a/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java b/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java index d47deaa7018..6f52397251b 100644 --- a/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java +++ b/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java @@ -27,6 +27,7 @@ import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl; import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; +import org.apache.cloudstack.test.utils.SpringUtils; import org.mockito.Mockito; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -94,7 +95,6 @@ import com.cloud.storage.swift.SwiftManager; import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.user.dao.AccountDaoImpl; import com.cloud.user.dao.UserDaoImpl; -import com.cloud.utils.component.SpringComponentScanUtils; import com.cloud.vm.dao.InstanceGroupDaoImpl; import com.cloud.vm.dao.NicDaoImpl; import com.cloud.vm.dao.NicSecondaryIpDaoImpl; @@ -338,7 +338,7 @@ public class ChildTestConfiguration { public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { mdr.getClassMetadata().getClassName(); ComponentScan cs = ChildTestConfiguration.class.getAnnotation(ComponentScan.class); - return SpringComponentScanUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); } } diff --git a/server/test/resources/affinityContext.xml b/server/test/resources/affinityContext.xml deleted file mode 100644 index d41a63d648b..00000000000 --- a/server/test/resources/affinityContext.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/services/console-proxy/pom.xml b/services/console-proxy/pom.xml index 2c9e2e6e2c7..3aac7b25a80 100644 --- a/services/console-proxy/pom.xml +++ b/services/console-proxy/pom.xml @@ -23,9 +23,9 @@ pom org.apache.cloudstack - cloudstack + cloudstack-services 4.2.0-SNAPSHOT - ../../pom.xml + ../pom.xml install diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml index 0797c9895f7..eb6c0ee9b50 100644 --- a/services/secondary-storage/pom.xml +++ b/services/secondary-storage/pom.xml @@ -18,13 +18,13 @@ --> 4.0.0 - cloudstack-service-secondary-storage + cloud-secondary-storage Apache CloudStack Secondary Storage Service org.apache.cloudstack - cloudstack + cloudstack-services 4.2.0-SNAPSHOT - ../../pom.xml + ../pom.xml diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml index c0505664486..25134a8968b 100644 --- a/tools/marvin/pom.xml +++ b/tools/marvin/pom.xml @@ -1,15 +1,14 @@ + 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. --> + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 cloud-marvin Apache CloudStack marvin @@ -35,7 +34,7 @@ - + Deleting ${project.artifactId} API sources @@ -83,7 +82,7 @@ - + marvin.sync @@ -160,6 +159,26 @@ + + org.codehaus.gmaven + gmaven-plugin + 1.5 + + + setproperty + validate + + execute + + + + pom.properties['resolved.basedir']=project.basedir.absolutePath.replace('\','/').replace('D:','/cyg/d'); + pom.properties['resolved.userdir']='${user.dir}'.replace('\','/').replace('D:','/cyg/d'); + + + + + org.codehaus.mojo exec-maven-plugin @@ -177,18 +196,18 @@ deployAndRun.py -c - ${user.dir}/${marvin.config} + ${resolved.userdir}/${marvin.config} -t /tmp/t.log -r /tmp/r.log -f - ${basedir}/marvin/testSetupSuccess.py + ${resolved.basedir}/marvin/testSetupSuccess.py - - + + diff --git a/usage/test/com/cloud/usage/UsageManagerTestConfiguration.java b/usage/test/com/cloud/usage/UsageManagerTestConfiguration.java index d7cf04644b8..1d3ed7b245d 100644 --- a/usage/test/com/cloud/usage/UsageManagerTestConfiguration.java +++ b/usage/test/com/cloud/usage/UsageManagerTestConfiguration.java @@ -25,7 +25,8 @@ import com.cloud.usage.dao.*; import com.cloud.usage.parser.*; import com.cloud.user.dao.AccountDaoImpl; import com.cloud.user.dao.UserStatisticsDaoImpl; -import com.cloud.utils.component.SpringComponentScanUtils; + +import org.apache.cloudstack.test.utils.SpringUtils; import org.mockito.Mockito; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -87,7 +88,7 @@ public class UsageManagerTestConfiguration { public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { mdr.getClassMetadata().getClassName(); ComponentScan cs = UsageManagerTestConfiguration.class.getAnnotation(ComponentScan.class); - return SpringComponentScanUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); } } diff --git a/utils/src/com/cloud/utils/AnnotationHelper.java b/utils/src/com/cloud/utils/AnnotationHelper.java index 954b870eb76..e7a6166677e 100755 --- a/utils/src/com/cloud/utils/AnnotationHelper.java +++ b/utils/src/com/cloud/utils/AnnotationHelper.java @@ -20,40 +20,38 @@ import javax.persistence.Table; import org.apache.log4j.Logger; -import com.cloud.utils.exception.CSExceptionErrorCode; - public class AnnotationHelper extends Object { // This class contains routines to help query annotation elements of objects. - + public static final Logger s_logger = Logger.getLogger(AnnotationHelper.class.getName()); - + public static String getTableName(Object proxyObj) { // The cglib class is generated by cglib during runtime. - + Class curClass = proxyObj.getClass(); if (curClass == null) { - s_logger.info("\nCould not retrieve class information for proxy object\n"); + s_logger.trace("Could not retrieve class information for proxy object"); return null; } - + while (curClass.getSuperclass() != null && curClass.getSuperclass().getName() != "java.lang.Object") { curClass = curClass.getSuperclass(); } // At this point, curClass is the root base class of proxyObj's class, and curClass is not java.lang.Object. - Table tabObj = (Table)curClass.getAnnotation(Table.class); + Table tabObj = curClass.getAnnotation(Table.class); if (tabObj == null) { - s_logger.info("\n" + curClass + "does not have a Table annotation\n"); + s_logger.trace(curClass + "does not have a Table annotation"); return null; } - + return tabObj.name(); } - + } - - - - + + + + diff --git a/utils/src/com/cloud/utils/component/SpringComponentScanUtils.java b/utils/src/com/cloud/utils/component/SpringComponentScanUtils.java deleted file mode 100644 index 28b84e68ce9..00000000000 --- a/utils/src/com/cloud/utils/component/SpringComponentScanUtils.java +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// 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.component; - -import org.springframework.context.annotation.ComponentScan; - -import com.cloud.utils.exception.CloudRuntimeException; - -public class SpringComponentScanUtils { - - public static boolean includedInBasePackageClasses(String clazzName, ComponentScan cs) { - Class clazzToCheck; - try { - clazzToCheck = Class.forName(clazzName); - } catch (ClassNotFoundException e) { - throw new CloudRuntimeException("Unable to find " + clazzName); - } - Class[] clazzes = cs.basePackageClasses(); - for (Class clazz : clazzes) { - if (clazzToCheck.isAssignableFrom(clazz)) { - return true; - } - } - return false; - } -} diff --git a/utils/src/org/apache/cloudstack/test/utils/SpringUtils.java b/utils/src/org/apache/cloudstack/test/utils/SpringUtils.java new file mode 100644 index 00000000000..220bd80e8d3 --- /dev/null +++ b/utils/src/org/apache/cloudstack/test/utils/SpringUtils.java @@ -0,0 +1,113 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// 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.test.utils; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; + +import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.component.ComponentInstantiationPostProcessor; +import com.cloud.utils.component.ComponentMethodInterceptor; +import com.cloud.utils.db.TransactionContextBuilder; +import com.cloud.utils.exception.CloudRuntimeException; + +public class SpringUtils { + + /** + * This method allows you to use @ComponentScan for your unit testing but + * it limits the scope of the classes found to the class specified in + * the @ComponentScan annotation. + * + * Without using this method, the default behavior of @ComponentScan is + * to actually scan in the package of the class specified rather than + * only the class. This can cause extra classes to be loaded which causes + * the classes these extra classes depend on to be loaded. The end effect + * is often most of the project gets loaded. + * + * In order to use this method properly, you must do the following:
  • + * - Specify @ComponentScan with basePackageClasses, includeFilters, and + * useDefaultFilters=true. See the following example. + * + *
    +     *     @ComponentScan(basePackageClasses={AffinityGroupServiceImpl.class, EventUtils.class},
    +     *     includeFilters={@Filter(value=TestConfiguration.Library.class, type=FilterType.CUSTOM)},
    +     *     useDefaultFilters=false)
    +     * 
    + * + * - Create a Library class and use that to call this method. See the + * following example. The Library class you define here is the Library + * class being added in the filter above. + * + *
    +     * public static class Library implements TypeFilter {
    +     *      @Override
    +     *      public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
    +     *          ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
    +     *          return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
    +     *      }
    +     * }
    +     * 
    + * + * @param clazzName name of the class that should be included in the Spring components + * @param cs ComponentScan annotation that was declared on the configuration + * + * @return + */ + public static boolean includedInBasePackageClasses(String clazzName, ComponentScan cs) { + Class clazzToCheck; + try { + clazzToCheck = Class.forName(clazzName); + } catch (ClassNotFoundException e) { + throw new CloudRuntimeException("Unable to find " + clazzName); + } + Class[] clazzes = cs.basePackageClasses(); + for (Class clazz : clazzes) { + if (clazzToCheck.isAssignableFrom(clazz)) { + return true; + } + } + return false; + } + + public static class CloudStackTestConfiguration { + + @Bean + public ComponentContext componentContext() { + return new ComponentContext(); + } + + @Bean + public TransactionContextBuilder transactionContextBuilder() { + return new TransactionContextBuilder(); + } + + @Bean + public ComponentInstantiationPostProcessor instantiatePostProcessor() { + ComponentInstantiationPostProcessor processor = new ComponentInstantiationPostProcessor(); + + List interceptors = new ArrayList(); + interceptors.add(new TransactionContextBuilder()); + processor.setInterceptors(interceptors); + + return processor; + } + } +} From e5d331ee58738dde8aa50d8a119d979b6d04d822 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Mon, 6 May 2013 06:31:47 -0700 Subject: [PATCH 10/71] Missing file and updated .gitignore --- .gitignore | 6 ++---- services/pom.xml | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 services/pom.xml diff --git a/.gitignore b/.gitignore index f41862895ec..016554a5f75 100644 --- a/.gitignore +++ b/.gitignore @@ -18,10 +18,7 @@ build/replace.properties build/build.number bin/ -cloudstack-proprietary/ -premium/ .lock-wscript -artifacts/ .waf-* waf-* target/ @@ -37,7 +34,7 @@ cloud-*.tar.bz2 *.egg-info/ *.prefs build.number -api.log.*.gz +*.log.*.gz cloud.log.*.* unittest deps/cloud.userlibraries @@ -59,6 +56,7 @@ tools/cli/build/ *.iso *.tar.gz *.tgz +.* target-eclipse awsapi/modules/* !.gitignore diff --git a/services/pom.xml b/services/pom.xml new file mode 100644 index 00000000000..805bcdb5e6d --- /dev/null +++ b/services/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + cloudstack-services + Apache CloudStack Cloud Services + pom + + org.apache.cloudstack + cloudstack + 4.2.0-SNAPSHOT + ../pom.xml + + + install + + + console-proxy + secondary-storage + + From 2639b9f91eaeefe46901598467fda34a520f52be Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Mon, 6 May 2013 10:34:22 -0700 Subject: [PATCH 11/71] Moved over the VLAN daos --- .../schema}/src/com/cloud/network/dao/AccountGuestVlanMapDao.java | 0 .../src/com/cloud/network/dao/AccountGuestVlanMapDaoImpl.java | 0 .../schema}/src/com/cloud/network/dao/AccountGuestVlanMapVO.java | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {server => engine/schema}/src/com/cloud/network/dao/AccountGuestVlanMapDao.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/AccountGuestVlanMapDaoImpl.java (100%) rename {server => engine/schema}/src/com/cloud/network/dao/AccountGuestVlanMapVO.java (100%) diff --git a/server/src/com/cloud/network/dao/AccountGuestVlanMapDao.java b/engine/schema/src/com/cloud/network/dao/AccountGuestVlanMapDao.java similarity index 100% rename from server/src/com/cloud/network/dao/AccountGuestVlanMapDao.java rename to engine/schema/src/com/cloud/network/dao/AccountGuestVlanMapDao.java diff --git a/server/src/com/cloud/network/dao/AccountGuestVlanMapDaoImpl.java b/engine/schema/src/com/cloud/network/dao/AccountGuestVlanMapDaoImpl.java similarity index 100% rename from server/src/com/cloud/network/dao/AccountGuestVlanMapDaoImpl.java rename to engine/schema/src/com/cloud/network/dao/AccountGuestVlanMapDaoImpl.java diff --git a/server/src/com/cloud/network/dao/AccountGuestVlanMapVO.java b/engine/schema/src/com/cloud/network/dao/AccountGuestVlanMapVO.java similarity index 100% rename from server/src/com/cloud/network/dao/AccountGuestVlanMapVO.java rename to engine/schema/src/com/cloud/network/dao/AccountGuestVlanMapVO.java From bc823f946c2493ab315a2b7e7ef7dccce9950994 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Mon, 6 May 2013 16:34:03 -0700 Subject: [PATCH 12/71] Fixed up the simulator to run with windows paths in cygwin --- .../com/cloud/simulator/MockSecStorageVO.java | 3 ++- .../cloud/simulator/MockStoragePoolVO.java | 3 ++- .../src/com/cloud/simulator/MockVolumeVO.java | 3 ++- server/pom.xml | 5 ---- test/integration/smoke/test_vm_life_cycle.py | 2 ++ tools/marvin/pom.xml | 24 +++++++++++++++++-- 6 files changed, 30 insertions(+), 10 deletions(-) diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecStorageVO.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecStorageVO.java index 532d2a7ff56..87905eedbd1 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecStorageVO.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecStorageVO.java @@ -48,6 +48,7 @@ public class MockSecStorageVO implements InternalIdentity { } + @Override public long getId() { return this.id; } @@ -57,7 +58,7 @@ public class MockSecStorageVO implements InternalIdentity { } public void setMountPoint(String mountPoint) { - this.mountPoint = mountPoint; + this.mountPoint = mountPoint.replace('\\', '/'); } public String getUrl() { diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockStoragePoolVO.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockStoragePoolVO.java index 06aa169a62a..7f1b7ccf610 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockStoragePoolVO.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockStoragePoolVO.java @@ -66,6 +66,7 @@ public class MockStoragePoolVO implements InternalIdentity { this.hostGuid = hostGuid; } + @Override public long getId() { return this.id; } @@ -91,7 +92,7 @@ public class MockStoragePoolVO implements InternalIdentity { } public void setMountPoint(String mountPoint) { - this.mountPoint = mountPoint; + this.mountPoint = mountPoint.replace('\\', '/'); } public long getCapacity() { diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVolumeVO.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVolumeVO.java index 6dd59e8507c..b7191b887f6 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVolumeVO.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVolumeVO.java @@ -66,6 +66,7 @@ public class MockVolumeVO implements InternalIdentity { @Enumerated(value=EnumType.STRING) private VMTemplateStorageResourceAssoc.Status status; + @Override public long getId() { return id; } @@ -90,7 +91,7 @@ public class MockVolumeVO implements InternalIdentity { } public void setPath(String path) { - this.path = path; + this.path = path.replace('\\', '/'); } public long getPoolId() { diff --git a/server/pom.xml b/server/pom.xml index 429d60819e3..808dd3eee0a 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -95,11 +95,6 @@ cloud-framework-events ${project.version} - - org.apache.cloudstack - cloud-utils - ${project.version} - install diff --git a/test/integration/smoke/test_vm_life_cycle.py b/test/integration/smoke/test_vm_life_cycle.py index ae36c648e0a..21c26357ab2 100644 --- a/test/integration/smoke/test_vm_life_cycle.py +++ b/test/integration/smoke/test_vm_life_cycle.py @@ -163,6 +163,8 @@ class TestDeployVM(cloudstackTestCase): cls.services["account"], domainid=domain.id ) + cls.debug(str("============" )) + cls.debug(cls.account.id) cls.service_offering = ServiceOffering.create( cls.apiclient, diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml index 25134a8968b..089c445ed9e 100644 --- a/tools/marvin/pom.xml +++ b/tools/marvin/pom.xml @@ -220,6 +220,26 @@ + + org.codehaus.gmaven + gmaven-plugin + 1.5 + + + setproperty + validate + + execute + + + + pom.properties['resolved.userdir']='${user.dir}'.replace('\','/').replace('D:','/cyg/d'); + pom.properties['resolved.marvin.config']='${marvin.config}'.replace('\','/').replace('D:','/cyg/d'); + + + + + org.codehaus.mojo exec-maven-plugin @@ -237,11 +257,11 @@ --with-marvin --marvin-config - ${user.dir}/${marvin.config} + ${resolved.user.dir}/${resolved.marvin.config} --load -a tags=${tag} - ${user.dir}/${test} + ${resolved.user.dir}/${test} -v From 5a6a1158fd1f99caf65718810a467562e09cba03 Mon Sep 17 00:00:00 2001 From: Dave Cahill Date: Fri, 19 Apr 2013 17:31:44 +0900 Subject: [PATCH 13/71] Add docs for MidoNet networking plugin [CLOUDSTACK-996] Signed-off-by: Dave Cahill --- docs/en-US/MidoNet_Plugin_Guide.ent | 22 ++++++ docs/en-US/MidoNet_Plugin_Guide.xml | 52 +++++++++++++ docs/en-US/plugin-midonet-about.xml | 27 +++++++ docs/en-US/plugin-midonet-features.xml | 57 ++++++++++++++ docs/en-US/plugin-midonet-introduction.xml | 26 +++++++ docs/en-US/plugin-midonet-preparations.xml | 90 ++++++++++++++++++++++ docs/en-US/plugin-midonet-provider.xml | 39 ++++++++++ docs/en-US/plugin-midonet-revisions.xml | 45 +++++++++++ docs/en-US/plugin-midonet-ui.xml | 65 ++++++++++++++++ docs/en-US/plugin-midonet-usage.xml | 29 +++++++ docs/publican-plugin-midonet.cfg | 28 +++++++ 11 files changed, 480 insertions(+) create mode 100644 docs/en-US/MidoNet_Plugin_Guide.ent create mode 100644 docs/en-US/MidoNet_Plugin_Guide.xml create mode 100644 docs/en-US/plugin-midonet-about.xml create mode 100644 docs/en-US/plugin-midonet-features.xml create mode 100644 docs/en-US/plugin-midonet-introduction.xml create mode 100644 docs/en-US/plugin-midonet-preparations.xml create mode 100644 docs/en-US/plugin-midonet-provider.xml create mode 100644 docs/en-US/plugin-midonet-revisions.xml create mode 100644 docs/en-US/plugin-midonet-ui.xml create mode 100644 docs/en-US/plugin-midonet-usage.xml create mode 100644 docs/publican-plugin-midonet.cfg diff --git a/docs/en-US/MidoNet_Plugin_Guide.ent b/docs/en-US/MidoNet_Plugin_Guide.ent new file mode 100644 index 00000000000..f31c40748c2 --- /dev/null +++ b/docs/en-US/MidoNet_Plugin_Guide.ent @@ -0,0 +1,22 @@ + + + + + + diff --git a/docs/en-US/MidoNet_Plugin_Guide.xml b/docs/en-US/MidoNet_Plugin_Guide.xml new file mode 100644 index 00000000000..86182e60b71 --- /dev/null +++ b/docs/en-US/MidoNet_Plugin_Guide.xml @@ -0,0 +1,52 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + + + + + + &PRODUCT; Plugin Guide for the MidoNet Plugin + Apache CloudStack + 4.2.0 + 1 + + + + Plugin Guide for the MidoNet Plugin. + + + + + + + + + + + + + + + + diff --git a/docs/en-US/plugin-midonet-about.xml b/docs/en-US/plugin-midonet-about.xml new file mode 100644 index 00000000000..dd9b3ad08e0 --- /dev/null +++ b/docs/en-US/plugin-midonet-about.xml @@ -0,0 +1,27 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + + + The MidoNet Plugin + + + diff --git a/docs/en-US/plugin-midonet-features.xml b/docs/en-US/plugin-midonet-features.xml new file mode 100644 index 00000000000..f242d63d0ee --- /dev/null +++ b/docs/en-US/plugin-midonet-features.xml @@ -0,0 +1,57 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + +
    + Features of the MidoNet Plugin + + + + In &PRODUCT; 4.2.0 only the KVM hypervisor is supported for use in combination with MidoNet. + + + + In &PRODUCT; release 4.2.0 this plugin supports several services in the Advanced Isolated network mode. + + + + When tenants create new isolated layer 3 networks, instead of spinning up extra Virtual Router VMs, the relevant L3 elements (routers etc) are created in the MidoNet virtual topology by making the appropriate calls to the MidoNet API. Instead of using VLANs, isolation is provided by MidoNet. + + + + Aside from the above service (Connectivity), several extra features are supported in the 4.2.0 release: + + + + DHCP + Firewall (ingress) + Source NAT + Static NAT + Port Forwarding + + + + The plugin has been tested with MidoNet version 12.12. (Caddo). + + + + +
    diff --git a/docs/en-US/plugin-midonet-introduction.xml b/docs/en-US/plugin-midonet-introduction.xml new file mode 100644 index 00000000000..7793ecbc884 --- /dev/null +++ b/docs/en-US/plugin-midonet-introduction.xml @@ -0,0 +1,26 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + +
    + Introduction to the MidoNet Plugin + The MidoNet plugin allows &PRODUCT; to use the MidoNet virtualized networking solution as a provider for &PRODUCT; networks and services. For more information on MidoNet and how it works, see http://www.midokura.com/midonet/. +
    diff --git a/docs/en-US/plugin-midonet-preparations.xml b/docs/en-US/plugin-midonet-preparations.xml new file mode 100644 index 00000000000..cf78774ec2b --- /dev/null +++ b/docs/en-US/plugin-midonet-preparations.xml @@ -0,0 +1,90 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + +
    + Prerequisites + + In order to use the MidoNet plugin, the compute hosts must be running the MidoNet Agent, and the MidoNet API server must be available. Please consult the MidoNet User Guide for more information. The following section describes the &PRODUCT; side setup. + + + + &PRODUCT; needs to have at least one physical network with the isolation method set to "MIDO". This network should be enabled for the Guest and Public traffic types. + + + + Next, we need to set the following &PRODUCT; settings under "Global Settings" in the UI: + +&PRODUCT; settings + + + + Setting Name + Description + Example + + + + + midonet.apiserver.address + Specify the address at which the Midonet API server can be contacted + http://192.168.1.144:8081/midolmanj-mgmt + + + midonet.providerrouter.id + Specifies the UUID of the Midonet provider router + d7c5e6a3-e2f4-426b-b728-b7ce6a0448e5 + + + +
    +
    + + + + We also want MidoNet to take care of public traffic, so in componentContext.xml we need to replace this line: + + ]]> + + + With this: + + ]]> + + + +
    + + + + On the compute host, MidoNet takes advantage of per-traffic type VIF driver support in &PRODUCT; KVM. + + + In agent.properties, we set the following to make MidoNet take care of Guest and Public traffic: + +libvirt.vif.driver.Guest=com.cloud.network.resource.MidoNetVifDriver +libvirt.vif.driver.Public=com.cloud.network.resource.MidoNetVifDriver + + This is explained further in MidoNet User Guide. + + + +
    diff --git a/docs/en-US/plugin-midonet-provider.xml b/docs/en-US/plugin-midonet-provider.xml new file mode 100644 index 00000000000..904828caecd --- /dev/null +++ b/docs/en-US/plugin-midonet-provider.xml @@ -0,0 +1,39 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + +
    + Enabling the MidoNet service provider via the API + + To enable via the API, use the following API calls: + addNetworkServiceProvider + + name = "MidoNet" + physicalnetworkid = <the uuid of the physical network> + + updateNetworkServiceProvider + + id = <the provider uuid returned by the previous call> + state = "Enabled" + + + +
    \ No newline at end of file diff --git a/docs/en-US/plugin-midonet-revisions.xml b/docs/en-US/plugin-midonet-revisions.xml new file mode 100644 index 00000000000..73def2325b5 --- /dev/null +++ b/docs/en-US/plugin-midonet-revisions.xml @@ -0,0 +1,45 @@ + + +%BOOK_ENTITIES; +]> + + + + + Revision History + + + + 0-0 + Wed Mar 13 2013 + + Dave + Cahill + dcahill@midokura.com + + + + Documentation created for 4.2.0 version of the MidoNet Plugin + + + + + + diff --git a/docs/en-US/plugin-midonet-ui.xml b/docs/en-US/plugin-midonet-ui.xml new file mode 100644 index 00000000000..8ee9850e5a7 --- /dev/null +++ b/docs/en-US/plugin-midonet-ui.xml @@ -0,0 +1,65 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + +
    + Enabling the MidoNet service provider via the UI + To allow &PRODUCT; to use the MidoNet Plugin the network service provider needs to be enabled on the physical network. + + + + The steps to enable via the UI are as follows: + + + In the left navbar, click Infrastructure + + + + In Zones, click View All + + + + Click the name of the Zone on which you are setting up MidoNet + + + + Click the Physical Network tab + + + + Click the Name of the Network on which you are setting up MidoNet + + + + Click Configure on the Network Service Providers box + + + + Click on the name MidoNet + + + + Click the Enable Provider button in the Network tab + + + + +
    diff --git a/docs/en-US/plugin-midonet-usage.xml b/docs/en-US/plugin-midonet-usage.xml new file mode 100644 index 00000000000..a314581dcda --- /dev/null +++ b/docs/en-US/plugin-midonet-usage.xml @@ -0,0 +1,29 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + + + Using the MidoNet Plugin + + + + + diff --git a/docs/publican-plugin-midonet.cfg b/docs/publican-plugin-midonet.cfg new file mode 100644 index 00000000000..6558d99e897 --- /dev/null +++ b/docs/publican-plugin-midonet.cfg @@ -0,0 +1,28 @@ +# Publican configuration file for CloudStack Complete Documentation Set +# Contains all technical docs except release notes +# Config::Simple 4.58 +# Tue May 29 00:57:27 2012 +# +# 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. + +xml_lang: en-US +type: Book +docname: MidoNet_Plugin_Guide +brand: cloudstack +chunk_first: 1 +chunk_section_depth: 1 +condition: install From fd3c3b6c47959001dddbf9b6b17e4ea26f013bd2 Mon Sep 17 00:00:00 2001 From: Radhika PC Date: Tue, 7 May 2013 11:30:17 +0530 Subject: [PATCH 14/71] CLOUDSTACK-893 first cut --- docs/en-US/gslb.xml | 235 +++++++++++++++++++++++++++++++++ docs/en-US/images/add-gslb.png | Bin 0 -> 17665 bytes docs/en-US/images/gslb.png | Bin 0 -> 184080 bytes 3 files changed, 235 insertions(+) create mode 100644 docs/en-US/gslb.xml create mode 100644 docs/en-US/images/add-gslb.png create mode 100644 docs/en-US/images/gslb.png diff --git a/docs/en-US/gslb.xml b/docs/en-US/gslb.xml new file mode 100644 index 00000000000..385642d394d --- /dev/null +++ b/docs/en-US/gslb.xml @@ -0,0 +1,235 @@ + + +%BOOK_ENTITIES; +]> + + +
    + Global Server Load Balancing Support + &PRODUCT; supports Global Server Load Balancing (GSLB) functionalities to provide business + continuity, and enable seamless resource movement within a &PRODUCT; environment. &PRODUCT; + achieve this by extending its functionality of integrating with NetScaler Application Delivery + Controller (ADC), which also provides various GSLB capabilities, such as disaster recovery and + load balancing. The DNS redirection technique is used to achieve GSLB in &PRODUCT;. + In order to support his functionality, region level services and service provider are + introduced. A new service 'GSLB' is introduced as a region level service. The GSLB service + provider is introduced that will provider the GSLB service. Currently, NetScaler is the + supported GSLB provider in &PRODUCT;. GSLB functionality works in an Active-Active data center + environment. +
    + About Global Server Load Balancing + Global Server Load Balancing (GSLB) is an extension of load balancing functionality, which + is highly efficient in avoiding downtime. Based on the nature of deployment, GSLB represents a + set of technologies that is used for various purposes, such as load sharing, disaster + recovery, performance, and legal obligations. With GSLB, workloads can be distributed across + multiple data centers situated at geographically separated locations. GSLB can also provide an + alternate location for accessing a resource in the event of a failure, or to provide a means + of shifting traffic easily to simplify maintenance, or both. +
    +
    + Prerequisites and Guidelines + + + The GSLB functionality is supported both Basic and Advanced zones. + + + GSLB is added as a new network service. + + + GSLB service provider can be added to a physical network in a zone. + + + The admin is allowed to enable or disable GSLB functionality at region level. + + + The admin is allowed to configure a zone as GSLB capable or enabled. + A zone shall be considered as GSLB capable only if a GSLB service provider is + provisioned in the zone. + + + When users have VMs deployed in multiple availability zones which are GSLB enabled, + user is allowed to use the GSLB functionality to load balance traffic across the VMs in + multiple zones. + + + The users are allowed to use GSLB to load balance across the VMs across zones in a + region only if the admin has enabled GSLB in that region. + + + The users are allowed to load balance traffic across the availability zones in the + same region or different regions. + + + The admin is allowed to configure DNS name for the entire cloud. + + + The users can specify an unique name, across the cloud, for a globally load balanced + service. The provided name will be used as the domain under the DNS name associated with + the cloud. + The user-provided name along with the admin-provided DNS name is used to produce a + globally resolvable FQDN for the globally load balanced service of the user. For example, + if the admin has configured xyztelco.com as the DNS name for the cloud, and user specifies + 'foo' for the GSLB virtual service, then the FQDN name of the GSLB virtual service is + foo.xyztelco.com. + + + While setting up GSLB, users can select a load balancing method, such as round robin + or least RTT, that would be the load balance traffic used across the zones that are part + of GSLB. + + + The user shall be able to set weight to zone-level virtual server. Weight shall be + considered by the load balancing method is distributing the traffic. + + + The GSLB functionality shall support session persistence, where series of client + requests for particular domain name is sent to a virtual server on the same zone. + Statistics is collected from each GSLB virtual server. + + +
    +
    + Adding a GSLB Rule + + + Log in to the &PRODUCT; UI as administrator. + + + In the left navigation pane, click Region. + + + Select the region for which you want to create a GSLB rule. + + + In the Details tab, click View GSLB. + + + Click Add GSLB. + The Add GSLB page is displayed as follows: + + + + + + gslb-add.png: adding a gslb rule + + + + + Specify the following: + + + Name: Name for the GSLB rule. + + + Description: (Optional) A short description of + the GSLB rule that can be displayed to users. + + + GSLB Domain Name: A preferred domain name for the + service. + + + Algorithm: (Optional) The algorithm to use to + load balance the traffic across the zones. The options are Round Robin, Least + Connection, and Proximity. + + + Service Type: The transport protocol to use for + GSLB. The options are TCP and UDP. + + + Domain: (Optional) The domain for which you want + to create the GSLB rule. + + + Account: (Optional) The account on which you want + to apply the GSLB rule. + + + + + Click OK to confirm. + + +
    +
    + Assigning Load Balancing Rules to GSLB + +
    +
    + How Does GSLB Works in &PRODUCT;? + The following is an illustrated conceptual model of how GLSB functionality is provided in + &PRODUCT;: An organization, xyztelco, has set up a public cloud that spans two zones, Zone-1 + and Zone-2, across geographically separated data centers that are managed by &PRODUCT;. + Tenant-A of the cloud launches a highly available solution by using xyztelco cloud. For that + purpose, they launch two instances each in both the zones: VM1 and VM2 in Zone-1 and VM5 and + VM6 in Zone-2. Tenant-A acquires a public IP, IP-1 in Zone-1, and configures a load balancer + rule to load balance the traffic between VM1 and VM2 instances. &PRODUCT; orchestrates setting + up a virtual server on the LB service provider in Zone-1. Virtual server 1 that is set up on + the LB service provider in Zone-1 represents a publicly accessible virtual server that client + reaches at IP-1. The client traffic to virtual server 1 at IP-1 will be load balanced across + VM1 and VM2 instances. + Tenant-A acquires another public IP, IP-2 in Zone-2 and sets up a load balancer rule to + load balance the traffic between VM5 and VM6 instances. Similarly in Zone-2, &PRODUCT; + orchestrates setting up a virtual server on the LB service provider. Virtual server 2 that is + setup on the LB service provider in Zone-2 represents a publicly accessible virtual server + that client reaches at IP-2. The client traffic that reaches virtual server 2 at IP-2 is load + balanced across VM5 and VM6 instances. At this point Tenant-A has the service enabled in both + the zones, but has no means to set up a disaster recovery plan if one of the zone fails. + Additionally, there is no way for Tenant-A to load balance the traffic intelligently to one of + the zones based on load, proximity and so on. The cloud administrator of xyztelco provisions a + GSLB service provider to both the zones. A GSLB provider is typically an ADC that has the + ability to act as an ADNS (Authoritative Domain Name Server) and has the mechanism to monitor + health of virtual servers both at local and remote sites. The cloud admin enables GSLB as a + service to the tenants that use zones 1 and 2. + + + + + + gslb.png: GSLB architecture + + + Tenant-A wishes to leverage the GSLB service provided by the xyztelco cloud. Tenant-A + configures a GSLB rule to load balance traffic across virtual server 1 at Zone-1 and virtual + server 2 at Zone-2. The domain name is provided as A.xyztelco.com. &PRODUCT; orchestrates + setting up GSLB virtual server 1 on the GSLB service provider at Zone-1. &PRODUCT; binds + virtual server 1 of Zone-1 and virtual server 2 of Zone-2 to GLSB virtual server 1. GSLB + virtual server 1 is configured to start monitoring the health of virtual server 1 and 2 in + Zone-1. &PRODUCT; will also orchestrate setting up GSLB virtual server 2 on GSLB service + provider at Zone-2. &PRODUCT; will bind virtual server 1 of Zone-1 and virtual server 2 of + Zone-2 to GLSB virtual server 2. GSLB virtual server 2 is configured to start monitoring the + health of virtual server 1 and 2. &PRODUCT; will bind the domain A.xyztelco.com to both the + GSLB virtual server 1 and 2. At this point, Tenant-A service will be globally reachable at + A.xyztelco.com. The private DNS server for the domain xyztelcom.com is configured by the admin + out-of-band to resolve the domain A.xyztelco.com to the GSLB providers at both the zones, + which are configured as ADNS for the domain A.xyztelco.com. A client when sends a DNS request + to resolve A.xyztelcom.com, will eventually get DNS delegation to the address of GSLB + providers at Zone 1 and 2. A client DNS request will be received by the GSLB provider. The + GSLB provider, depending on the domain for which it needs to resolve, will pick up the GSLB + virtual server associated with the domain. Depending on the health of the virtual servers + being load balanced, DNS request for the domain will be resolved to the public IP associated + with the selected virtual server. +
    +
    + Known Limitation + Currently, &PRODUCT; does not support orchestration of services across the zones. The + notion of services and service providers in region are to be introduced. +
    +
    diff --git a/docs/en-US/images/add-gslb.png b/docs/en-US/images/add-gslb.png new file mode 100644 index 0000000000000000000000000000000000000000..827a913093b5e68a6afbd74fd172a28d82815aff GIT binary patch literal 17665 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 literal 0 HcmV?d00001 diff --git a/docs/en-US/images/gslb.png b/docs/en-US/images/gslb.png new file mode 100644 index 0000000000000000000000000000000000000000..8d1a389936c31e3ed46c24f7a6787fd21a873c65 GIT binary patch literal 184080 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¬Q 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≦pX2w0y$m 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 literal 0 HcmV?d00001 From d6e0452af1785a259e52a760c1f5c372a52a7574 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Tue, 7 May 2013 09:58:16 +0200 Subject: [PATCH 15/71] Recent pom switcharoo caused the client to lose the dependecy on console-proxy, which it needs to include the systemvm --- client/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/pom.xml b/client/pom.xml index a7c7009ffc2..147959bd7f0 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -239,6 +239,11 @@ cloud-plugin-host-anti-affinity ${project.version} + + org.apache.cloudstack + cloud-console-proxy + ${project.version} + install From 9037d3b3d06eba017ab0aaba84b92e5b10dbc59f Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 7 May 2013 13:50:12 +0530 Subject: [PATCH 16/71] dedicateGuestVlanRange is admin only API Adding ACL for the dedicateGuestVlanRange API. Signed-off-by: Prasanna Santhanam --- client/tomcatconf/commands.properties.in | 1 + 1 file changed, 1 insertion(+) diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 6e3a5e4a40c..22de93dc65d 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -126,6 +126,7 @@ createVlanIpRange=1 deleteVlanIpRange=1 listVlanIpRanges=1 dedicatePublicIpRange=1 +dedicateGuestVlanRange=1 releasePublicIpRange=1 #### address commands From 26d637a0fb77e803b9f03cfcbc46076931a3c4b6 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 7 May 2013 13:50:56 +0530 Subject: [PATCH 17/71] Adding tracelogs to the API discovery service Signed-off-by: Prasanna Santhanam --- .../apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java index 2d7dbd18671..08fb573e4d9 100755 --- a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java +++ b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java @@ -83,6 +83,9 @@ public class ApiDiscoveryServiceImpl implements ApiDiscoveryService { } String apiName = apiCmdAnnotation.name(); + if (s_logger.isTraceEnabled()) { + s_logger.trace("Found api: " + apiName); + } ApiDiscoveryResponse response = getCmdRequestMap(cmdClass, apiCmdAnnotation); String responseName = apiCmdAnnotation.responseObject().getName(); From 64522b6bd582f55eb4ca6a5e4850e39847beda34 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 7 May 2013 13:51:34 +0530 Subject: [PATCH 18/71] moving test data to top level dictionary Signed-off-by: Prasanna Santhanam --- .../integration/smoke/test_guest_vlan_range.py | 18 ++++++++++++------ tools/marvin/marvin/cloudstackConnection.py | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/test/integration/smoke/test_guest_vlan_range.py b/test/integration/smoke/test_guest_vlan_range.py index eca0e61f137..01cd68c1435 100644 --- a/test/integration/smoke/test_guest_vlan_range.py +++ b/test/integration/smoke/test_guest_vlan_range.py @@ -43,7 +43,8 @@ class Services: "username": "test", "password": "password", }, - "name": "testphysicalnetwork" + "name": "testphysicalnetwork", + "vlan": "2118-2120", } @@ -64,7 +65,7 @@ class TesDedicateGuestVlanRange(cloudstackTestCase): domainid=cls.domain.id ) cls._cleanup = [ - #cls.account, + cls.account, ] return @@ -72,6 +73,13 @@ class TesDedicateGuestVlanRange(cloudstackTestCase): def tearDownClass(cls): try: # Cleanup resources used + list_physical_network_response = PhysicalNetwork.list(cls.api_client) + if list_physical_network_response is not None and len(list_physical_network_response) > 0: + physical_network = list_physical_network_response[0] + removeGuestVlanRangeResponse = \ + physical_network.update(cls.api_client, + id=physical_network.id, + removevlan=cls.services["vlan"]) cleanup_resources(cls.api_client, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) @@ -119,12 +127,12 @@ class TesDedicateGuestVlanRange(cloudstackTestCase): physical_network_response = list_physical_network_response[0] self.debug("Adding guest vlan range") - addGuestVlanRangeResponse = physical_network_response.update(self.apiclient, id=physical_network_response.id, vlan="387-390") + addGuestVlanRangeResponse = physical_network_response.update(self.apiclient, id=physical_network_response.id, vlan=self.services["vlan"]) self.debug("Dedicating guest vlan range"); dedicate_guest_vlan_range_response = PhysicalNetwork.dedicate( self.apiclient, - "387-390", + self.services["vlan"], physicalnetworkid=physical_network_response.id, account=self.account.name, domainid=self.account.domainid @@ -153,5 +161,3 @@ class TesDedicateGuestVlanRange(cloudstackTestCase): "Check account name is system account in listDedicatedGuestVlanRanges" ) - self.debug("Removing guest vlan range") - removeGuestVlanRangeResponse = physical_network_response.update(self.apiclient, id=physical_network_response.id, removevlan="387-390") diff --git a/tools/marvin/marvin/cloudstackConnection.py b/tools/marvin/marvin/cloudstackConnection.py index 9a4c387a87a..803911721e9 100644 --- a/tools/marvin/marvin/cloudstackConnection.py +++ b/tools/marvin/marvin/cloudstackConnection.py @@ -113,7 +113,7 @@ class cloudConnection(object): ) signature = base64.encodestring(hmac.new( self.securityKey, hashStr, hashlib.sha1).digest()).strip() - self.logging.info("Computed Signature by Marvin: %s" % signature) + self.logging.debug("Computed Signature by Marvin: %s" % signature) return signature def request(self, command, auth=True, payload={}, method='GET'): From 8b965c56859c32983da4d2414f5c4d34de34769d Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Tue, 7 May 2013 10:57:23 +0200 Subject: [PATCH 19/71] commit e0d8f01ecd92a1a7b74558d02a28be3b2f20a10d enabled all tests, but the tests in vmware-base are horribly broken and will not compile with the current CloudStack. Removing the tests to fix the nonoss build and they are so broken they should be rewritten from scratch anyway. --- vmware-base/pom.xml | 4 - .../vmware/mo/TestVmwareContextFactory.java | 43 - .../hypervisor/vmware/mo/TestVmwareMO.java | 39 - .../vmware/util/TestVmwareUtil.java | 107 -- .../test/com/cloud/vmware/TestVMWare.java | 1342 ----------------- 5 files changed, 1535 deletions(-) delete mode 100644 vmware-base/test/com/cloud/hypervisor/vmware/mo/TestVmwareContextFactory.java delete mode 100644 vmware-base/test/com/cloud/hypervisor/vmware/mo/TestVmwareMO.java delete mode 100755 vmware-base/test/com/cloud/hypervisor/vmware/util/TestVmwareUtil.java delete mode 100644 vmware-base/test/com/cloud/vmware/TestVMWare.java diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml index 8fa811fb3f2..da4fb21c713 100644 --- a/vmware-base/pom.xml +++ b/vmware-base/pom.xml @@ -59,8 +59,4 @@ 1.4 - - install - src - diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/mo/TestVmwareContextFactory.java b/vmware-base/test/com/cloud/hypervisor/vmware/mo/TestVmwareContextFactory.java deleted file mode 100644 index 81a62d2993a..00000000000 --- a/vmware-base/test/com/cloud/hypervisor/vmware/mo/TestVmwareContextFactory.java +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.hypervisor.vmware.mo; - -import com.cloud.hypervisor.vmware.util.VmwareClient; -import com.cloud.hypervisor.vmware.util.VmwareContext; - - -public class TestVmwareContextFactory { - private static volatile int s_seq = 1; - - static { - // skip certificate check - System.setProperty("axis.socketSecureFactory", "org.apache.axis.components.net.SunFakeTrustSocketFactory"); - } - - public static VmwareContext create(String vCenterAddress, String vCenterUserName, String vCenterPassword) throws Exception { - assert(vCenterAddress != null); - assert(vCenterUserName != null); - assert(vCenterPassword != null); - - String serviceUrl = "https://" + vCenterAddress + "/sdk/vimService"; - VmwareClient vimClient = new VmwareClient(vCenterAddress + "-" + s_seq++); - vimClient.connect(serviceUrl, vCenterUserName, vCenterPassword); - - VmwareContext context = new VmwareContext(vimClient, vCenterAddress); - return context; - } -} diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/mo/TestVmwareMO.java b/vmware-base/test/com/cloud/hypervisor/vmware/mo/TestVmwareMO.java deleted file mode 100644 index c9807f443f1..00000000000 --- a/vmware-base/test/com/cloud/hypervisor/vmware/mo/TestVmwareMO.java +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.hypervisor.vmware.mo; - -import java.util.GregorianCalendar; - -import org.apache.log4j.Logger; - -import com.cloud.hypervisor.vmware.mo.SnapshotDescriptor.SnapshotInfo; -import com.cloud.hypervisor.vmware.util.VmwareContext; -import com.cloud.utils.Pair; -import com.cloud.utils.testcase.Log4jEnabledTestCase; -import com.google.gson.Gson; -import com.vmware.vim25.DynamicProperty; -import com.vmware.vim25.ManagedObjectReference; -import com.vmware.vim25.ObjectContent; -import com.vmware.vim25.VirtualMachineConfigSpec; - -public class TestVmwareMO extends Log4jEnabledTestCase { - private static final Logger s_logger = Logger.getLogger(TestVmwareMO.class); - - public void test() { - } -} - diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/util/TestVmwareUtil.java b/vmware-base/test/com/cloud/hypervisor/vmware/util/TestVmwareUtil.java deleted file mode 100755 index d1dd11b7c8e..00000000000 --- a/vmware-base/test/com/cloud/hypervisor/vmware/util/TestVmwareUtil.java +++ /dev/null @@ -1,107 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.hypervisor.vmware.util; -import java.io.File; - -import junit.framework.Assert; - -import org.apache.log4j.Logger; - -import com.cloud.hypervisor.vmware.resource.SshHelper; -import com.cloud.hypervisor.vmware.resource.VmwareContextFactory; -import com.cloud.utils.Pair; -import com.cloud.utils.testcase.Log4jEnabledTestCase; -import com.vmware.vim25.ManagedObjectReference; - -public class TestVmwareUtil extends Log4jEnabledTestCase { - private static final Logger s_logger = Logger.getLogger(TestVmwareUtil.class); - - public void testContextCreation() { - try { - VmwareContext context = VmwareContextFactory.create("vsphere-1.lab.vmops.com", "Administrator", "Suite219"); - Assert.assertTrue(true); - context.close(); - } catch(Exception e) { - s_logger.error("Unexpected exception : ", e); - } - } - - public void testSearchIndex() { - try { - VmwareContext context = VmwareContextFactory.create("vsphere-1.lab.vmops.com", "Administrator", "Suite219"); - Assert.assertTrue(true); - - ManagedObjectReference morHost = context.getService().findByDnsName(context.getServiceContent().getSearchIndex(), - null, "esxhost-1.lab.vmops.com", false); - Assert.assertTrue(morHost.getType().equalsIgnoreCase("HostSystem")); - - morHost = context.getService().findByIp(context.getServiceContent().getSearchIndex(), - null, "192.168.1.168", false); - Assert.assertTrue(morHost == null); - context.close(); - } catch(Exception e) { - s_logger.error("Unexpected exception : ", e); - } - } - - public void testVmxFileDownload() { - try { - VmwareContext context = VmwareContextFactory.create("vsphere-1.lab.vmops.com", "Administrator", "Suite219"); - byte[] vmxContent = context.getResourceContent("https://vsphere-1.lab.vmops.com/folder/ServerRoom-Fedora32/ServerRoom-Fedora32.vmx?dcPath=cupertino&dsName=NFS%20datastore"); - System.out.print(new String(vmxContent)); - context.close(); - } catch(Exception e) { - s_logger.error("Unexpected exception : ", e); - } - } - - public void testVmxFileParser() { - String[] tokens = "[NFS datastore] Fedora-clone-test/Fedora-clone-test.vmx".split("\\[|\\]|/"); - - for(String str : tokens) { - System.out.println("Token " + str); - } - } - - public void testSsh() { - try { - File file = new File("c:\\temp\\id_rsa.kelven"); - if(!file.exists()) { - System.out.println("key file does not exist!"); - } - - Pair result = SshHelper.sshExecute("192.168.1.107", 22, "kelven", file, null, "ls -al"); - System.out.println("Result: " + result.second()); - } catch(Exception e) { - s_logger.error("Unexpected exception : ", e); - } - } - - public void testScp() { - try { - File file = new File("c:\\temp\\id_rsa.kelven"); - if(!file.exists()) { - System.out.println("key file does not exist!"); - } - - SshHelper.scpTo("192.168.1.107", 22, "kelven", file, null, "~", "Hello, world".getBytes(), - "hello.txt", null); - } catch(Exception e) { - s_logger.error("Unexpected exception : ", e); - } - } -} diff --git a/vmware-base/test/com/cloud/vmware/TestVMWare.java b/vmware-base/test/com/cloud/vmware/TestVMWare.java deleted file mode 100644 index f2d08e17f5a..00000000000 --- a/vmware-base/test/com/cloud/vmware/TestVMWare.java +++ /dev/null @@ -1,1342 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.vmware; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; -import java.rmi.RemoteException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLSession; - -import org.apache.log4j.xml.DOMConfigurator; - -import com.cloud.hypervisor.vmware.mo.DatacenterMO; -import com.cloud.hypervisor.vmware.mo.DistributedVirtualSwitchMO; -import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper; -import com.cloud.hypervisor.vmware.util.VmwareContext; -import com.cloud.utils.PropertiesUtil; -import com.vmware.vim25.HostIpConfig; -import com.vmware.vim25.HostVirtualNicSpec; -import com.vmware.vim25.ArrayOfManagedObjectReference; -import com.vmware.vim25.DVPortgroupConfigInfo; -import com.vmware.vim25.DVPortgroupConfigSpec; -import com.vmware.vim25.DVSSecurityPolicy; -import com.vmware.vim25.DVSTrafficShapingPolicy; -import com.vmware.vim25.DatastoreInfo; -import com.vmware.vim25.DynamicProperty; -import com.vmware.vim25.HostConfigManager; -import com.vmware.vim25.HostIpConfig; -import com.vmware.vim25.HostPortGroupSpec; -import com.vmware.vim25.HostVirtualNicSpec; -import com.vmware.vim25.HttpNfcLeaseDeviceUrl; -import com.vmware.vim25.HttpNfcLeaseInfo; -import com.vmware.vim25.HttpNfcLeaseState; -import com.vmware.vim25.InvalidProperty; -import com.vmware.vim25.ManagedObjectReference; -import com.vmware.vim25.ObjectContent; -import com.vmware.vim25.ObjectSpec; -import com.vmware.vim25.OvfCreateImportSpecParams; -import com.vmware.vim25.OvfCreateImportSpecResult; -import com.vmware.vim25.OvfFileItem; -import com.vmware.vim25.PropertyFilterSpec; -import com.vmware.vim25.PropertySpec; -import com.vmware.vim25.RuntimeFault; -import com.vmware.vim25.SelectionSpec; -import com.vmware.vim25.TraversalSpec; -import com.vmware.vim25.VMwareDVSPortSetting; -import com.vmware.vim25.VirtualDeviceConfigSpec; -import com.vmware.vim25.VirtualDeviceConfigSpecOperation; -import com.vmware.vim25.VirtualEthernetCard; -import com.vmware.vim25.VirtualEthernetCardNetworkBackingInfo; -import com.vmware.vim25.VirtualMachineCloneSpec; -import com.vmware.vim25.VirtualMachineConfigSpec; -import com.vmware.vim25.VirtualMachineRelocateSpec; -import com.vmware.vim25.VirtualNicManagerNetConfig; -import com.vmware.vim25.VirtualPCNet32; -import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanSpec; - -public class TestVMWare { - private static ExtendedAppUtil cb; - private static String[] _args; - - private static final int IND_DATACENTER_MOR = 3; - private static final int IND_DVSWITCH_MOR = 4; - private static final int IND_DVSWITCH_NAME = 5; - private static final int IND_DVPORTGROUP_NAME = 6; - private static final int IND_DVPORTGROUP_VLAN = 7; - private static final int IND_DVPORTGROUP_PORTCOUNT = 8; - private static final int MAX_ARGS = 9; - static { - try { - javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1]; - javax.net.ssl.TrustManager tm = new TrustAllManager(); - trustAllCerts[0] = tm; - javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL"); - sc.init(null, trustAllCerts, null); - javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); - } catch (Exception e) { - } - } - - private static void setupLog4j() { - File file = PropertiesUtil.findConfigFile("log4j-cloud.xml"); - - if(file != null) { - System.out.println("Log4j configuration from : " + file.getAbsolutePath()); - DOMConfigurator.configureAndWatch(file.getAbsolutePath(), 10000); - } else { - System.out.println("Configure log4j with default properties"); - } - } - - private void getAndPrintInventoryContents() throws Exception { - TraversalSpec resourcePoolTraversalSpec = new TraversalSpec(); - resourcePoolTraversalSpec.setName("resourcePoolTraversalSpec"); - resourcePoolTraversalSpec.setType("ResourcePool"); - resourcePoolTraversalSpec.setPath("resourcePool"); - resourcePoolTraversalSpec.setSkip(new Boolean(false)); - resourcePoolTraversalSpec.setSelectSet( - new SelectionSpec [] { new SelectionSpec(null,null,"resourcePoolTraversalSpec") }); - - TraversalSpec computeResourceRpTraversalSpec = new TraversalSpec(); - computeResourceRpTraversalSpec.setName("computeResourceRpTraversalSpec"); - computeResourceRpTraversalSpec.setType("ComputeResource"); - computeResourceRpTraversalSpec.setPath("resourcePool"); - computeResourceRpTraversalSpec.setSkip(new Boolean(false)); - computeResourceRpTraversalSpec.setSelectSet( - new SelectionSpec [] { new SelectionSpec(null,null,"resourcePoolTraversalSpec") }); - - TraversalSpec computeResourceHostTraversalSpec = new TraversalSpec(); - computeResourceHostTraversalSpec.setName("computeResourceHostTraversalSpec"); - computeResourceHostTraversalSpec.setType("ComputeResource"); - computeResourceHostTraversalSpec.setPath("host"); - computeResourceHostTraversalSpec.setSkip(new Boolean(false)); - - TraversalSpec datacenterHostTraversalSpec = new TraversalSpec(); - datacenterHostTraversalSpec.setName("datacenterHostTraversalSpec"); - datacenterHostTraversalSpec.setType("Datacenter"); - datacenterHostTraversalSpec.setPath("hostFolder"); - datacenterHostTraversalSpec.setSkip(new Boolean(false)); - datacenterHostTraversalSpec.setSelectSet( - new SelectionSpec [] { new SelectionSpec(null,null,"folderTraversalSpec") }); - - TraversalSpec datacenterVmTraversalSpec = new TraversalSpec(); - datacenterVmTraversalSpec.setName("datacenterVmTraversalSpec"); - datacenterVmTraversalSpec.setType("Datacenter"); - datacenterVmTraversalSpec.setPath("vmFolder"); - datacenterVmTraversalSpec.setSkip(new Boolean(false)); - datacenterVmTraversalSpec.setSelectSet( - new SelectionSpec [] { new SelectionSpec(null,null,"folderTraversalSpec") }); - - TraversalSpec folderTraversalSpec = new TraversalSpec(); - folderTraversalSpec.setName("folderTraversalSpec"); - folderTraversalSpec.setType("Folder"); - folderTraversalSpec.setPath("childEntity"); - folderTraversalSpec.setSkip(new Boolean(false)); - folderTraversalSpec.setSelectSet( - new SelectionSpec [] { new SelectionSpec(null,null,"folderTraversalSpec"), - datacenterHostTraversalSpec, - datacenterVmTraversalSpec, - computeResourceRpTraversalSpec, - computeResourceHostTraversalSpec, - resourcePoolTraversalSpec }); - - PropertySpec[] propspecary = new PropertySpec[] { new PropertySpec() }; - propspecary[0].setAll(new Boolean(false)); - propspecary[0].setPathSet(new String[] { "name" }); - propspecary[0].setType("ManagedEntity"); - - PropertyFilterSpec spec = new PropertyFilterSpec(); - spec.setPropSet(propspecary); - spec.setObjectSet(new ObjectSpec[] { new ObjectSpec() }); - spec.getObjectSet(0).setObj(cb.getServiceConnection3().getRootFolder()); - spec.getObjectSet(0).setSkip(new Boolean(false)); - spec.getObjectSet(0).setSelectSet( - new SelectionSpec[] { folderTraversalSpec }); - - // Recursively get all ManagedEntity ManagedObjectReferences - // and the "name" property for all ManagedEntities retrieved - ObjectContent[] ocary = - cb.getServiceConnection3().getService().retrieveProperties( - cb.getServiceConnection3().getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { spec } - ); - - // If we get contents back. print them out. - if (ocary != null) { - ObjectContent oc = null; - ManagedObjectReference mor = null; - DynamicProperty[] pcary = null; - DynamicProperty pc = null; - for (int oci = 0; oci < ocary.length; oci++) { - oc = ocary[oci]; - mor = oc.getObj(); - pcary = oc.getPropSet(); - - System.out.println("Object Type : " + mor.getType()); - System.out.println("Reference Value : " + mor.get_value()); - - if (pcary != null) { - for (int pci = 0; pci < pcary.length; pci++) { - pc = pcary[pci]; - System.out.println(" Property Name : " + pc.getName()); - if (pc != null) { - if (!pc.getVal().getClass().isArray()) { - System.out.println(" Property Value : " + pc.getVal()); - } - else { - Object[] ipcary = (Object[])pc.getVal(); - System.out.println("Val : " + pc.getVal()); - for (int ii = 0; ii < ipcary.length; ii++) { - Object oval = ipcary[ii]; - if (oval.getClass().getName().indexOf("ManagedObjectReference") >= 0) { - ManagedObjectReference imor = (ManagedObjectReference)oval; - - System.out.println("Inner Object Type : " + imor.getType()); - System.out.println("Inner Reference Value : " + imor.get_value()); - } - else { - System.out.println("Inner Property Value : " + oval); - } - } - } - } - } - } - } - } else { - System.out.println("No Managed Entities retrieved!"); - } - } - - private void listDataCenters() { - try { - ManagedObjectReference[] morDatacenters = getDataCenterMors(); - if(morDatacenters != null) { - for(ManagedObjectReference mor : morDatacenters) { - System.out.println("Datacenter : " + mor.get_value()); - - Map properites = new HashMap(); - properites.put("name", null); - properites.put("vmFolder", null); - properites.put("hostFolder", null); - - getProperites(mor, properites); - for(Map.Entry entry : properites.entrySet()) { - if(entry.getValue() instanceof ManagedObjectReference) { - ManagedObjectReference morProp = (ManagedObjectReference)entry.getValue(); - System.out.println("\t" + entry.getKey() + ":(" + morProp.getType() + ", " + morProp.get_value() + ")"); - } else { - System.out.println("\t" + entry.getKey() + ":" + entry.getValue()); - } - } - - System.out.println("Datacenter clusters"); - ManagedObjectReference[] clusters = getDataCenterClusterMors(mor); - if(clusters != null) { - for(ManagedObjectReference morCluster : clusters) { - Object[] props = this.getProperties(morCluster, new String[] {"name"}); - System.out.println("cluster : " + props[0]); - - System.out.println("cluster hosts"); - ManagedObjectReference[] hosts = getClusterHostMors(morCluster); - if(hosts != null) { - for(ManagedObjectReference morHost : hosts) { - Object[] props2 = this.getProperties(morHost, new String[] {"name"}); - System.out.println("host : " + props2[0]); - } - } - } - } - - System.out.println("Datacenter standalone hosts"); - ManagedObjectReference[] hosts = getDataCenterStandaloneHostMors(mor); - if(hosts != null) { - for(ManagedObjectReference morHost : hosts) { - Object[] props = this.getProperties(morHost, new String[] {"name"}); - System.out.println("host : " + props[0]); - } - } - - System.out.println("Datacenter datastores"); - ManagedObjectReference[] stores = getDataCenterDatastoreMors(mor); - if(stores != null) { - for(ManagedObjectReference morStore : stores) { - // data store name property does not work for some reason - Object[] props = getProperties(morStore, new String[] {"info" }); - - System.out.println(morStore.getType() + ": " + ((DatastoreInfo)props[0]).getName()); - } - } - - System.out.println("Datacenter VMs"); - ManagedObjectReference[] vms = getDataCenterVMMors(mor); - if(stores != null) { - for(ManagedObjectReference morVm : vms) { - Object[] props = this.getProperties(morVm, new String[] {"name"}); - System.out.println("VM name: " + props[0] + ", ref val: " + morVm.get_value()); - } - } - } - } - } catch(RuntimeFault e) { - e.printStackTrace(); - } catch(RemoteException e) { - e.printStackTrace(); - } - } - - private void listInventoryFolders() { - TraversalSpec folderTraversalSpec = new TraversalSpec(); - folderTraversalSpec.setName("folderTraversalSpec"); - folderTraversalSpec.setType("Folder"); - folderTraversalSpec.setPath("childEntity"); - folderTraversalSpec.setSkip(new Boolean(false)); - folderTraversalSpec.setSelectSet( - new SelectionSpec [] { new SelectionSpec(null, null, "folderTraversalSpec")} - ); - - PropertySpec[] propSpecs = new PropertySpec[] { new PropertySpec() }; - propSpecs[0].setAll(new Boolean(false)); - propSpecs[0].setPathSet(new String[] { "name" }); - propSpecs[0].setType("ManagedEntity"); - - PropertyFilterSpec filterSpec = new PropertyFilterSpec(); - filterSpec.setPropSet(propSpecs); - filterSpec.setObjectSet(new ObjectSpec[] { new ObjectSpec() }); - filterSpec.getObjectSet(0).setObj(cb.getServiceConnection3().getRootFolder()); - filterSpec.getObjectSet(0).setSkip(new Boolean(false)); - filterSpec.getObjectSet(0).setSelectSet( - new SelectionSpec[] { folderTraversalSpec } - ); - - try { - ObjectContent[] objContent = cb.getServiceConnection3().getService().retrieveProperties( - cb.getServiceConnection3().getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { filterSpec } - ); - printContent(objContent); - } catch (InvalidProperty e) { - e.printStackTrace(); - } catch (RuntimeFault e) { - e.printStackTrace(); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - - private TraversalSpec getFolderRecursiveTraversalSpec() { - SelectionSpec recurseFolders = new SelectionSpec(); - recurseFolders.setName("folder2childEntity"); - - TraversalSpec folder2childEntity = new TraversalSpec(); - folder2childEntity.setType("Folder"); - folder2childEntity.setPath("childEntity"); - folder2childEntity.setName(recurseFolders.getName()); - folder2childEntity.setSelectSet(new SelectionSpec[] { recurseFolders }); - - return folder2childEntity; - } - - private ManagedObjectReference[] getDataCenterMors() throws RuntimeFault, RemoteException { - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("Datacenter"); - pSpec.setPathSet(new String[] { "name"} ); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(cb.getServiceConnection3().getRootFolder()); - oSpec.setSkip(Boolean.TRUE); - oSpec.setSelectSet(new SelectionSpec[] { getFolderRecursiveTraversalSpec() }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - - ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( - cb.getServiceConnection3().getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - - if(ocs != null) { - ManagedObjectReference[] morDatacenters = new ManagedObjectReference[ocs.length]; - for(int i = 0; i < ocs.length; i++) - morDatacenters[i] = ocs[i].getObj(); - - return morDatacenters; - } - return null; - } - - private ManagedObjectReference[] getDataCenterVMMors(ManagedObjectReference morDatacenter) throws RuntimeFault, RemoteException { - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("VirtualMachine"); - pSpec.setPathSet(new String[] { "name"} ); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(morDatacenter); - oSpec.setSkip(Boolean.TRUE); - - TraversalSpec tSpec = new TraversalSpec(); - tSpec.setName("dc2VMFolder"); - tSpec.setType("Datacenter"); - tSpec.setPath("vmFolder"); - tSpec.setSelectSet(new SelectionSpec[] { getFolderRecursiveTraversalSpec() } ); - - oSpec.setSelectSet(new SelectionSpec[] { tSpec }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - - ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( - cb.getServiceConnection3().getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - - if(ocs != null) { - ManagedObjectReference[] morVMs = new ManagedObjectReference[ocs.length]; - for(int i = 0; i < ocs.length; i++) - morVMs[i] = ocs[i].getObj(); - - return morVMs; - } - return null; - } - - private ManagedObjectReference[] getDataCenterDatastoreMors(ManagedObjectReference morDatacenter) throws RuntimeFault, RemoteException { - Object[] stores = getProperties(morDatacenter, new String[] { "datastore" }); - if(stores != null && stores.length == 1) { - return ((ArrayOfManagedObjectReference)stores[0]).getManagedObjectReference(); - } - return null; - } - - private ManagedObjectReference[] getDataCenterClusterMors(ManagedObjectReference morDatacenter) throws RuntimeFault, RemoteException { - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("ClusterComputeResource"); - pSpec.setPathSet(new String[] { "name"} ); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(morDatacenter); - oSpec.setSkip(Boolean.TRUE); - - TraversalSpec tSpec = new TraversalSpec(); - tSpec.setName("traversalHostFolder"); - tSpec.setType("Datacenter"); - tSpec.setPath("hostFolder"); - tSpec.setSkip(false); - tSpec.setSelectSet(new SelectionSpec[] { getFolderRecursiveTraversalSpec() }); - - oSpec.setSelectSet(new TraversalSpec[] { tSpec }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - - ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( - cb.getServiceConnection3().getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - - if(ocs != null) { - ManagedObjectReference[] morDatacenters = new ManagedObjectReference[ocs.length]; - for(int i = 0; i < ocs.length; i++) - morDatacenters[i] = ocs[i].getObj(); - - return morDatacenters; - } - return null; - } - - private ManagedObjectReference[] getDataCenterStandaloneHostMors(ManagedObjectReference morDatacenter) throws RuntimeFault, RemoteException { - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("ComputeResource"); - pSpec.setPathSet(new String[] { "name"} ); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(morDatacenter); - oSpec.setSkip(Boolean.TRUE); - - TraversalSpec tSpec = new TraversalSpec(); - tSpec.setName("traversalHostFolder"); - tSpec.setType("Datacenter"); - tSpec.setPath("hostFolder"); - tSpec.setSkip(false); - tSpec.setSelectSet(new SelectionSpec[] { getFolderRecursiveTraversalSpec() }); - - oSpec.setSelectSet(new TraversalSpec[] { tSpec }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - - ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( - cb.getServiceConnection3().getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - - if(ocs != null) { - List listComputeResources = new ArrayList(); - for(ObjectContent oc : ocs) { - if(oc.getObj().getType().equalsIgnoreCase("ComputeResource")) - listComputeResources.add(oc.getObj()); - } - - List listHosts = new ArrayList(); - for(ManagedObjectReference morComputeResource : listComputeResources) { - ManagedObjectReference[] hosts = getComputeResourceHostMors(morComputeResource); - if(hosts != null) { - for(ManagedObjectReference host: hosts) - listHosts.add(host); - } - } - - return listHosts.toArray(new ManagedObjectReference[0]); - } - return null; - } - - private ManagedObjectReference[] getComputeResourceHostMors(ManagedObjectReference morCompute) throws RuntimeFault, RemoteException { - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("HostSystem"); - pSpec.setPathSet(new String[] { "name"} ); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(morCompute); - oSpec.setSkip(true); - - TraversalSpec tSpec = new TraversalSpec(); - tSpec.setName("computeResource2Host"); - tSpec.setType("ComputeResource"); - tSpec.setPath("host"); - tSpec.setSkip(false); - oSpec.setSelectSet(new TraversalSpec[] { tSpec }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - - ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( - cb.getServiceConnection3().getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - - if(ocs != null) { - ManagedObjectReference[] morDatacenters = new ManagedObjectReference[ocs.length]; - for(int i = 0; i < ocs.length; i++) - morDatacenters[i] = ocs[i].getObj(); - - return morDatacenters; - } - return null; - } - - private ManagedObjectReference[] getClusterHostMors(ManagedObjectReference morCluster) throws RuntimeFault, RemoteException { - // ClusterComputeResource inherits from ComputeResource - return getComputeResourceHostMors(morCluster); - } - - private ObjectContent[] getDataCenterProperites(String[] properites) throws RuntimeFault, RemoteException { - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("Datacenter"); - pSpec.setPathSet(properites ); - - SelectionSpec recurseFolders = new SelectionSpec(); - recurseFolders.setName("folder2childEntity"); - - TraversalSpec folder2childEntity = new TraversalSpec(); - folder2childEntity.setType("Folder"); - folder2childEntity.setPath("childEntity"); - folder2childEntity.setName(recurseFolders.getName()); - folder2childEntity.setSelectSet(new SelectionSpec[] { recurseFolders }); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(cb.getServiceConnection3().getRootFolder()); - oSpec.setSkip(Boolean.TRUE); - oSpec.setSelectSet(new SelectionSpec[] { folder2childEntity }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - - return cb.getServiceConnection3().getService().retrieveProperties( - cb.getServiceConnection3().getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - } - - private void printContent(ObjectContent[] objContent) { - if(objContent != null) { - for(ObjectContent oc : objContent) { - ManagedObjectReference mor = oc.getObj(); - DynamicProperty[] objProps = oc.getPropSet(); - - System.out.println("Object type: " + mor.getType()); - if(objProps != null) { - for(DynamicProperty objProp : objProps) { - if(!objProp.getClass().isArray()) { - System.out.println("\t" + objProp.getName() + "=" + objProp.getVal()); - } else { - Object[] ipcary = (Object[])objProp.getVal(); - System.out.print("\t" + objProp.getName() + "=["); - int i = 0; - for(Object item : ipcary) { - if (item.getClass().getName().indexOf("ManagedObjectReference") >= 0) { - ManagedObjectReference imor = (ManagedObjectReference)item; - System.out.print("(" + imor.getType() + "," + imor.get_value() + ")"); - } else { - System.out.print(item); - } - - if(i < ipcary.length - 1) - System.out.print(", "); - i++; - } - - System.out.println("]"); - } - } - } - } - } - } - - private void getProperites(ManagedObjectReference mor, Map properties) throws RuntimeFault, RemoteException { - PropertySpec pSpec = new PropertySpec(); - pSpec.setType(mor.getType()); - pSpec.setPathSet(properties.keySet().toArray(new String[0])); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(mor); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] {pSpec} ); - pfSpec.setObjectSet(new ObjectSpec[] {oSpec} ); - - ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( - cb.getServiceConnection3().getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] {pfSpec} ); - - if(ocs != null) { - for(ObjectContent oc : ocs) { - DynamicProperty[] propSet = oc.getPropSet(); - if(propSet != null) { - for(DynamicProperty prop : propSet) { - properties.put(prop.getName(), prop.getVal()); - } - } - } - } - } - - private Object[] getProperties(ManagedObjectReference moRef, String[] properties) throws RuntimeFault, RemoteException { - PropertySpec pSpec = new PropertySpec(); - pSpec.setType(moRef.getType()); - pSpec.setPathSet(properties); - - ObjectSpec oSpec = new ObjectSpec(); - // Set the starting object - oSpec.setObj(moRef); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] {pSpec} ); - pfSpec.setObjectSet(new ObjectSpec[] {oSpec} ); - ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( - cb.getServiceConnection3().getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] {pfSpec} ); - - Object[] ret = new Object[properties.length]; - if(ocs != null) { - for(int i = 0; i< ocs.length; ++i) { - ObjectContent oc = ocs[i]; - DynamicProperty[] dps = oc.getPropSet(); - if(dps != null) { - for(int j = 0; j < dps.length; ++j) { - DynamicProperty dp = dps[j]; - for(int p = 0; p < ret.length; ++p) { - if(properties[p].equals(dp.getName())) { - ret[p] = dp.getVal(); - } - } - } - } - } - } - return ret; - } - - private void powerOnVm() throws Exception { - ManagedObjectReference morVm = new ManagedObjectReference(); - morVm.setType("VirtualMachine"); - morVm.set_value("vm-480"); - - cb.getServiceConnection3().getService().powerOnVM_Task(morVm, null); - } - - private void powerOffVm() throws Exception { - ManagedObjectReference morVm = new ManagedObjectReference(); - morVm.setType("VirtualMachine"); - morVm.set_value("vm-66"); - - cb.getServiceConnection3().getService().powerOffVM_Task(morVm); - } - - private void createSnapshot() throws Exception { - ManagedObjectReference morVm = new ManagedObjectReference(); - morVm.setType("VirtualMachine"); - morVm.set_value("vm-66"); - cb.getServiceConnection3().getService().createSnapshot_Task(morVm, "RunningSnapshotProg", "", false, false); - } - - private void registerTemplate() throws Exception { - ManagedObjectReference morFolder = new ManagedObjectReference(); - morFolder.setType("Folder"); - morFolder.set_value("group-v3"); - - ManagedObjectReference morHost = new ManagedObjectReference(); - morHost.setType("HostSystem"); - morHost.set_value("host-48"); - - System.out.println("Begin registerVM_Task"); - ManagedObjectReference taskmor = cb.getServiceConnection3().getService().registerVM_Task( - morFolder, "[NFS datastore] Template-Fedora/Template-Fedora.vmtx", "Template-Fedora", true, - null, morHost); - System.out.println("End registerVM_Task"); - - String result = cb.getServiceUtil3().waitForTask(taskmor); - if (result.equalsIgnoreCase("Sucess")) { - System.out.println("Registering The Virtual Machine ..........Done"); - } else { - System.out.println("Some Exception While Registering The VM"); - } - } - - private void createVmFromTemplate() throws Exception { - VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec(); - - ManagedObjectReference morDatastore = new ManagedObjectReference(); - morDatastore.setType("Datastore"); - morDatastore.set_value("datastore-30"); - - ManagedObjectReference morHost = new ManagedObjectReference(); - morHost.setType("HostSystem"); - morHost.set_value("host-48"); - - ManagedObjectReference morPool = new ManagedObjectReference(); - morPool.setType("ResourcePool"); - morPool.set_value("resgroup-41"); - - VirtualMachineRelocateSpec relocSpec = new VirtualMachineRelocateSpec(); - cloneSpec.setLocation(relocSpec); - cloneSpec.setPowerOn(false); - cloneSpec.setTemplate(false); - - relocSpec.setDatastore(morDatastore); - relocSpec.setHost(morHost); - relocSpec.setPool(morPool); - - ManagedObjectReference morTemplate = new ManagedObjectReference(); - morTemplate.setType("VirtualMachine"); - morTemplate.set_value("vm-76"); - - ManagedObjectReference morFolder = new ManagedObjectReference(); - morFolder.setType("Folder"); - morFolder.set_value("group-v3"); - - ManagedObjectReference cloneTask - = cb.getServiceConnection3().getService().cloneVM_Task(morTemplate, morFolder, - "Fedora-clone-test", cloneSpec); - - String status = cb.getServiceUtil3().waitForTask(cloneTask); - if(status.equalsIgnoreCase("failure")) { - System.out.println("Failure -: Virtual Machine cannot be cloned"); - } - - if(status.equalsIgnoreCase("sucess")) { - System.out.println("Virtual Machine Cloned successfully."); - } - } - - private void addNic() throws Exception { - ManagedObjectReference morVm = new ManagedObjectReference(); - morVm.setType("VirtualMachine"); - morVm.set_value("vm-77"); - - ManagedObjectReference morNetwork = new ManagedObjectReference(); - morNetwork.setType("DistributedVirtualPortgroup"); - morNetwork.set_value("dvportgroup-56"); - - VirtualDeviceConfigSpec nicSpec = new VirtualDeviceConfigSpec(); - nicSpec.setOperation(VirtualDeviceConfigSpecOperation.add); - VirtualEthernetCard nic = new VirtualPCNet32(); - VirtualEthernetCardNetworkBackingInfo nicBacking - = new VirtualEthernetCardNetworkBackingInfo(); - nicBacking.setDeviceName("Adapter to dSwitch-vlan26"); - nicBacking.setNetwork(morNetwork); - - nic.setAddressType("generated"); - nic.setBacking(nicBacking); - nic.setKey(4); - nicSpec.setDevice(nic); - - VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); - VirtualDeviceConfigSpec [] nicSpecArray = {nicSpec}; - vmConfigSpec.setDeviceChange(nicSpecArray); - - ManagedObjectReference tmor - = cb.getServiceConnection3().getService().reconfigVM_Task( - morVm, vmConfigSpec); - - String status = cb.getServiceUtil3().waitForTask(tmor); - if(status.equalsIgnoreCase("failure")) { - System.out.println("Failure -: Virtual Machine cannot be cloned"); - } - - if(status.equalsIgnoreCase("sucess")) { - System.out.println("Virtual Machine Cloned successfully."); - } - } - - // add virtual NIC to vmkernel - private void addNicToNetwork() throws Exception { - ManagedObjectReference morHost = new ManagedObjectReference(); - morHost.setType("HostSystem"); - morHost.set_value("host-48"); - - HostPortGroupSpec portgrp = new HostPortGroupSpec(); - portgrp.setName("VM Network vlan26"); - - Object cmobj = cb.getServiceUtil3().getDynamicProperty(morHost, "configManager"); - HostConfigManager configMgr = (HostConfigManager)cmobj; - ManagedObjectReference nwSystem = configMgr.getNetworkSystem(); - - HostVirtualNicSpec vNicSpec = new HostVirtualNicSpec(); - HostIpConfig ipConfig = new HostIpConfig(); - ipConfig.setDhcp(false); - ipConfig.setIpAddress("192.168.26.177"); - ipConfig.setSubnetMask("255.255.255.0"); - - vNicSpec.setIp(ipConfig); - vNicSpec.setPortgroup("VM Network vlan26"); - - cb.getServiceConnection3().getService().addVirtualNic(nwSystem, - "dvPortGroup-vlan26", vNicSpec); - } - - private void createDatacenter() throws Exception { - cb.getServiceConnection3().getService().createDatacenter( - cb.getServiceConnection3().getRootFolder(), - "cloud.dc.test"); - } - - private void getPropertyWithPath() throws Exception { - ManagedObjectReference morHost = new ManagedObjectReference(); - morHost.setType("HostSystem"); - morHost.set_value("host-161"); - - VirtualNicManagerNetConfig[] netConfigs = (VirtualNicManagerNetConfig[])cb.getServiceUtil3().getDynamicProperty(morHost, "config.virtualNicManagerInfo.netConfig"); - } - - private void getHostVMs() throws Exception { - ManagedObjectReference morHost = new ManagedObjectReference(); - morHost.setType("HostSystem"); - morHost.set_value("host-48"); - - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("VirtualMachine"); - pSpec.setPathSet(new String[] { "name", "runtime.powerState", "config.template" }); - - TraversalSpec host2VmTraversal = new TraversalSpec(); - host2VmTraversal.setType("HostSystem"); - host2VmTraversal.setPath("vm"); - host2VmTraversal.setName("host2VmTraversal"); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(morHost); - oSpec.setSkip(Boolean.TRUE); - oSpec.setSelectSet(new SelectionSpec[] { host2VmTraversal }); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] { pSpec }); - pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - - ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( - cb.getServiceConnection3().getServiceContent().getPropertyCollector(), - new PropertyFilterSpec[] { pfSpec }); - this.printContent(ocs); - } - - private void testFT() throws Exception { - - ManagedObjectReference morVm = new ManagedObjectReference(); - morVm.setType("VirtualMachine"); - morVm.set_value("vm-480"); - - ManagedObjectReference morHost = new ManagedObjectReference(); - morHost.setType("HostSystem"); - morHost.set_value("host-470"); - - System.out.println("Create secondary VM"); - ManagedObjectReference morTask = cb.getServiceConnection3().getService().createSecondaryVM_Task(morVm, morHost); - String result = cb.getServiceUtil3().waitForTask(morTask); - - System.out.println("Create secondary VM resutl : " + result); - } - - private void testFTEnable() throws Exception { - ManagedObjectReference morVm = new ManagedObjectReference(); - morVm.setType("VirtualMachine"); - morVm.set_value("vm-480"); - - ManagedObjectReference morHost = new ManagedObjectReference(); - morHost.setType("HostSystem"); - morHost.set_value("host-470"); - - ManagedObjectReference morSecondaryVm = new ManagedObjectReference(); - morSecondaryVm.setType("VirtualMachine"); - morSecondaryVm.set_value("vm-485"); - - System.out.println("Enable FT"); - ManagedObjectReference morTask = cb.getServiceConnection3().getService().enableSecondaryVM_Task(morVm, - morSecondaryVm, morHost); - String result = cb.getServiceUtil3().waitForTask(morTask); - - System.out.println("Enable FT resutl : " + result); - } - private DatacenterMO setupDatacenterObject(String serverAddress, String dcMor) { - VmwareContext context = new VmwareContext(cb, serverAddress); - - ManagedObjectReference morDc = new ManagedObjectReference(); - morDc.setType("Datacenter"); - morDc.set_value(dcMor); - - return new DatacenterMO(context, morDc); - } - - private DistributedVirtualSwitchMO setupDistributedVirtualSwitchObject(String dvsMor, String serverAddress) { - VmwareContext context = new VmwareContext(cb, serverAddress); - return new DistributedVirtualSwitchMO(context, setupDVS(dvsMor)); - } - - private ManagedObjectReference setupDVS(String dvsMor) { - ManagedObjectReference morDvs = new ManagedObjectReference(); - morDvs.setType("VmwareDistributedVirtualSwitch"); - morDvs.set_value(dvsMor); - return morDvs; - } - - private void testDvSwitchOperations() throws Exception { - String dvSwitchName, dcMor; - ManagedObjectReference queriedDvs; - ManagedObjectReference morDvs; - DatacenterMO dcMo; - URL serviceUrl; - - // Initialize mor for existing DVS - if (_args.length <= IND_DVSWITCH_NAME) { - System.out.println("Using default parameters as required command line arguments are not provided."); - System.out.println("Sequence of arguments: "); - morDvs = setupDVS("dvs-921"); - dvSwitchName = "dvSwitch0"; - dcMor = "datacenter-2"; - } else { - morDvs = setupDVS(_args[IND_DVSWITCH_MOR]); - dvSwitchName = _args[IND_DVSWITCH_NAME]; - dcMor = _args[IND_DATACENTER_MOR]; - } - - serviceUrl = new URL(cb.getServiceUrl()); - - // Initialize Datacenter Object that pertains to above DVS - dcMo = setupDatacenterObject(serviceUrl.getHost(), dcMor); - - // Query for DVS with name - queriedDvs = dcMo.getDvSwitchMor(dvSwitchName); - - System.out.print("\nTest fetch dvSwitch object from vCenter : "); - if (morDvs.equals(queriedDvs)) { - System.out.println("Success\n"); - } else { - System.out.println("Failed\n"); - } - } - - private void testDvPortGroupOpearations() throws Exception { - // addDvPortGroup, updateDvPortGroup, getDvPortGroup, hasDvPortGroup - ManagedObjectReference morDvs, morDvPortGroup; - DatacenterMO dcMo; - DistributedVirtualSwitchMO dvsMo; - int networkRateMbps; - int networkRateMbpsToUpdate; - DVSTrafficShapingPolicy shapingPolicy; - VmwareDistributedVirtualSwitchVlanSpec vlanSpec; - DVSSecurityPolicy secPolicy; - VMwareDVSPortSetting dvsPortSetting; - DVPortgroupConfigSpec dvPortGroupSpec; - DVPortgroupConfigInfo dvPortgroupInfo = null; - String dvPortGroupName, dcMor; - Integer vid; - int numPorts; - int timeOutMs; - URL serviceUrl; - - if (_args.length < MAX_ARGS) { - System.out.println("Using default parameters as required command line arguments are not provided."); - System.out.println("Sequence of arguments: "); - morDvs = setupDVS("dvs-921"); - dvPortGroupName = "cloud.public.201.dvSwitch0.1"; - networkRateMbps = 201; - vid = new Integer(399); // VLAN 399 - timeOutMs = 7000; - numPorts = 64; - dcMor = "datacenter-2"; - } else { - morDvs = setupDVS(_args[IND_DVSWITCH_MOR]); - dvPortGroupName = _args[IND_DVPORTGROUP_NAME]; - vid = new Integer(IND_DVPORTGROUP_VLAN); - dcMor = _args[IND_DATACENTER_MOR]; - numPorts = Integer.parseInt(_args[IND_DVPORTGROUP_PORTCOUNT]); - timeOutMs = 7000; - networkRateMbps = 201; - } - serviceUrl = new URL(cb.getServiceUrl()); - - // Initialize Datacenter Object that pertains to above DVS - dcMo = setupDatacenterObject(serviceUrl.getHost(), dcMor); - // Create dvPortGroup configuration spec - dvsMo = setupDistributedVirtualSwitchObject(morDvs.get_value(), serviceUrl.getHost()); - - shapingPolicy = HypervisorHostHelper.getDVSShapingPolicy(networkRateMbps); - secPolicy = HypervisorHostHelper.createDVSSecurityPolicy(); - if (vid != null) { - vlanSpec = HypervisorHostHelper.createDVPortVlanIdSpec(vid); - } else { - vlanSpec = HypervisorHostHelper.createDVPortVlanSpec(); - } - dvsPortSetting = HypervisorHostHelper.createVmwareDVPortSettingSpec(shapingPolicy, secPolicy, vlanSpec); - dvPortGroupSpec = HypervisorHostHelper.createDvPortGroupSpec(dvPortGroupName, dvsPortSetting, numPorts); - if (!dcMo.hasDvPortGroup(dvPortGroupName)) { - System.out.print("\nTest create dvPortGroup : "); - try { - // Call method to create dvPortGroup - dvsMo.createDVPortGroup(dvPortGroupSpec); - System.out.println("Success\n"); - HypervisorHostHelper.waitForDvPortGroupReady(dcMo, dvPortGroupName, timeOutMs); - } catch (Exception e) { - System.out.println("Failed\n"); - throw new Exception(e); - } - } - - // Test for presence of dvPortGroup - System.out.print("\nTest presence of dvPortGroup : "); - if (dcMo.hasDvPortGroup(dvPortGroupName)) { - System.out.println("Success\n"); - } else { - System.out.println("Failed\n"); - } - - // Test get existing dvPortGroup - System.out.print("\nTest fetch dvPortGroup configuration : "); - try { - dvPortgroupInfo = dcMo.getDvPortGroupSpec(dvPortGroupName); - if (dvPortgroupInfo != null) - System.out.println("Success\n"); - } catch (Exception e) { - System.out.println("Failed\n"); - } - // Test compare dvPortGroup configuration - System.out.print("\nTest compare dvPortGroup configuration : "); - - if (HypervisorHostHelper.isSpecMatch(dvPortgroupInfo, vid, shapingPolicy)) { - System.out.println("Success\n"); - // We haven't modified the dvPortGroup after creating above. - // Hence expecting to be matching. - // NOTE : Hopefully nothing changes the configuration externally. - } else { - System.out.println("Failed\n"); - } - - // Test update dvPortGroup configuration - networkRateMbpsToUpdate = 210; - shapingPolicy = HypervisorHostHelper.getDVSShapingPolicy(networkRateMbpsToUpdate); - dvsPortSetting = HypervisorHostHelper.createVmwareDVPortSettingSpec(shapingPolicy, secPolicy, vlanSpec); - dvPortGroupSpec.setDefaultPortConfig(dvsPortSetting); - dvPortGroupSpec.setConfigVersion(dvPortgroupInfo.getConfigVersion()); - morDvPortGroup = dcMo.getDvPortGroupMor(dvPortGroupName); - System.out.print("\nTest update dvPortGroup configuration : "); - if (!HypervisorHostHelper.isSpecMatch(dvPortgroupInfo, vid, shapingPolicy)) { - try { - dvsMo.updateDvPortGroup(morDvPortGroup, dvPortGroupSpec); - System.out.println("Success\n"); - } catch (Exception e) { - System.out.println("Failed\n"); - throw new Exception(e); - } - } - } - private void importOVF() throws Exception { - ManagedObjectReference morHost = new ManagedObjectReference(); - morHost.setType("HostSystem"); - morHost.set_value("host-223"); - - ManagedObjectReference morRp = new ManagedObjectReference(); - morRp.setType("ResourcePool"); - morRp.set_value("resgroup-222"); - - ManagedObjectReference morDs = new ManagedObjectReference(); - morDs.setType("Datastore"); - morDs.set_value("datastore-30"); - - ManagedObjectReference morVmFolder = new ManagedObjectReference(); - morVmFolder.setType("Folder"); - morVmFolder.set_value("group-v3"); - - ManagedObjectReference morNetwork = new ManagedObjectReference(); - morNetwork.setType("Network"); - morNetwork.set_value("network-32"); - - ManagedObjectReference morOvf = cb.getServiceConnection3().getServiceContent().getOvfManager(); - - OvfCreateImportSpecParams importSpecParams = new OvfCreateImportSpecParams(); - importSpecParams.setHostSystem(morHost); - importSpecParams.setLocale("US"); - importSpecParams.setEntityName("winxpsp3-ovf-deployed"); - importSpecParams.setDeploymentOption(""); - importSpecParams.setDiskProvisioning("thin"); - -/* - OvfNetworkMapping networkMapping = new OvfNetworkMapping(); - networkMapping.setName("VM Network"); - networkMapping.setNetwork(morNetwork); // network); - importSpecParams.setNetworkMapping(new OvfNetworkMapping[] { networkMapping }); -*/ - importSpecParams.setPropertyMapping(null); - - String ovfDescriptor = readOvfContent("C:\\research\\vmware\\winxpsp3-ovf\\winxpsp3-ovf.ovf"); - OvfCreateImportSpecResult ovfImportResult = cb.getServiceConnection3().getService().createImportSpec( - morOvf, ovfDescriptor, morRp, morDs, importSpecParams); - - if(ovfImportResult != null) { - long totalBytes = addTotalBytes(ovfImportResult); - - ManagedObjectReference morLease = cb.getServiceConnection3().getService().importVApp(morRp, - ovfImportResult.getImportSpec(), morVmFolder, morHost); - - HttpNfcLeaseState state; - for(;;) { - state = (HttpNfcLeaseState)cb.getServiceUtil3().getDynamicProperty(morLease, "state"); - if(state == HttpNfcLeaseState.ready || state == HttpNfcLeaseState.error) - break; - } - - if(state == HttpNfcLeaseState.ready) { - HttpNfcLeaseInfo httpNfcLeaseInfo = (HttpNfcLeaseInfo)cb.getServiceUtil3().getDynamicProperty(morLease, "info"); - HttpNfcLeaseDeviceUrl[] deviceUrls = httpNfcLeaseInfo.getDeviceUrl(); - long bytesAlreadyWritten = 0; - for (HttpNfcLeaseDeviceUrl deviceUrl : deviceUrls) { - - String deviceKey = deviceUrl.getImportKey(); - for (OvfFileItem ovfFileItem : ovfImportResult.getFileItem()) { - if (deviceKey.equals(ovfFileItem.getDeviceId())) { - System.out.println("Import key==OvfFileItem device id: " + deviceKey); - System.out.println("device URL: " + deviceUrl.getUrl()); - - String absoluteFile = "C:\\research\\vmware\\winxpsp3-ovf\\" + ovfFileItem.getPath(); - String urlToPost = deviceUrl.getUrl().replace("*", "esxhost-1.lab.vmops.com"); - - uploadVmdkFile(ovfFileItem.isCreate(), absoluteFile, urlToPost, bytesAlreadyWritten, totalBytes); - bytesAlreadyWritten += ovfFileItem.getSize(); - System.out.println("Completed uploading the VMDK file:" + absoluteFile); - } - } - } - cb.getServiceConnection3().getService().httpNfcLeaseProgress(morLease, 100); - cb.getServiceConnection3().getService().httpNfcLeaseComplete(morLease); - } - } - } - - private static void uploadVmdkFile(boolean put, String diskFilePath, String urlStr, long bytesAlreadyWritten, long totalBytes) throws IOException { - HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { - public boolean verify(String urlHostName, SSLSession session) { - return true; - } - }); - - HttpsURLConnection conn = (HttpsURLConnection) new URL(urlStr).openConnection(); - - conn.setDoOutput(true); - conn.setUseCaches(false); - - int CHUCK_LEN = 64*1024; - conn.setChunkedStreamingMode(CHUCK_LEN); - conn.setRequestMethod(put? "PUT" : "POST"); // Use a post method to write the file. - conn.setRequestProperty("Connection", "Keep-Alive"); - conn.setRequestProperty("Content-Type", "application/x-vnd.vmware-streamVmdk"); - conn.setRequestProperty("Content-Length", Long.toString(new File(diskFilePath).length())); - BufferedOutputStream bos = new BufferedOutputStream(conn.getOutputStream()); - BufferedInputStream diskis = new BufferedInputStream(new FileInputStream(diskFilePath)); - int bytesAvailable = diskis.available(); - int bufferSize = Math.min(bytesAvailable, CHUCK_LEN); - byte[] buffer = new byte[bufferSize]; - long totalBytesWritten = 0; - while (true) { - int bytesRead = diskis.read(buffer, 0, bufferSize); - if (bytesRead == -1) - { - System.out.println("Total bytes written: " + totalBytesWritten); - break; - } - totalBytesWritten += bytesRead; - bos.write(buffer, 0, bufferSize); - bos.flush(); - System.out.println("Total bytes written: " + totalBytesWritten); - -/* - int progressPercent = (int) (((bytesAlreadyWritten + totalBytesWritten) * 100) / totalBytes); - leaseUpdater.setPercent(progressPercent); -*/ - } - diskis.close(); - bos.flush(); - bos.close(); - conn.disconnect(); - } - - public static long addTotalBytes(OvfCreateImportSpecResult ovfImportResult) { - OvfFileItem[] fileItemArr = ovfImportResult.getFileItem(); - long totalBytes = 0; - if (fileItemArr != null) { - for (OvfFileItem fi : fileItemArr) { - printOvfFileItem(fi); - totalBytes += fi.getSize(); - } - } - return totalBytes; - } - - private static void printOvfFileItem(OvfFileItem fi) { - System.out.println("================ OvfFileItem ================"); - System.out.println("chunkSize: " + fi.getChunkSize()); - System.out.println("create: " + fi.isCreate()); - System.out.println("deviceId: " + fi.getDeviceId()); - System.out.println("path: " + fi.getPath()); - System.out.println("size: " + fi.getSize()); - System.out.println("=============================================="); - } - - public static String readOvfContent(String ovfFilePath) throws IOException { - StringBuffer strContent = new StringBuffer(); - BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(ovfFilePath))); - String lineStr; - while ((lineStr = in.readLine()) != null) { - strContent.append(lineStr); - } - - in.close(); - return strContent.toString(); - } - - public static String escapeSpecialChars(String str) { - str = str.replaceAll("<", "<"); - return str.replaceAll(">", ">"); // do not escape "&" -> "&", "\"" -> """ - } - - public static void main(String[] args) throws Exception { - setupLog4j(); - TestVMWare client = new TestVMWare(); - - // skip certificate check - System.setProperty("axis.socketSecureFactory", "org.apache.axis.components.net.SunFakeTrustSocketFactory"); - - String serviceUrl = "https://" + args[0] + "/sdk/vimService"; - - try { - String[] params = new String[] {"--url", serviceUrl, "--username", args[1], "--password", args[2] }; - - cb = ExtendedAppUtil.initialize("Connect", params); - cb.connect(); - System.out.println("Connection Succesful."); - _args = args; - - // client.listInventoryFolders(); - // client.listDataCenters(); - // client.powerOnVm(); - // client.createSnapshot(); - // client.registerTemplate(); - // client.createVmFromTemplate(); - // client.addNic(); - // client.addNicToNetwork(); - - // client.createDatacenter(); - // client.getPropertyWithPath(); - // client.getHostVMs(); - // client.testFT(); - // client.testFTEnable(); - - // client.importOVF(); - - // Test get DvSwitch - client.testDvSwitchOperations(); - // Test add DvPortGroup, - // Test update vPortGroup, - // Test get DvPortGroup, - // Test compare DvPortGroup - client.testDvPortGroupOpearations(); - - // Test addDvNic - // Test deleteDvNic - // client.testDvNicOperations(); - - cb.disConnect(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static class TrustAllManager implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager { - - public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return null; - } - - public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) { - return true; - } - - public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) { - return true; - } - - public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) - throws java.security.cert.CertificateException { - return; - } - public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) - throws java.security.cert.CertificateException { - return; - } - } -} - From 9ee853313439a2cb4c3cbd9ae2a650ed6b44274a Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Tue, 7 May 2013 11:44:23 +0200 Subject: [PATCH 20/71] commit e0d8f01ecd92a1a7b74558d02a28be3b2f20a10d enabled all tests. Fix AWSAPI build by removing broken tests and excluding failing tests. --- awsapi/pom.xml | 33 +- .../com/cloud/gate/model/ModelTestCase.java | 368 ------------------ .../cloud/gate/persist/PersitTestCase.java | 73 ---- 3 files changed, 11 insertions(+), 463 deletions(-) delete mode 100644 awsapi/test/com/cloud/gate/model/ModelTestCase.java delete mode 100644 awsapi/test/com/cloud/gate/persist/PersitTestCase.java diff --git a/awsapi/pom.xml b/awsapi/pom.xml index f19a71381d3..d4573491723 100644 --- a/awsapi/pom.xml +++ b/awsapi/pom.xml @@ -286,12 +286,6 @@ - install - src - src @@ -307,6 +301,17 @@ + + org.apache.maven.plugins + maven-surefire-plugin + + + com/cloud/gate/util/UtilTestCase.java + com/cloud/gate/service/ServiceTestCase.java + com/cloud/gate/util/CloudStackClientTestCase.java + + + org.apache.maven.plugins maven-war-plugin @@ -364,22 +369,6 @@ - diff --git a/awsapi/test/com/cloud/gate/model/ModelTestCase.java b/awsapi/test/com/cloud/gate/model/ModelTestCase.java deleted file mode 100644 index 91aeaa75215..00000000000 --- a/awsapi/test/com/cloud/gate/model/ModelTestCase.java +++ /dev/null @@ -1,368 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.gate.model; - -import java.util.Date; -import java.util.Iterator; -import java.util.List; - -import org.apache.log4j.Logger; -import org.hibernate.Query; -import org.hibernate.Session; -import org.hibernate.Transaction; -import org.junit.Assert; - -import com.cloud.bridge.model.MHost; -import com.cloud.bridge.model.MHostMount; -import com.cloud.bridge.model.SBucket; -import com.cloud.bridge.model.SHost; -import com.cloud.bridge.model.SMeta; -import com.cloud.bridge.model.SObject; -import com.cloud.bridge.util.CloudSessionFactory; -import com.cloud.bridge.util.QueryHelper; -import com.cloud.gate.testcase.BaseTestCase; - -public class ModelTestCase extends BaseTestCase { - protected final static Logger logger = Logger.getLogger(ModelTestCase.class); - - public void testSHost() { - SHost host; - - // create the record - Session session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - host = new SHost(); - host.setHost("localhost"); - host.setExportRoot("/"); - host.setUserOnHost("root"); - host.setUserPassword("password"); - session.saveOrUpdate(host); - txn.commit(); - } finally { - session.close(); - } - Assert.assertTrue(host.getId() != 0); - - // retrive the record - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - host = (SHost)session.get(SHost.class, (long)host.getId()); - txn.commit(); - - Assert.assertTrue(host.getHost().equals("localhost")); - Assert.assertTrue(host.getUserOnHost().equals("root")); - Assert.assertTrue(host.getUserPassword().equals("password")); - - logger.info("Retrived record, host:" + host.getHost() - + ", user: " + host.getUserOnHost() - + ", password: " + host.getUserPassword()); - - } finally { - session.close(); - } - - // delete the record - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - host = (SHost)session.get(SHost.class, (long)host.getId()); - session.delete(host); - txn.commit(); - } finally { - session.close(); - } - - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - host = (SHost)session.get(SHost.class, (long)host.getId()); - txn.commit(); - - Assert.assertTrue(host == null); - } finally { - session.close(); - } - } - - public void testSBucket() { - SHost host; - SBucket bucket; - Session session; - - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - host = new SHost(); - host.setHost("localhost"); - host.setUserOnHost("root"); - host.setUserPassword("password"); - host.setExportRoot("/"); - - bucket = new SBucket(); - bucket.setName("Bucket"); - bucket.setOwnerCanonicalId("OwnerId-dummy"); - bucket.setCreateTime(new Date()); - - host.getBuckets().add(bucket); - bucket.setShost(host); - - session.save(host); - session.save(bucket); - txn.commit(); - } finally { - session.close(); - } - - long bucketId = bucket.getId(); - - // load bucket - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - bucket = (SBucket)session.get(SBucket.class, bucketId); - txn.commit(); - - Assert.assertTrue(bucket.getShost().getHost().equals("localhost")); - Assert.assertTrue(bucket.getName().equals("Bucket")); - Assert.assertTrue(bucket.getOwnerCanonicalId().equals("OwnerId-dummy")); - } finally { - session.close(); - } - - // delete the bucket - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - bucket = (SBucket)session.get(SBucket.class, bucketId); - session.delete(bucket); - - host = (SHost)session.get(SHost.class, host.getId()); - session.delete(host); - txn.commit(); - } finally { - session.close(); - } - - // verify the deletion - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - bucket = (SBucket)session.get(SBucket.class, bucketId); - txn.commit(); - - Assert.assertTrue(bucket == null); - } finally { - session.close(); - } - } - - public void testSObject() { - SHost host; - SBucket bucket; - Session session; - SObject sobject; - - // setup - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - host = new SHost(); - host.setHost("localhost"); - host.setUserOnHost("root"); - host.setUserPassword("password"); - host.setExportRoot("/"); - - bucket = new SBucket(); - bucket.setName("Bucket"); - bucket.setOwnerCanonicalId("OwnerId-dummy"); - bucket.setCreateTime(new Date()); - bucket.setShost(host); - host.getBuckets().add(bucket); - - sobject = new SObject(); - sobject.setNameKey("ObjectNameKey"); - sobject.setOwnerCanonicalId("OwnerId-dummy"); - sobject.setCreateTime(new Date()); - sobject.setBucket(bucket); - bucket.getObjectsInBucket().add(sobject); - - session.save(host); - session.save(bucket); - session.save(sobject); - txn.commit(); - - } finally { - session.close(); - } - - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - sobject = (SObject)session.get(SObject.class, sobject.getId()); - txn.commit(); - Assert.assertTrue(sobject.getBucket().getName().equals("Bucket")); - Assert.assertTrue(sobject.getNameKey().equals("ObjectNameKey")); - Assert.assertTrue(sobject.getOwnerCanonicalId().equals("OwnerId-dummy")); - } finally { - session.close(); - } - - // test delete cascade - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - bucket = (SBucket)session.get(SBucket.class, bucket.getId()); - session.delete(bucket); - - host = (SHost)session.get(SHost.class, host.getId()); - session.delete(host); - txn.commit(); - } finally { - session.close(); - } - } - - public void testMeta() { - Session session; - - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - SMeta meta = new SMeta(); - meta.setTarget("SObject"); - meta.setTargetId(1); - meta.setName("param1"); - meta.setValue("value1"); - session.save(meta); - - logger.info("Meta 1: " + meta.getId()); - - meta = new SMeta(); - meta.setTarget("SObject"); - meta.setTargetId(1); - meta.setName("param2"); - meta.setValue("value2"); - session.save(meta); - - logger.info("Meta 2: " + meta.getId()); - - txn.commit(); - } finally { - session.close(); - } - - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - Query query = session.createQuery("from SMeta where target=? and targetId=?"); - QueryHelper.bindParameters(query, new Object[] { - "SObject", new Long(1) - }); - List l = QueryHelper.executeQuery(query); - txn.commit(); - - for(SMeta meta: l) { - logger.info("" + meta.getName() + "=" + meta.getValue()); - } - } finally { - session.close(); - } - - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - Query query = session.createQuery("delete from SMeta where target=?"); - QueryHelper.bindParameters(query, new Object[] {"SObject"}); - query.executeUpdate(); - txn.commit(); - } finally { - session.close(); - } - } - - public void testHosts() { - Session session; - SHost shost; - MHost mhost; - MHostMount hostMount; - - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - shost = new SHost(); - shost.setHost("Storage host1"); - shost.setUserOnHost("root"); - shost.setUserPassword("password"); - shost.setExportRoot("/"); - session.save(shost); - - mhost = new MHost(); - mhost.setHostKey("1"); - mhost.setHost("management host1"); - mhost.setVersion("v1"); - session.save(mhost); - - hostMount = new MHostMount(); - hostMount.setMhost(mhost); - hostMount.setShost(shost); - hostMount.setMountPath("/mnt"); - session.save(hostMount); - txn.commit(); - } finally { - session.close(); - } - - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - mhost = (MHost)session.createQuery("from MHost where hostKey=?"). - setLong(0, new Long(1)).uniqueResult(); - - if(mhost != null) { - Iterator it = mhost.getMounts().iterator(); - while(it.hasNext()) { - MHostMount mount = (MHostMount)it.next(); - Assert.assertTrue(mount.getMountPath().equals("/mnt")); - - logger.info(mount.getMountPath()); - } - } - txn.commit(); - } finally { - session.close(); - } - - session = CloudSessionFactory.getInstance().openSession(); - try { - Transaction txn = session.beginTransaction(); - mhost = (MHost)session.createQuery("from MHost where hostKey=?"). - setLong(0, new Long(1)).uniqueResult(); - if(mhost != null) - session.delete(mhost); - - shost = (SHost)session.createQuery("from SHost where host=?"). - setString(0, "Storage host1").uniqueResult(); - if(shost != null) - session.delete(shost); - txn.commit(); - } finally { - session.close(); - } - } -} diff --git a/awsapi/test/com/cloud/gate/persist/PersitTestCase.java b/awsapi/test/com/cloud/gate/persist/PersitTestCase.java deleted file mode 100644 index 4961d932682..00000000000 --- a/awsapi/test/com/cloud/gate/persist/PersitTestCase.java +++ /dev/null @@ -1,73 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.gate.persist; - -import org.apache.log4j.Logger; - -import com.cloud.bridge.persist.PersistContext; -import com.cloud.gate.testcase.BaseTestCase; - -public class PersitTestCase extends BaseTestCase { - protected final static Logger logger = Logger.getLogger(PersitTestCase.class); - - public void testNamedLock() { - Thread t1 = new Thread(new Runnable() { - public void run() { - for(int i = 0; i < 10; i++) { - if(PersistContext.acquireNamedLock("TestLock", 3)) { - logger.info("Thread 1 acquired lock"); - try { - Thread.currentThread().sleep(BaseTestCase.getRandomMilliseconds(5000, 10000)); - } catch (InterruptedException e) { - } - logger.info("Thread 1 to release lock"); - PersistContext.releaseNamedLock("TestLock"); - } else { - logger.info("Thread 1 is unable to acquire lock"); - } - } - } - }); - - Thread t2 = new Thread(new Runnable() { - public void run() { - for(int i = 0; i < 10; i++) { - if(PersistContext.acquireNamedLock("TestLock", 3)) { - logger.info("Thread 2 acquired lock"); - try { - Thread.currentThread().sleep(BaseTestCase.getRandomMilliseconds(1000, 5000)); - } catch (InterruptedException e) { - } - logger.info("Thread 2 to release lock"); - PersistContext.releaseNamedLock("TestLock"); - } else { - logger.info("Thread 2 is unable to acquire lock"); - } - } - } - }); - - t1.start(); - t2.start(); - - try { - t1.join(); - t2.join(); - } catch(InterruptedException e) { - } - } -} From 1d24cbc3071e6b6b75449e01ec8d1a4dc9744ec4 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 7 May 2013 15:26:48 +0530 Subject: [PATCH 21/71] add debug logs when access checkers fail to find API When the access checkers fail for api discovery, we fail silently. instead record a debug message. Signed-off-by: Prasanna Santhanam --- .../org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java index 08fb573e4d9..860240faef0 100755 --- a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java +++ b/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java @@ -219,6 +219,7 @@ public class ApiDiscoveryServiceImpl implements ApiDiscoveryService { try { apiChecker.checkAccess(user, name); } catch (Exception ex) { + s_logger.debug("API discovery access check failed for " + name + " with " + ex.getMessage()); return null; } } From b8642c80efa8e4a3a7ae56db1264231ac0d7bf20 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 7 May 2013 15:27:26 +0530 Subject: [PATCH 22/71] adding ACL for dedicateGuestVlanRange set of APIs Signed-off-by: Prasanna Santhanam --- client/tomcatconf/commands.properties.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 22de93dc65d..687c3c16c75 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -126,8 +126,10 @@ createVlanIpRange=1 deleteVlanIpRange=1 listVlanIpRanges=1 dedicatePublicIpRange=1 -dedicateGuestVlanRange=1 releasePublicIpRange=1 +dedicateGuestVlanRange=1 +releaseDedicatedGuestVlanRange=1 +listDedicatedGuestVlanRanges=1 #### address commands associateIpAddress=15 From 808b49b21685ec850230c121492127f2047830c7 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 7 May 2013 15:28:20 +0530 Subject: [PATCH 23/71] Adding isolation method to the zone creation of marvin Signed-off-by: Prasanna Santhanam --- setup/dev/advanced.cfg | 3 +++ setup/dev/basic.cfg | 3 +++ tools/marvin/marvin/configGenerator.py | 1 + tools/marvin/marvin/deployDataCenter.py | 1 + tools/marvin/marvin/sandbox/advanced/advanced_env.py | 3 +++ tools/marvin/marvin/sandbox/basic/basic_env.py | 1 + tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py | 2 ++ 7 files changed, 14 insertions(+) diff --git a/setup/dev/advanced.cfg b/setup/dev/advanced.cfg index 431598947c6..63e435bb18f 100644 --- a/setup/dev/advanced.cfg +++ b/setup/dev/advanced.cfg @@ -46,6 +46,9 @@ "broadcastdomainrange": "ZONE", "name": "VpcVirtualRouter" } + ], + "isolationmethods": [ + "VLAN" ] } ], diff --git a/setup/dev/basic.cfg b/setup/dev/basic.cfg index 3f56a3ce980..326874d1f19 100644 --- a/setup/dev/basic.cfg +++ b/setup/dev/basic.cfg @@ -42,6 +42,9 @@ "broadcastdomainrange": "Pod", "name": "SecurityGroupProvider" } + ], + "isolationmethods": [ + "L3" ] } ], diff --git a/tools/marvin/marvin/configGenerator.py b/tools/marvin/marvin/configGenerator.py index e2a6a24d69f..4e82bbe387d 100644 --- a/tools/marvin/marvin/configGenerator.py +++ b/tools/marvin/marvin/configGenerator.py @@ -133,6 +133,7 @@ class physical_network(): self.traffictypes = [] self.broadcastdomainrange = 'Zone' self.vlan = None + self.isolationmethods = [] '''enable default virtual router provider''' vrouter = provider() vrouter.name = 'VirtualRouter' diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index 5ca1ebfb4f8..21685923b37 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -169,6 +169,7 @@ class deployDataCenters(): phynet = createPhysicalNetwork.createPhysicalNetworkCmd() phynet.zoneid = zoneid phynet.name = net.name + phynet.isolationmethods = net.isolationmethods phynetwrk = self.apiClient.createPhysicalNetwork(phynet) self.addTrafficTypes(phynetwrk.id, net.traffictypes) return phynetwrk diff --git a/tools/marvin/marvin/sandbox/advanced/advanced_env.py b/tools/marvin/marvin/sandbox/advanced/advanced_env.py index db78a84b33b..bf880f38055 100644 --- a/tools/marvin/marvin/sandbox/advanced/advanced_env.py +++ b/tools/marvin/marvin/sandbox/advanced/advanced_env.py @@ -46,6 +46,7 @@ def describeResources(config): z.name = 'Sandbox-%s'%(config.get('cloudstack', 'hypervisor')) z.networktype = 'Advanced' z.guestcidraddress = '10.1.1.0/24' + z.securitygroupenabled = 'false' vpcprovider = provider() vpcprovider.name = 'VpcVirtualRouter' @@ -57,6 +58,7 @@ def describeResources(config): pn.traffictypes = [traffictype("Guest"), traffictype("Management", {"simulator" : "cloud-simulator-mgmt"}), traffictype("Public", {"simulator":"cloud-simulator-public"})] + pn.isolationmethods = ["VLAN"] pn.providers.append(vpcprovider) pn2 = physical_network() @@ -64,6 +66,7 @@ def describeResources(config): pn2.vlan = config.get('cloudstack', 'pnet2.vlan') pn2.tags = ["cloud-simulator-guest"] pn2.traffictypes = [traffictype('Guest', {'simulator': 'cloud-simulator-guest'})] + pn2.isolationmethods = ["VLAN"] pn2.providers.append(vpcprovider) z.physical_networks.append(pn) diff --git a/tools/marvin/marvin/sandbox/basic/basic_env.py b/tools/marvin/marvin/sandbox/basic/basic_env.py index e588fdcc882..cf1869fa499 100644 --- a/tools/marvin/marvin/sandbox/basic/basic_env.py +++ b/tools/marvin/marvin/sandbox/basic/basic_env.py @@ -55,6 +55,7 @@ def describeResources(config): pn = physical_network() pn.name = "Sandbox-pnet" pn.traffictypes = [traffictype("Guest"), traffictype("Management")] + pn.isolationmethods = ["L3"] pn.providers.append(sgprovider) z.physical_networks.append(pn) diff --git a/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py b/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py index e4ec9b7b1b1..d45d48243bd 100644 --- a/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py +++ b/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py @@ -41,6 +41,7 @@ def describeResources(config): z.name = 'Sandbox-%s'%(config.get('environment', 'hypervisor')) z.networktype = 'Advanced' z.guestcidraddress = '10.1.1.0/24' + z.securitygroupenabled = 'false' vpcprovider = provider() vpcprovider.name = 'VpcVirtualRouter' @@ -48,6 +49,7 @@ def describeResources(config): pn = physical_network() pn.name = "Sandbox-pnet" pn.traffictypes = [traffictype("Guest"), traffictype("Management"), traffictype("Public")] + pn.isolationmethods = ["VLAN"] pn.providers.append(vpcprovider) pn.vlan = config.get('cloudstack', 'zone.vlan') From 887f405ce3b02abef807e7dc8b40cbc4f33ae5bd Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 7 May 2013 15:28:43 +0530 Subject: [PATCH 24/71] Renaming TesDedicateVlanRange -> TestDedicateVlanRange Signed-off-by: Prasanna Santhanam --- test/integration/smoke/test_guest_vlan_range.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/integration/smoke/test_guest_vlan_range.py b/test/integration/smoke/test_guest_vlan_range.py index 01cd68c1435..17234775ca1 100644 --- a/test/integration/smoke/test_guest_vlan_range.py +++ b/test/integration/smoke/test_guest_vlan_range.py @@ -44,15 +44,15 @@ class Services: "password": "password", }, "name": "testphysicalnetwork", - "vlan": "2118-2120", + "vlan": "118-120", } -class TesDedicateGuestVlanRange(cloudstackTestCase): +class TestDedicateGuestVlanRange(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.api_client = super(TesDedicateGuestVlanRange, cls).getClsTestClient().getApiClient() + cls.api_client = super(TestDedicateGuestVlanRange, cls).getClsTestClient().getApiClient() cls.services = Services().services # Get Zone, Domain cls.domain = get_domain(cls.api_client, cls.services) From b9f262aa1c30b38b5a2135faa62818fcb32e73d6 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Tue, 7 May 2013 17:06:15 +0530 Subject: [PATCH 25/71] Fixing the gmaven configuration for marvin/pom.xml For the marvin checkin test custom properties had a typo when run for the *nix environment. Signed-off-by: Prasanna Santhanam --- tools/marvin/pom.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml index 089c445ed9e..b8f7d7430a5 100644 --- a/tools/marvin/pom.xml +++ b/tools/marvin/pom.xml @@ -232,9 +232,13 @@ execute + + ${user.dir} + ${marvin.config} + - pom.properties['resolved.userdir']='${user.dir}'.replace('\','/').replace('D:','/cyg/d'); - pom.properties['resolved.marvin.config']='${marvin.config}'.replace('\','/').replace('D:','/cyg/d'); + project.properties['resolved.user.dir']='${user.dir}'.replace('\','/').replace('D:','/cyg/d'); + project.properties['resolved.marvin.config']='${marvin.config}'.replace('\','/').replace('D:','/cyg/d'); From 43fdb144e19332fa4a37a1c01376921545ebbc28 Mon Sep 17 00:00:00 2001 From: Radhika PC Date: Tue, 7 May 2013 18:26:08 +0530 Subject: [PATCH 26/71] CLOUDSTACK-893 api --- docs/en-US/added-API-commands-4.2.xml | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/docs/en-US/added-API-commands-4.2.xml b/docs/en-US/added-API-commands-4.2.xml index 34716240657..7417bd15f35 100644 --- a/docs/en-US/added-API-commands-4.2.xml +++ b/docs/en-US/added-API-commands-4.2.xml @@ -63,5 +63,48 @@ more IDs separated by comma); type (string); olderthan (yyyy-mm-dd format). The response parameters are: true, false + + createGlobalLoadBalancerRule + Creates a GSLB rule. The request parameters are name (the name of the global load + balancer rule); domain name ( the preferred domain name for the service); lb algorithm (the + algorithm used to load balance the traffic across the zones); session persistence (source IP + and HTTP cookie); account name; and domain Id. + + + assignToGlobalLoadBalancerRule + Assigns a load balancing rule or list of load balancing rules to GSLB. The request + parameters are: id (the UUID of global load balancer rule); loadbalancerrulelist (the list + load balancer rules that will be assigned to global load balancer rule. These are second + tier load balancing rules created with createLoadBalancerRule API. Weight is optional, the + default is 1). + + + removeFromGlobalLoadBalancerRule + Removes a load balancer rule association with global load balancer rule. The request + parameters are id (the UUID of global load balancer rule); loadbalancerrulelist (the list + load balancer rules that will be assigned to global load balancer rule). + + + deleteGlobalLoadBalancerRule + Deletes a global load balancer rule. The request parameters is: id (the unique ID of the + global load balancer rule). + + + listGlobalLoadBalancerRule + Lists load balancer rules. account (lists resources by account. Use with the domainId + parameter); domainid (lists only resources belonging to the domain specified) id (the unique + ID of the global load balancer rule) isrecursive (defaults to false, but if true, lists all + resources from the parent specified by the domainId till leaves); keyword (List by keyword); + listall (if set to false, list only resources belonging to the command's caller; if set to + true - list resources that the caller is authorized to see. Default value is false); page; + pagesize; projectid (lists objects by project); regionid (region ID); tags (lists resources + by tags: key/value pairs). + + + updateGlobalLoadBalancerRule + Archives the specified events. The request parameters are: ids (allowed to pass one or + more IDs separated by comma); type (string); olderthan (yyyy-mm-dd format). + The response parameters are: true, false + From 732566e70368ef771d2f29f951bfba3b8272f9c3 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Tue, 7 May 2013 13:02:29 -0700 Subject: [PATCH 27/71] CLOUDSTACK-2364: fixed private gateway creation in VPC - the vnet for the private gateway network is not stored in data_center_vnet table --- .../com/cloud/network/NetworkManagerImpl.java | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index a995661b9ce..4fffbc11072 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -2005,23 +2005,28 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L if (_networksDao.countByZoneAndUri(zoneId, uri) > 0) { throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId); } else { - DataCenterVnetVO dcVnet = _datacenterVnetDao.findVnet(zoneId, vlanId.toString()).get(0); - // Fail network creation if specified vlan is dedicated to a different account - if (dcVnet.getAccountGuestVlanMapId() != null) { - Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId(); - AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId); - if (map.getAccountId() != owner.getAccountId()) { - throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account"); - } - // Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool - } else { - List maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId()); - if (maps != null && !maps.isEmpty()) { - int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId()); - int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId()); - if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) { - throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + - " to the vlan range dedicated to the owner "+ owner.getAccountName()); + List dcVnets = _datacenterVnetDao.findVnet(zoneId, vlanId.toString()); + //for the network that is created as part of private gateway, + //the vnet is not coming from the data center vnet table, so the list can be empty + if (!dcVnets.isEmpty()) { + DataCenterVnetVO dcVnet = dcVnets.get(0); + // Fail network creation if specified vlan is dedicated to a different account + if (dcVnet.getAccountGuestVlanMapId() != null) { + Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId(); + AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId); + if (map.getAccountId() != owner.getAccountId()) { + throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account"); + } + // Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool + } else { + List maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId()); + if (maps != null && !maps.isEmpty()) { + int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId()); + int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId()); + if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) { + throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + + " to the vlan range dedicated to the owner "+ owner.getAccountName()); + } } } } From 5b74b4d6fe68e81d76ce8743c017201212f0d7aa Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 7 May 2013 15:44:28 -0700 Subject: [PATCH 28/71] UI plugin API: Support IE-compatible CSS loading If browser is IE < 9, use document.createStyleSheet to properly load plugin's CSS dynamically. --- ui/scripts/plugins.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/ui/scripts/plugins.js b/ui/scripts/plugins.js index 122f4a03491..6a886ba0ae6 100644 --- a/ui/scripts/plugins.js +++ b/ui/scripts/plugins.js @@ -20,15 +20,20 @@ } var loadCSS = function(path) { - var $link = $(''); + if (document.createStyleSheet) { + // IE-compatible CSS loading + document.createStyleSheet(path); + } else { + var $link = $(''); - $link.attr({ - rel: 'stylesheet', - type: 'text/css', - href: path - }); + $link.attr({ + rel: 'stylesheet', + type: 'text/css', + href: path + }); - $('head').append($link); + $('html head').append($link); + } }; $.extend(cloudStack.pluginAPI, { From 64dc39a2b068e0cb82ad300a98ae83e323137364 Mon Sep 17 00:00:00 2001 From: Hiroaki KAWAI Date: Wed, 8 May 2013 10:06:44 +0900 Subject: [PATCH 29/71] Fix typo Reported by Soheil Eizadi at dev@cloudstack.apache.org --- .../src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java old mode 100644 new mode 100755 index 8d21a55a65e..9ba1c836a98 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java @@ -95,7 +95,7 @@ public class DeleteNiciraNvpDeviceCmd extends BaseAsyncCmd { @Override public String getEventType() { - return EventTypes.EVENT_EXTERNAL_LB_DEVICE_DELETE; + return EventTypes.EVENT_EXTERNAL_NVP_CONTROLLER_DELETE; } @Override From 20bc334f2c9df58d658c9541b1fa43a47521d979 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Wed, 8 May 2013 08:32:48 +0530 Subject: [PATCH 30/71] CLOUDSTACK-2357 : Failed to update VNMC provider to enabled state --- .../src/com/cloud/network/element/CiscoVnmcElement.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java index 443bb40f57f..470c4e88217 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java @@ -434,16 +434,14 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro @Override public boolean isReady(PhysicalNetworkServiceProvider provider) { - // TODO Auto-generated method stub - return false; + return true; } @Override public boolean shutdownProviderInstances( PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { - // TODO Auto-generated method stub - return false; + return true; } @Override From 3a41a83f885cfd05b9fd951738abab30353618df Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Wed, 8 May 2013 11:20:12 +0530 Subject: [PATCH 31/71] [MARVIN] Fixing dedicate_guest_vlan_range test --- test/integration/smoke/test_guest_vlan_range.py | 17 +++++++---------- tools/marvin/marvin/integration/lib/base.py | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/test/integration/smoke/test_guest_vlan_range.py b/test/integration/smoke/test_guest_vlan_range.py index 17234775ca1..13cf335b893 100644 --- a/test/integration/smoke/test_guest_vlan_range.py +++ b/test/integration/smoke/test_guest_vlan_range.py @@ -149,15 +149,12 @@ class TestDedicateGuestVlanRange(cloudstackTestCase): ) self.debug("Releasing guest vlan range"); - dedicated_guest_vlan_response.release(self.apiclient) - list_dedicated_guest_vlan_range_response = PhysicalNetwork.listDedicated( - self.apiclient, - id=dedicate_guest_vlan_range_response.id - ) - dedicated_guest_vlan_response = list_dedicated_guest_vlan_range_response[0] + dedicate_guest_vlan_range_response.release(self.apiclient) + list_dedicated_guest_vlan_range_response = PhysicalNetwork.listDedicated(self.apiclient) self.assertEqual( - dedicated_guest_vlan_response.account, - "system", - "Check account name is system account in listDedicatedGuestVlanRanges" - ) + list_dedicated_guest_vlan_range_response, + None, + "Check vlan range is not available in listDedicatedGuestVlanRanges" + + ) diff --git a/tools/marvin/marvin/integration/lib/base.py b/tools/marvin/marvin/integration/lib/base.py index cdb6a36c41d..92b8a2d1e10 100755 --- a/tools/marvin/marvin/integration/lib/base.py +++ b/tools/marvin/marvin/integration/lib/base.py @@ -2202,7 +2202,7 @@ class PhysicalNetwork: cmd = listDedicatedGuestVlanRanges.listDedicatedGuestVlanRangesCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] - return map(lambda pn : PhysicalNetwork(pn.__dict__), apiclient.listDedicatedGuestVlanRanges(cmd)) + return apiclient.listDedicatedGuestVlanRanges(cmd) @classmethod def list(cls, apiclient, **kwargs): From b6cb23cb99c9daee41b46a3fc13fffabfb791dc3 Mon Sep 17 00:00:00 2001 From: Sanjay Tripathi Date: Wed, 3 Apr 2013 11:56:17 +0530 Subject: [PATCH 32/71] CLOUDSTACK-957: Localization -- Add UK keyboard support. --- .../console-proxy/server/css/ajaxviewer.css | 6 +- services/console-proxy/server/js/ajaxkeys.js | 295 ++++++++++++++++-- .../console-proxy/server/js/ajaxviewer.js | 128 ++------ .../consoleproxy/ConsoleProxyClientBase.java | 1 + 4 files changed, 295 insertions(+), 135 deletions(-) diff --git a/services/console-proxy/server/css/ajaxviewer.css b/services/console-proxy/server/css/ajaxviewer.css index 5ea552b176f..fd2fb3c44e9 100644 --- a/services/console-proxy/server/css/ajaxviewer.css +++ b/services/console-proxy/server/css/ajaxviewer.css @@ -91,12 +91,12 @@ body { position: absolute; top:32; width: 260; - height: 65; + height: 95; display: block; display: none; border-top: 1px solid black; - background-image:url(/resource/images/back.gif); - background-repeat:repeat-x repeat-y; + background-image:url(/resource/images/back.gif); + background-repeat:repeat-x repeat-y; } #toolbar ul li ul li { diff --git a/services/console-proxy/server/js/ajaxkeys.js b/services/console-proxy/server/js/ajaxkeys.js index 2ecf5b561e0..1ed41c562d4 100644 --- a/services/console-proxy/server/js/ajaxkeys.js +++ b/services/console-proxy/server/js/ajaxkeys.js @@ -23,55 +23,286 @@ under the License. * They are used by the ajaxviewer.js */ -//client event type. corresponds to events in ajaxviewer. -X11_KEY_CIRCUMFLEX_ACCENT = 0x5e; // ^ -X11_KEY_YEN_MARK = 0xa5; +//client event type. corresponds to events in ajaxviewer. + + +//use java AWT key modifier masks +JS_KEY_BACKSPACE = 8; +JS_KEY_TAB = 9; +JS_KEY_ENTER = 13; +JS_KEY_SHIFT = 16; +JS_KEY_CTRL = 17; +JS_KEY_ALT = 18; +JS_KEY_CAPSLOCK = 20; +JS_KEY_ESCAPE = 27; +JS_KEY_PAGEUP = 33; +JS_KEY_PAGEDOWN = 34; +JS_KEY_END = 35; +JS_KEY_HOME = 36; +JS_KEY_LEFT = 37; +JS_KEY_UP = 38; +JS_KEY_RIGHT = 39; +JS_KEY_DOWN = 40; +JS_KEY_INSERT = 45; +JS_KEY_DELETE = 46; +JS_KEY_SELECT_KEY = 93; +JS_KEY_NUMPAD0 = 96; +JS_KEY_NUMPAD1 = 97; +JS_KEY_NUMPAD2 = 98; +JS_KEY_NUMPAD3 = 99; +JS_KEY_NUMPAD4 = 100; +JS_KEY_NUMPAD5 = 101; +JS_KEY_NUMPAD6 = 102; +JS_KEY_NUMPAD7 = 103; +JS_KEY_NUMPAD8 = 104; +JS_KEY_NUMPAD9 = 105; +JS_KEY_MULTIPLY = 106; +JS_KEY_ADD = 107; +JS_KEY_SUBSTRACT = 109; +JS_KEY_DECIMAL_POINT = 110; +JS_KEY_DIVIDE = 111; +JS_KEY_F1 = 112; +JS_KEY_F2 = 113; +JS_KEY_F3 = 114; +JS_KEY_F4 = 115; +JS_KEY_F5 = 116; +JS_KEY_F6 = 117; +JS_KEY_F7 = 118; +JS_KEY_F8 = 119; +JS_KEY_F9 = 120; +JS_KEY_F10 = 121; +JS_KEY_F11 = 122; +JS_KEY_F12 = 123; +JS_KEY_SEMI_COLON = 186; // ; +JS_KEY_COMMA = 188; // , +JS_KEY_DASH = 189; // - +JS_KEY_PERIOD = 190; // . +JS_KEY_FORWARD_SLASH = 191; // / +JS_KEY_GRAVE_ACCENT = 192; // ` +JS_KEY_OPEN_BRACKET = 219; // [ +JS_KEY_BACK_SLASH = 220; // \ +JS_KEY_CLOSE_BRACKET = 221; // ] +JS_KEY_SINGLE_QUOTE = 222; // ' + + +//X11 keysym definitions +X11_KEY_CAPSLOCK = 0xffe5; +X11_KEY_BACKSPACE = 0xff08; +X11_KEY_TAB = 0xff09; +X11_KEY_ENTER = 0xff0d; +X11_KEY_ESCAPE = 0xff1b; +X11_KEY_INSERT = 0xff63; +X11_KEY_DELETE = 0xffff; +X11_KEY_HOME = 0xff50; +X11_KEY_END = 0xff57; +X11_KEY_PAGEUP = 0xff55; +X11_KEY_PAGEDOWN = 0xff56; +X11_KEY_LEFT = 0xff51; +X11_KEY_UP = 0xff52; +X11_KEY_RIGHT = 0xff53; +X11_KEY_DOWN = 0xff54; +X11_KEY_F1 = 0xffbe; +X11_KEY_F2 = 0xffbf; +X11_KEY_F3 = 0xffc0; +X11_KEY_F4 = 0xffc1; +X11_KEY_F5 = 0xffc2; +X11_KEY_F6 = 0xffc3; +X11_KEY_F7 = 0xffc4; +X11_KEY_F8 = 0xffc5; +X11_KEY_F9 = 0xffc6; +X11_KEY_F10 = 0xffc7; +X11_KEY_F11 = 0xffc8; +X11_KEY_F12 = 0xffc9; +X11_KEY_SHIFT = 0xffe1; +X11_KEY_CTRL = 0xffe3; +X11_KEY_ALT = 0xffe9; +X11_KEY_GRAVE_ACCENT = 0x60; +X11_KEY_SUBSTRACT = 0x2d; +X11_KEY_ADD = 0x2b; X11_KEY_OPEN_BRACKET = 0x5b; X11_KEY_CLOSE_BRACKET = 0x5d; +X11_KEY_BACK_SLASH = 0x7c; +X11_KEY_REVERSE_SOLIUS = 0x5c; // another back slash (back slash on JP keyboard) +X11_KEY_SINGLE_QUOTE = 0x22; +X11_KEY_COMMA = 0x3c; +X11_KEY_PERIOD = 0x3e; +X11_KEY_FORWARD_SLASH = 0x3f; +X11_KEY_DASH = 0x2d; X11_KEY_COLON = 0x3a; -X11_KEY_REVERSE_SOLIUS = 0x5c; // another back slash (back slash on JP keyboard) -X11_KEY_CAPSLOCK = 0xffe5; X11_KEY_SEMI_COLON = 0x3b; -X11_KEY_SHIFT = 0xffe1; -X11_KEY_ADD = 0x2b; +X11_KEY_NUMPAD0 = 0x30; +X11_KEY_NUMPAD1 = 0x31; +X11_KEY_NUMPAD2 = 0x32; +X11_KEY_NUMPAD3 = 0x33; +X11_KEY_NUMPAD4 = 0x34; +X11_KEY_NUMPAD5 = 0x35; +X11_KEY_NUMPAD6 = 0x36; +X11_KEY_NUMPAD7 = 0x37; +X11_KEY_NUMPAD8 = 0x38; +X11_KEY_NUMPAD9 = 0x39; +X11_KEY_DECIMAL_POINT = 0x2e; +X11_KEY_DIVIDE = 0x3f; +X11_KEY_TILDE = 0x7e; // ~ +X11_KEY_CIRCUMFLEX_ACCENT = 0x5e; // ^ +X11_KEY_YEN_MARK = 0xa5; // Japanese YEN mark +X11_KEY_ASTERISK = 0x2a; KEY_DOWN = 5; KEY_UP = 6; +KEYBOARD_TYPE_COOKED = "us"; +KEYBOARD_TYPE_JP = "jp"; +KEYBOARD_TYPE_UK = "uk"; + //JP keyboard type -// +// var keyboardTables = [ - {tindex: 0, keyboardType: "EN-Cooked", mappingTable: - {X11: [ {keycode: 222, entry: X11_KEY_CIRCUMFLEX_ACCENT}, + {tindex: 0, keyboardType: KEYBOARD_TYPE_COOKED, mappingTable: + {X11: [ {keycode: 222, entry: X11_KEY_CIRCUMFLEX_ACCENT}, {keycode: 220, entry: X11_KEY_YEN_MARK}, - {keycode: 219, entry: X11_KEY_OPEN_BRACKET}, - {keycode: 221, entry: X11_KEY_CLOSE_BRACKET}, - {keycode: 59, entry: X11_KEY_COLON, browser: "Firefox"}, {keycode: 186, entry: X11_KEY_COLON, browser: "Chrome"}, {keycode: 9, entry: 9, guestos: "XenServer"}, {keycode: 226, entry: X11_KEY_REVERSE_SOLIUS}, + {keycode: 240, entry: [ {type: KEY_DOWN, code: X11_KEY_CAPSLOCK, modifiers: 0 }, {type: KEY_UP, code: X11_KEY_CAPSLOCK, modifiers: 0 }, ] + } + ], + keyPress: [ + {keycode: 59, entry: [ + {type: KEY_DOWN, code: X11_KEY_SEMI_COLON, modifiers: 0 }, + {type: KEY_UP, code: X11_KEY_SEMI_COLON, modifiers: 0 }, + ] }, - ], - keyPress: [ - {keycode: 59, entry: [ - {type: KEY_DOWN, code: X11_KEY_SEMI_COLON, modifiers: 0 }, - {type: KEY_UP, code: X11_KEY_SEMI_COLON, modifiers: 0 }, - ] - }, - {keycode: 43, entry: [ - {type: KEY_DOWN, code: X11_KEY_SHIFT, modifiers: 0, shift: false }, - {type: KEY_DOWN, code: X11_KEY_ADD, modifiers: 0, shift: false }, - {type: KEY_UP, code: X11_KEY_ADD, modifiers: 0, shift: false }, - {type: KEY_UP, code: X11_KEY_SHIFT, modifiers: 0, shift: false }, - {type: KEY_DOWN, code: X11_KEY_ADD, modifiers: 0, shift: true }, - {type: KEY_UP, code: X11_KEY_ADD, modifiers: 0, shift: true }, - ] - }, - ] - } - } ] + {keycode: 43, entry: [ + {type: KEY_DOWN, code: X11_KEY_SHIFT, modifiers: 0, shift: false }, + {type: KEY_DOWN, code: X11_KEY_ADD, modifiers: 0, shift: false }, + {type: KEY_UP, code: X11_KEY_ADD, modifiers: 0, shift: false }, + {type: KEY_UP, code: X11_KEY_SHIFT, modifiers: 0, shift: false }, + {type: KEY_DOWN, code: X11_KEY_ADD, modifiers: 0, shift: true }, + {type: KEY_UP, code: X11_KEY_ADD, modifiers: 0, shift: true }, + ] + } + ] + } + }, {tindex: 1, keyboardType: KEYBOARD_TYPE_JP, mappingTable: + // intialize keyboard mapping for RAW keyboard + {X11: [ + {keycode: JS_KEY_CAPSLOCK, entry : X11_KEY_CAPSLOCK}, + {keycode: JS_KEY_BACKSPACE, entry : X11_KEY_BACKSPACE}, + {keycode: JS_KEY_TAB, entry : X11_KEY_TAB}, + {keycode: JS_KEY_ENTER, entry : X11_KEY_ENTER}, + {keycode: JS_KEY_ESCAPE, entry : X11_KEY_ESCAPE}, + {keycode: JS_KEY_INSERT, entry : X11_KEY_INSERT}, + {keycode: JS_KEY_DELETE, entry : X11_KEY_DELETE}, + {keycode: JS_KEY_HOME, entry : X11_KEY_HOME}, + {keycode: JS_KEY_END, entry : X11_KEY_END}, + {keycode: JS_KEY_PAGEUP, entry : X11_KEY_PAGEUP}, + {keycode: JS_KEY_PAGEDOWN, entry : X11_KEY_PAGEDOWN}, + {keycode: JS_KEY_LEFT, entry : X11_KEY_LEFT}, + {keycode: JS_KEY_UP, entry : X11_KEY_UP}, + {keycode: JS_KEY_RIGHT, entry : X11_KEY_RIGHT}, + {keycode: JS_KEY_DOWN, entry : X11_KEY_DOWN}, + {keycode: JS_KEY_F1, entry : X11_KEY_F1}, + {keycode: JS_KEY_F2, entry : X11_KEY_F2}, + {keycode: JS_KEY_F3, entry : X11_KEY_F3}, + {keycode: JS_KEY_F4, entry : X11_KEY_F4}, + {keycode: JS_KEY_F5, entry : X11_KEY_F5}, + {keycode: JS_KEY_F6, entry : X11_KEY_F6}, + {keycode: JS_KEY_F7, entry : X11_KEY_F7}, + {keycode: JS_KEY_F8, entry : X11_KEY_F8}, + {keycode: JS_KEY_F9, entry : X11_KEY_F9}, + {keycode: JS_KEY_F10, entry : X11_KEY_F10}, + {keycode: JS_KEY_F11, entry : X11_KEY_F11}, + {keycode: JS_KEY_F12, entry : X11_KEY_F12}, + {keycode: JS_KEY_SHIFT, entry : X11_KEY_SHIFT}, + {keycode: JS_KEY_CTRL, entry : X11_KEY_CTRL}, + {keycode: JS_KEY_ALT, entry : X11_KEY_ALT}, + {keycode: JS_KEY_GRAVE_ACCENT, entry : X11_KEY_GRAVE_ACCENT}, + {keycode: JS_KEY_SUBSTRACT, entry : X11_KEY_SUBSTRACT}, + {keycode: JS_KEY_ADD, entry : X11_KEY_ADD}, + {keycode: JS_KEY_OPEN_BRACKET, entry : X11_KEY_OPEN_BRACKET}, + {keycode: JS_KEY_CLOSE_BRACKET, entry : X11_KEY_CLOSE_BRACKET}, + {keycode: JS_KEY_BACK_SLASH, entry : X11_KEY_BACK_SLASH}, + {keycode: JS_KEY_SINGLE_QUOTE, entry : X11_KEY_SINGLE_QUOTE}, + {keycode: JS_KEY_COMMA, entry : X11_KEY_COMMA}, + {keycode: JS_KEY_PERIOD, entry : X11_KEY_PERIOD}, + {keycode: JS_KEY_FORWARD_SLASH, entry : X11_KEY_FORWARD_SLASH}, + {keycode: JS_KEY_DASH, entry : X11_KEY_DASH}, + {keycode: JS_KEY_SEMI_COLON, entry : X11_KEY_SEMI_COLON}, + {keycode: JS_KEY_NUMPAD0, entry : X11_KEY_NUMPAD0}, + {keycode: JS_KEY_NUMPAD1, entry : X11_KEY_NUMPAD1}, + {keycode: JS_KEY_NUMPAD2, entry : X11_KEY_NUMPAD2}, + {keycode: JS_KEY_NUMPAD3, entry : X11_KEY_NUMPAD3}, + {keycode: JS_KEY_NUMPAD4, entry : X11_KEY_NUMPAD4}, + {keycode: JS_KEY_NUMPAD5, entry : X11_KEY_NUMPAD5}, + {keycode: JS_KEY_NUMPAD6, entry : X11_KEY_NUMPAD6}, + {keycode: JS_KEY_NUMPAD7, entry : X11_KEY_NUMPAD7}, + {keycode: JS_KEY_NUMPAD8, entry : X11_KEY_NUMPAD8}, + {keycode: JS_KEY_NUMPAD9, entry : X11_KEY_NUMPAD9}, + {keycode: JS_KEY_DECIMAL_POINT, entry : X11_KEY_DECIMAL_POINT}, + {keycode: JS_KEY_DIVIDE, entry : X11_KEY_DIVIDE}, + {keycode: JS_KEY_MULTIPLY, entry : [ + {type: KEY_DOWN, code: X11_KEY_SHIFT, modifiers: 0 }, + {type: KEY_DOWN, code: X11_KEY_ASTERISK, modifiers: 0 }, + {type: KEY_UP, code: X11_KEY_ASTERISK, modifiers: 0 }, + {type: KEY_UP, code: X11_KEY_SHIFT, modifiers: 0 } + ]}, + {keycode: JS_KEY_ADD, entry : false} + ], + keyPress: [ + {keycode: 61, entry: [ + {type: KEY_DOWN, code: X11_KEY_ADD, modifiers: 0, shift: false }, + {type: KEY_UP, code: X11_KEY_ADD, modifiers: 0, shift: false } + ]}, + {keycode: 43, entry: [ + {type: KEY_DOWN, code: X11_KEY_SHIFT, modifiers: 0, shift: false }, + {type: KEY_DOWN, code: X11_KEY_ADD, modifiers: 0, shift: false }, + {type: KEY_UP, code: X11_KEY_ADD, modifiers: 0, shift: false }, + {type: KEY_UP, code: X11_KEY_SHIFT, modifiers: 0, shift: false }, + {type: KEY_DOWN, code: X11_KEY_ADD, modifiers: 0, shift: true }, + {type: KEY_UP, code: X11_KEY_ADD, modifiers: 0, shift: true } + ]} + ] + } + }, {tindex: 2, keyboardType: KEYBOARD_TYPE_UK, mappingTable: + {X11: [], + keyPress: [ + //[34 = "] + {keycode: 34, entry: + [{type : KEY_DOWN, code : 0x40, modifiers : 64, shift : true}] + }, + //[35 = #] + {keycode: 35, entry: + [{type : KEY_DOWN, code : 0x5c, modifiers : 0, shift : false}] + }, + // [64 = @] + {keycode: 64, entry: + [{type : KEY_DOWN, code : 0x22, modifiers : 64, shift : true}] + }, + // [92 = \] + {keycode: 92, entry: + [{type : KEY_DOWN, code : 0xa6, modifiers : 0, shift : false}] + }, + // [126 = ~] + {keycode: 126, entry: + [{type : KEY_DOWN, code : 0x7c, modifiers : 64, shift : true}] + }, + // [163 = £] + {keycode: 163, entry: + [{type : KEY_DOWN, code : 0x23, modifiers : 64, shift : true}] + }, + // [172 = ¬] + {keycode: 172, entry: + [{type : KEY_DOWN, code : 0x7e, modifiers : 64, shift : true}] + }, + // [166 = ¦] + {keycode: 166, entry: + [{type : KEY_DOWN, code : 0x60, modifiers : 896, shift : false}] + } + ] + } + }] diff --git a/services/console-proxy/server/js/ajaxviewer.js b/services/console-proxy/server/js/ajaxviewer.js index e95615d8946..a6e1edafaea 100644 --- a/services/console-proxy/server/js/ajaxviewer.js +++ b/services/console-proxy/server/js/ajaxviewer.js @@ -99,92 +99,13 @@ function KeyboardMapper() { // KeyboardMapper.KEYBOARD_TYPE_RAW = 0; KeyboardMapper.KEYBOARD_TYPE_COOKED = 1; +KeyboardMapper.KEYBOARD_TYPE_UK = 2; KeyboardMapper.prototype = { - + setKeyboardType : function(keyboardType) { this.keyboardType = keyboardType; - - if(keyboardType == KeyboardMapper.KEYBOARD_TYPE_RAW) { - // intialize keyboard mapping for RAW keyboard - this.jsX11KeysymMap[AjaxViewer.JS_KEY_CAPSLOCK] = AjaxViewer.X11_KEY_CAPSLOCK; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_BACKSPACE] = AjaxViewer.X11_KEY_BACKSPACE; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_TAB] = AjaxViewer.X11_KEY_TAB; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_ENTER] = AjaxViewer.X11_KEY_ENTER; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_ESCAPE] = AjaxViewer.X11_KEY_ESCAPE; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_INSERT] = AjaxViewer.X11_KEY_INSERT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_DELETE] = AjaxViewer.X11_KEY_DELETE; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_HOME] = AjaxViewer.X11_KEY_HOME; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_END] = AjaxViewer.X11_KEY_END; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_PAGEUP] = AjaxViewer.X11_KEY_PAGEUP; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_PAGEDOWN] = AjaxViewer.X11_KEY_PAGEDOWN; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_LEFT] = AjaxViewer.X11_KEY_LEFT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_UP] = AjaxViewer.X11_KEY_UP; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_RIGHT] = AjaxViewer.X11_KEY_RIGHT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_DOWN] = AjaxViewer.X11_KEY_DOWN; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F1] = AjaxViewer.X11_KEY_F1; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F2] = AjaxViewer.X11_KEY_F2; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F3] = AjaxViewer.X11_KEY_F3; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F4] = AjaxViewer.X11_KEY_F4; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F5] = AjaxViewer.X11_KEY_F5; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F6] = AjaxViewer.X11_KEY_F6; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F7] = AjaxViewer.X11_KEY_F7; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F8] = AjaxViewer.X11_KEY_F8; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F9] = AjaxViewer.X11_KEY_F9; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F10] = AjaxViewer.X11_KEY_F10; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F11] = AjaxViewer.X11_KEY_F11; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F12] = AjaxViewer.X11_KEY_F12; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_SHIFT] = AjaxViewer.X11_KEY_SHIFT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_CTRL] = AjaxViewer.X11_KEY_CTRL; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_ALT] = AjaxViewer.X11_KEY_ALT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_GRAVE_ACCENT] = AjaxViewer.X11_KEY_GRAVE_ACCENT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_SUBSTRACT] = AjaxViewer.X11_KEY_SUBSTRACT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_ADD] = AjaxViewer.X11_KEY_ADD; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_OPEN_BRACKET] = AjaxViewer.X11_KEY_OPEN_BRACKET; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_CLOSE_BRACKET] = AjaxViewer.X11_KEY_CLOSE_BRACKET; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_BACK_SLASH] = AjaxViewer.X11_KEY_BACK_SLASH; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_SINGLE_QUOTE] = AjaxViewer.X11_KEY_SINGLE_QUOTE; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_COMMA] = AjaxViewer.X11_KEY_COMMA; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_PERIOD] = AjaxViewer.X11_KEY_PERIOD; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_FORWARD_SLASH] = AjaxViewer.X11_KEY_FORWARD_SLASH; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_DASH] = AjaxViewer.X11_KEY_DASH; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_SEMI_COLON] = AjaxViewer.X11_KEY_SEMI_COLON; - - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD0] = AjaxViewer.X11_KEY_NUMPAD0; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD1] = AjaxViewer.X11_KEY_NUMPAD1; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD2] = AjaxViewer.X11_KEY_NUMPAD2; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD3] = AjaxViewer.X11_KEY_NUMPAD3; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD4] = AjaxViewer.X11_KEY_NUMPAD4; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD5] = AjaxViewer.X11_KEY_NUMPAD5; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD6] = AjaxViewer.X11_KEY_NUMPAD6; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD7] = AjaxViewer.X11_KEY_NUMPAD7; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD8] = AjaxViewer.X11_KEY_NUMPAD8; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD9] = AjaxViewer.X11_KEY_NUMPAD9; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_DECIMAL_POINT] = AjaxViewer.X11_KEY_DECIMAL_POINT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_DIVIDE] = AjaxViewer.X11_KEY_DIVIDE; - - this.jsX11KeysymMap[AjaxViewer.JS_KEY_MULTIPLY] = [ - {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0 }, - {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ASTERISK, modifiers: 0 }, - {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ASTERISK, modifiers: 0 }, - {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0 } - ]; - - this.jsX11KeysymMap[AjaxViewer.JS_KEY_ADD] = false; - this.jsKeyPressX11KeysymMap = []; - this.jsKeyPressX11KeysymMap[61] = [ - {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false }, - {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false } - ]; - this.jsKeyPressX11KeysymMap[43] = [ - {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0, shift: false }, - {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false }, - {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false }, - {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0, shift: false }, - {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: true }, - {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: true } - ]; - } else { + if(keyboardType == KeyboardMapper.KEYBOARD_TYPE_COOKED || keyboardType == KeyboardMapper.KEYBOARD_TYPE_UK) { // initialize mapping for COOKED keyboard this.jsX11KeysymMap[AjaxViewer.JS_KEY_CAPSLOCK] = AjaxViewer.X11_KEY_CAPSLOCK; this.jsX11KeysymMap[AjaxViewer.JS_KEY_BACKSPACE] = AjaxViewer.X11_KEY_BACKSPACE; @@ -325,7 +246,6 @@ KeyboardMapper.prototype = { // ENTER/BACKSPACE key should already have been sent through KEY DOWN/KEY UP event if(code == AjaxViewer.JS_KEY_ENTER || code == AjaxViewer.JS_KEY_BACKSPACE) return; - if(code > 0) { var X11Keysym = code; X11Keysym = this.jsKeyPressX11KeysymMap[code]; @@ -475,6 +395,7 @@ AjaxViewer.STATUS_SENDING = 3; AjaxViewer.STATUS_SENT = 4; AjaxViewer.KEYBOARD_TYPE_ENGLISH = "us"; +AjaxViewer.KEYBOARD_TYPE_UK_ENGLISH = "uk"; AjaxViewer.KEYBOARD_TYPE_JAPANESE = "jp"; AjaxViewer.JS_KEY_BACKSPACE = 8; @@ -736,6 +657,10 @@ AjaxViewer.prototype = { this.keyboardMappers[AjaxViewer.KEYBOARD_TYPE_ENGLISH] = mapper; mapper.setKeyboardType(KeyboardMapper.KEYBOARD_TYPE_COOKED); + var mapper = new KeyboardMapper(); + this.keyboardMappers[AjaxViewer.KEYBOARD_TYPE_UK_ENGLISH] = mapper; + mapper.setKeyboardType(KeyboardMapper.KEYBOARD_TYPE_UK); + mapper = new KeyboardMapper(); this.keyboardMappers[AjaxViewer.KEYBOARD_TYPE_JAPANESE] = mapper; mapper.setKeyboardType(KeyboardMapper.KEYBOARD_TYPE_RAW); @@ -795,25 +720,25 @@ AjaxViewer.prototype = { */ // create the mapping table based on the tables input - if (keyboardTables != undefined ) { + if (keyboardTables != undefined ) { - for(var i = 0; i < keyboardTables.length; i++) { - var mappingTbl = keyboardTables[i]; - var mappings = mappingTbl.mappingTable; - var x11Maps = mappings.X11; - for (var j = 0; j < x11Maps.length; j++) { - var code = x11Maps[j].keycode; - var mappedEntry = x11Maps[j].entry; - mapper.jsX11KeysymMap[code] = mappedEntry; + for(var i = 0; i < keyboardTables.length; i++) { + var mappingTbl = keyboardTables[i]; + var keyboardType = mappingTbl.keyboardType; + var mappings = mappingTbl.mappingTable; + var x11Maps = mappings.X11; + for (var j = 0; j < x11Maps.length; j++) { + var code = x11Maps[j].keycode; + var mappedEntry = x11Maps[j].entry; + this.keyboardMappers[keyboardType].jsX11KeysymMap[code] = mappedEntry; + } + var keyPressMaps = mappings.keyPress; + for (var j = 0; j < keyPressMaps.length; j++) { + var code = keyPressMaps[j].keycode; + var mappedEntry = keyPressMaps[j].entry; + this.keyboardMappers[keyboardType].jsKeyPressX11KeysymMap[code] = mappedEntry; + } } - var keyPressMaps = mappings.keyPress; - for (var j = 0; j < keyPressMaps.length; j++) { - var code = keyPressMaps[j].keycode; - var mappedEntry = keyPressMaps[j].entry; - mapper.jsKeyPressX11KeysymMap[code] = mappedEntry; - } - - } } }, // end of the setupKeyboardTranslationTable function @@ -867,6 +792,9 @@ AjaxViewer.prototype = { } else if(cmd == "keyboard_us") { $("#toolbar").find(".pulldown").find("ul").hide(); this.currentKeyboard = AjaxViewer.KEYBOARD_TYPE_ENGLISH; + } else if(cmd == "keyboard_uk") { + $("#toolbar").find(".pulldown").find("ul").hide(); + this.currentKeyboard = AjaxViewer.KEYBOARD_TYPE_UK_ENGLISH; } else if(cmd == "sendCtrlAltDel") { this.sendKeyboardEvent(AjaxViewer.KEY_DOWN, 0xffe9, 0); // X11 Alt this.sendKeyboardEvent(AjaxViewer.KEY_DOWN, 0xffe3, 0); // X11 Ctrl diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientBase.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientBase.java index 289bdab2f8a..f4c912a9e53 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientBase.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientBase.java @@ -329,6 +329,7 @@ public abstract class ConsoleProxyClientBase implements ConsoleProxyClient, Cons "", "", "
  • ", From 5ef2f1f26fcd159cb48b25882ea10cb3fc44d1b9 Mon Sep 17 00:00:00 2001 From: Sangeetha Hariharan Date: Fri, 3 May 2013 17:02:32 -0700 Subject: [PATCH 33/71] CLOUDSTACK-2329, CLOUDSTACK-1820: Tests for regions Marvin tests and corresponding library changes for the regions feature. Signed-off-by: Prasanna Santhanam --- test/integration/component/test_regions.py | 443 ++++++++++++++++++++ tools/marvin/marvin/integration/lib/base.py | 54 +++ 2 files changed, 497 insertions(+) create mode 100644 test/integration/component/test_regions.py diff --git a/test/integration/component/test_regions.py b/test/integration/component/test_regions.py new file mode 100644 index 00000000000..1b24871ce4c --- /dev/null +++ b/test/integration/component/test_regions.py @@ -0,0 +1,443 @@ +#!/usr/bin/env python +# 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 marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * +from marvin import remoteSSHClient +from nose.plugins.attrib import attr + +class Services: + """ + """ + + def __init__(self): + self.services = { + "domain": { + "name": "testuuid", + "domainUUID": "domain1" + }, + "account": { + "email": "test@test.com", + "firstname": "Testuuid", + "lastname": "Useruuid", + "username": "test", + # Random characters are appended for unique + # username + "password": "password", + "accountUUID": "account1", + "userUUID": "user1" + }, + "user": { + "email": "test@test.com", + "firstname": "Testuuid", + "lastname": "Useruuid", + "username": "test", + # Random characters are appended for unique + # username + "password": "password", + "userUUID": "user2" + }, + "ostype": 'CentOS 5.3 (64-bit)', + "region": { + "regionid": "2", + "regionname": "Region2", + "regionendpoint": "http://region2:8080/client" + } + } + + +class TestRegions(cloudstackTestCase): + """ + Testing Regions related Apis + """ + @classmethod + def setUpClass(cls): + cls.api_client = super(TestRegions, cls).getClsTestClient().getApiClient() + cls.services = Services().services + cls.domain = get_domain(cls.api_client, cls.services) + cls.cleanup = [] + return + + @attr(tags=["basic", "advanced"]) + def test_createAccountWithUUID(self): + """ + Test for creating Account by passing id parameter + + # Validate the following + # 1.Create an Account by passing id parameter.Verify the account is created. + # 2.List this account by passing id parameter.Verify that list account is able to lis this account. + # 3.Delete account should succeed. + + """ + account = Account.create( + self.api_client, + self.services["account"], + domainid=self.domain.id + ) + self.assertIn ( self.services["account"]["accountUUID"] , account.id, + "Account is not created with the accountId passed") + + list_account = Account.list(self.api_client, + id=account.id + ) + + self.assertEqual( + isinstance(list_account, list), + True, + "Check for list account response by uuid failed" + ) + + print (list_account) + + account_response = list_account[0] + + print (account_response) + + self.assertEqual( account_response.id, + account.id, + "listAccount response does not match with account Id " + ) + self.assertEqual( + account_response.user[0].firstname, + self.services["account"]["firstname"], + "listAccount response does not match with account firstname" + ) + + self.cleanup.append(account) + return + + @attr(tags=["basic", "advanced"]) + def test_createUserWithUUID(self): + """ + Test for creating User by passing id parameter + + # Validate the following + # 1.Create a User by passing id parameter.Verify the user is created. + # 2.List this user by passing id parameter.Verify that list user is able to list this user. + # 3.Delete User should succeed. + + """ + + user = User.create( + self.api_client, + self.services["user"], + account="Admin", + domainid=self.domain.id + ) + self.assertIn ( self.services["user"]["userUUID"] , user.id, + "User is not created successfully with the userId passed") + + list_user = User.list(self.api_client, + id=user.id + ) + + self.assertEqual( + isinstance(list_user, list), + True, + "Check for list user response by uuid failed" + ) + + + user_response = list_user[0] + + + self.assertEqual( user_response.id, + user.id, + "list User response does not match with user Id " + ) + self.assertEqual( + user_response.firstname, + self.services["user"]["firstname"], + "listUser response does not match with user firstname" + ) + + user.delete(self.api_client) + + list_user = User.list(self.api_client, + id=user.id + ) + + self.assertIsNone( + list_user, + "Deletion of user failed" + ) + + + return + + @attr(tags=["basic", "advanced"]) + def test_createdomainWithUUID(self): + """ + Test for creating Domain by passing id parameter + + # Validate the following + # 1.Create a domain by passing id parameter.Verify the domain is created. + # 2.List this domain by passing id parameter.Verify that list domain is able to list this domain. + # 3.Delete domain should succeed. + + """ + + domain = Domain.create( + self.api_client, + self.services["domain"] + ) + self.assertIn ( self.services["domain"]["domainUUID"] , domain.id, + "Domain is not created with the doaminId passed") + + list_domain = Domain.list(self.api_client, + id=domain.id + ) + + self.assertEqual( + isinstance(list_domain, list), + True, + "Check for list domain response by uuid failed" + ) + + + domain_response = list_domain[0] + + + self.assertEqual( domain_response.id, + domain.id, + "list domain response does not match with domain Id " + ) + self.assertIn( + self.services["domain"]["name"], + domain_response.name, + "list domaiin response does not match with user firstname" + ) + try: + domain.delete(self.api_client) + except Exception as e: + self.fail("Failed to delete domain: %s" % e) + + return + + @attr(tags=["basic", "advanced"]) + def test_createRegion(self): + """ + Test for add Region + """ + + region = Region.create(self.api_client, + self.services["region"] + ) + + list_region = Region.list(self.api_client, + id=self.services["region"]["regionid"] + ) + + self.assertEqual( + isinstance(list_region, list), + True, + "Check for list Region response" + ) + region_response = list_region[0] + + print (region_response) + print (self.services["region"]) + + self.assertEqual( + str(region_response.id), + self.services["region"]["regionid"], + "listRegion response does not match with region Id created" + ) + + self.assertEqual( + region_response.name, + self.services["region"]["regionname"], + "listRegion response does not match with region name created" + ) + self.assertEqual( + region_response.endpoint, + self.services["region"]["regionendpoint"], + "listRegion response does not match with region endpoint created" + ) + + region = region.delete(self.api_client) + + return + + @attr(tags=["basic", "advanced"]) + def test_createDupRegion(self): + """ + Test for duplicate checks on id and name parameters when adding regions + """ + + self.services["region"]["regionid"]="5" + self.services["region"]["regionname"]="Region5" + self.services["region"]["regionendpoint"]="http://region5:8080/client" + + + region = Region.create(self.api_client, + self.services["region"] + ) + + list_region = Region.list(self.api_client, + id=self.services["region"]["regionid"] + ) + + self.assertEqual( + isinstance(list_region, list), + True + ) + """ + Creating regions with duplicate id should not be allowed + """ + + self.services["region"]["regionid"]="5" + self.services["region"]["regionname"]="Region51" + self.services["region"]["regionendpoint"]="http://region51:8080/client" + + try: + region = Region.create(self.api_client, + self.services["region"] + ) + self.assertIsNone(region, + "Creating regions with duplicate id is allowed" + ) + except: + print " Creating Region with duplicate Id is not allowed" + pass + + """ + Creating regions with duplicate name should not be allowed + """ + + self.services["region"]["regionid"]="51" + self.services["region"]["regionname"]="Region5" + self.services["region"]["regionendpoint"]="http://region51:8080/client" + + try: + region = Region.create(self.api_client, + self.services["region"] + ) + except: + print " Creating Region with duplicate Name is not allowed" + pass + + region.delete(self.api_client) + + return + + @attr(tags=["basic", "advanced"]) + def test_updateRegion(self): + """ + Test for update Region + """ + + self.services["region"]["regionid"]="3" + self.services["region"]["regionname"]="Region3" + self.services["region"]["regionendpoint"]="http://region3:8080/client" + region = Region.create(self.api_client, + self.services["region"] + ) + + self.services["region"]["regionname"]="Region3upd" + self.services["region"]["regionendpoint"]="http://region3upd:8080/client" + + updated_region = region.update(self.api_client, + self.services["region"] + ) + + list_region = Region.list(self.api_client, + id=self.services["region"]["regionid"] + ) + + self.assertEqual( + isinstance(list_region, list), + True, + "Check for list Region response" + ) + region_response = list_region[0] + + self.assertEqual( + str(region_response.id), + self.services["region"]["regionid"], + "listRegion response does not match with region Id created" + ) + + self.assertEqual( + region_response.name, + self.services["region"]["regionname"], + "listRegion response does not match with region name created" + ) + self.assertEqual( + region_response.endpoint, + self.services["region"]["regionendpoint"], + "listRegion response does not match with region endpoint created" + ) + + region.delete(self.api_client) + + return + + @attr(tags=["basic", "advanced"]) + def test_deleteRegion(self): + """ + Test for delete Region + """ + + self.services["region"]["regionid"]="4" + self.services["region"]["regionname"]="Region4" + self.services["region"]["regionendpoint"]="http://region4:8080/client" + + region = Region.create(self.api_client, + self.services["region"] + ) + + list_region = Region.list(self.api_client, + id=self.services["region"]["regionid"] + ) + + print (list_region); + + self.assertEqual( + len(list_region), + 1, + "Check for Region response" + ) + + region = region.delete(self.api_client) + + list_region = Region.list(self.api_client, + id=self.services["region"]["regionid"] + ) + + print (list_region); + + self.assertIsNone(list_region, + "Check for empty Region response" + ) + + return + + + @classmethod + def tearDown(cls): + + try: + cls.api_client = super(TestRegions, cls).getClsTestClient().getApiClient() + #Clean up + cleanup_resources(cls.api_client, cls.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) diff --git a/tools/marvin/marvin/integration/lib/base.py b/tools/marvin/marvin/integration/lib/base.py index 92b8a2d1e10..899c203d87e 100755 --- a/tools/marvin/marvin/integration/lib/base.py +++ b/tools/marvin/marvin/integration/lib/base.py @@ -40,6 +40,9 @@ class Domain: cmd = createDomain.createDomainCmd() + if "domainUUID" in services: + cmd.domainid = "-".join([services["domainUUID"],random_gen()]) + if name: cmd.name = "-".join([name, random_gen()]) elif "name" in services: @@ -97,6 +100,13 @@ class Account: cmd.password = services["password"] cmd.username = "-".join([services["username"], random_gen()]) + if "accountUUID" in services: + cmd.accountid = "-".join([services["accountUUID"],random_gen()]) + + if "userUUID" in services: + cmd.userid = "-".join([services["userUUID"],random_gen()]) + + if domainid: cmd.domainid = domainid account = apiclient.createAccount(cmd) @@ -135,6 +145,9 @@ class User: cmd.firstname = services["firstname"] cmd.lastname = services["lastname"] + if "userUUID" in services: + cmd.userid = "-".join([services["userUUID"],random_gen()]) + # Password Encoding mdf = hashlib.md5() mdf.update(services["password"]) @@ -3108,3 +3121,44 @@ class VmSnapshot: cmd.vmsnapshotid = vmsnapshotid return apiclient.deleteVMSnapshot(cmd) + +class Region: + """ Regions related Api """ + def __init__(self, items): + self.__dict__.update(items) + + @classmethod + def create(cls, apiclient, services): + cmd = addRegion.addRegionCmd() + cmd.id = services["regionid"] + cmd.endpoint = services["regionendpoint"] + cmd.name = services["regionname"] + try: + region = apiclient.addRegion(cmd) + if region is not None: + return Region(region.__dict__) + except Exception as e: + raise e + + @classmethod + def list(cls, apiclient, **kwargs): + cmd = listRegions.listRegionsCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + region = apiclient.listRegions(cmd) + return region + + def update(self, apiclient, services): + cmd = updateRegion.updateRegionCmd() + cmd.id = self.id + if services["regionendpoint"]: + cmd.endpoint = services["regionendpoint"] + if services["regionname"]: + cmd.name = services["regionname"] + region = apiclient.updateRegion(cmd) + return region + + def delete(self, apiclient): + cmd = removeRegion.removeRegionCmd() + cmd.id = self.id + region = apiclient.removeRegion(cmd) + return region From 548a8d8c1f391812bb492b42704d21dd99ac59b7 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Wed, 8 May 2013 12:39:34 +0530 Subject: [PATCH 34/71] Breaking down region tests region tests will be run in smoke and regression. In smoke we only test the basic creation of a region. More extensive testing of duplicate regions, test for updating region atteributes is in component. Separated the class for testing accounts within region (account sync) into a a new suite. Signed-off-by: Prasanna Santhanam --- test/integration/component/test_regions.py | 471 ++++-------------- .../component/test_regions_accounts.py | 206 ++++++++ test/integration/smoke/test_regions.py | 93 ++++ tools/marvin/marvin/integration/lib/base.py | 8 +- 4 files changed, 387 insertions(+), 391 deletions(-) create mode 100644 test/integration/component/test_regions_accounts.py create mode 100644 test/integration/smoke/test_regions.py diff --git a/test/integration/component/test_regions.py b/test/integration/component/test_regions.py index 1b24871ce4c..daf16cd1f44 100644 --- a/test/integration/component/test_regions.py +++ b/test/integration/component/test_regions.py @@ -21,423 +21,120 @@ from marvin.cloudstackAPI import * from marvin.integration.lib.utils import * from marvin.integration.lib.base import * from marvin.integration.lib.common import * -from marvin import remoteSSHClient from nose.plugins.attrib import attr +from random import choice class Services: - """ - """ - def __init__(self): self.services = { - "domain": { - "name": "testuuid", - "domainUUID": "domain1" - }, - "account": { - "email": "test@test.com", - "firstname": "Testuuid", - "lastname": "Useruuid", - "username": "test", - # Random characters are appended for unique - # username - "password": "password", - "accountUUID": "account1", - "userUUID": "user1" - }, - "user": { - "email": "test@test.com", - "firstname": "Testuuid", - "lastname": "Useruuid", - "username": "test", - # Random characters are appended for unique - # username - "password": "password", - "userUUID": "user2" - }, - "ostype": 'CentOS 5.3 (64-bit)', - "region": { - "regionid": "2", - "regionname": "Region2", - "regionendpoint": "http://region2:8080/client" - } + "region": { + "regionid": "2", + "regionname": "Region2", + "regionendpoint": "http://region2:8080/client" + } } - class TestRegions(cloudstackTestCase): + """Test Regions - CRUD tests for regions """ - Testing Regions related Apis - """ + @classmethod def setUpClass(cls): cls.api_client = super(TestRegions, cls).getClsTestClient().getApiClient() cls.services = Services().services - cls.domain = get_domain(cls.api_client, cls.services) - cls.cleanup = [] + cls.domain = get_domain(cls.api_client, cls.services) + cls.cleanup = [] return - @attr(tags=["basic", "advanced"]) - def test_createAccountWithUUID(self): - """ - Test for creating Account by passing id parameter + def setUp(self): + pseudo_random_int = choice(xrange(1, 200)) + self.services["region"]["regionid"] = pseudo_random_int + self.services["region"]["regionname"] = "region" + str(pseudo_random_int) + self.services["region"]["regionendpoint"] = "http://region" + str(pseudo_random_int) + ":8080/client" - # Validate the following - # 1.Create an Account by passing id parameter.Verify the account is created. - # 2.List this account by passing id parameter.Verify that list account is able to lis this account. - # 3.Delete account should succeed. - - """ - account = Account.create( - self.api_client, - self.services["account"], - domainid=self.domain.id - ) - self.assertIn ( self.services["account"]["accountUUID"] , account.id, - "Account is not created with the accountId passed") - - list_account = Account.list(self.api_client, - id=account.id - ) - - self.assertEqual( - isinstance(list_account, list), - True, - "Check for list account response by uuid failed" - ) - - print (list_account) - - account_response = list_account[0] - - print (account_response) - - self.assertEqual( account_response.id, - account.id, - "listAccount response does not match with account Id " - ) - self.assertEqual( - account_response.user[0].firstname, - self.services["account"]["firstname"], - "listAccount response does not match with account firstname" - ) - - self.cleanup.append(account) - return - - @attr(tags=["basic", "advanced"]) - def test_createUserWithUUID(self): - """ - Test for creating User by passing id parameter - - # Validate the following - # 1.Create a User by passing id parameter.Verify the user is created. - # 2.List this user by passing id parameter.Verify that list user is able to list this user. - # 3.Delete User should succeed. - - """ - - user = User.create( - self.api_client, - self.services["user"], - account="Admin", - domainid=self.domain.id - ) - self.assertIn ( self.services["user"]["userUUID"] , user.id, - "User is not created successfully with the userId passed") - - list_user = User.list(self.api_client, - id=user.id - ) - - self.assertEqual( - isinstance(list_user, list), - True, - "Check for list user response by uuid failed" - ) - - - user_response = list_user[0] - - - self.assertEqual( user_response.id, - user.id, - "list User response does not match with user Id " - ) - self.assertEqual( - user_response.firstname, - self.services["user"]["firstname"], - "listUser response does not match with user firstname" - ) - - user.delete(self.api_client) - - list_user = User.list(self.api_client, - id=user.id - ) - - self.assertIsNone( - list_user, - "Deletion of user failed" - ) - - - return - - @attr(tags=["basic", "advanced"]) - def test_createdomainWithUUID(self): - """ - Test for creating Domain by passing id parameter - - # Validate the following - # 1.Create a domain by passing id parameter.Verify the domain is created. - # 2.List this domain by passing id parameter.Verify that list domain is able to list this domain. - # 3.Delete domain should succeed. - - """ - - domain = Domain.create( - self.api_client, - self.services["domain"] - ) - self.assertIn ( self.services["domain"]["domainUUID"] , domain.id, - "Domain is not created with the doaminId passed") - - list_domain = Domain.list(self.api_client, - id=domain.id - ) - - self.assertEqual( - isinstance(list_domain, list), - True, - "Check for list domain response by uuid failed" - ) - - - domain_response = list_domain[0] - - - self.assertEqual( domain_response.id, - domain.id, - "list domain response does not match with domain Id " - ) - self.assertIn( - self.services["domain"]["name"], - domain_response.name, - "list domaiin response does not match with user firstname" - ) - try: - domain.delete(self.api_client) - except Exception as e: - self.fail("Failed to delete domain: %s" % e) - - return - - @attr(tags=["basic", "advanced"]) - def test_createRegion(self): - """ - Test for add Region - """ - - region = Region.create(self.api_client, + self.region = Region.create(self.api_client, self.services["region"] - ) + ) + self.cleanup = [] + self.cleanup.append(self.region) - list_region = Region.list(self.api_client, + list_region = Region.list(self.api_client, id=self.services["region"]["regionid"] - ) - - self.assertEqual( - isinstance(list_region, list), - True, - "Check for list Region response" - ) - region_response = list_region[0] - - print (region_response) - print (self.services["region"]) + ) self.assertEqual( - str(region_response.id), - self.services["region"]["regionid"], - "listRegion response does not match with region Id created" - ) + isinstance(list_region, list), + True, + msg="Region creation failed" + ) - self.assertEqual( - region_response.name, - self.services["region"]["regionname"], - "listRegion response does not match with region name created" - ) - self.assertEqual( - region_response.endpoint, - self.services["region"]["regionendpoint"], - "listRegion response does not match with region endpoint created" - ) - - region = region.delete(self.api_client) - - return - - @attr(tags=["basic", "advanced"]) - def test_createDupRegion(self): - """ - Test for duplicate checks on id and name parameters when adding regions - """ - - self.services["region"]["regionid"]="5" - self.services["region"]["regionname"]="Region5" - self.services["region"]["regionendpoint"]="http://region5:8080/client" - - - region = Region.create(self.api_client, - self.services["region"] - ) - - list_region = Region.list(self.api_client, - id=self.services["region"]["regionid"] - ) - - self.assertEqual( - isinstance(list_region, list), - True - ) - """ - Creating regions with duplicate id should not be allowed + @attr(tags=["simulator", "basic", "advanced"]) + def test_createRegionWithExistingRegionId(self): + """Test for duplicate checks on region id """ + self.services["region"]["regionname"] = random_gen() #alter region name but not id + self.assertRaises(Exception, Region.create, self.api_client, self.services["region"]) - self.services["region"]["regionid"]="5" - self.services["region"]["regionname"]="Region51" - self.services["region"]["regionendpoint"]="http://region51:8080/client" + @attr(tags=["simulator", "basic", "advanced"]) + def test_createRegionWithExistingRegionName(self): + """Test for duplicate checks on region name + """ + random_int = choice(xrange(1, 200)) + self.services["region"]["regionid"] = random_int #alter id but not name + self.services["region"]["regionendpoint"] = "http://region" + str(random_int) + ":8080/client" + self.assertRaises(Exception, Region.create, self.api_client, self.services["region"]) - try: - region = Region.create(self.api_client, - self.services["region"] - ) - self.assertIsNone(region, - "Creating regions with duplicate id is allowed" - ) - except: - print " Creating Region with duplicate Id is not allowed" - pass - - """ - Creating regions with duplicate name should not be allowed - """ - - self.services["region"]["regionid"]="51" - self.services["region"]["regionname"]="Region5" - self.services["region"]["regionendpoint"]="http://region51:8080/client" - - try: - region = Region.create(self.api_client, - self.services["region"] - ) - except: - print " Creating Region with duplicate Name is not allowed" - pass - - region.delete(self.api_client) - - return - - @attr(tags=["basic", "advanced"]) + @attr(tags=["simulator", "basic", "advanced"]) def test_updateRegion(self): - """ - Test for update Region - """ + """ Test for update Region + """ + self.services["region"]["regionname"] = "Region3" + random_gen() + self.services["region"]["regionendpoint"] = "http://region3updated:8080/client" - self.services["region"]["regionid"]="3" - self.services["region"]["regionname"]="Region3" - self.services["region"]["regionendpoint"]="http://region3:8080/client" - region = Region.create(self.api_client, - self.services["region"] - ) + updated_region = self.region.update(self.api_client, + self.services["region"] + ) - self.services["region"]["regionname"]="Region3upd" - self.services["region"]["regionendpoint"]="http://region3upd:8080/client" + list_region = Region.list(self.api_client, + id=self.services["region"]["regionid"] + ) - updated_region = region.update(self.api_client, - self.services["region"] - ) + self.assertEqual( + isinstance(list_region, list), + True, + "Check for list Region response" + ) + region_response = list_region[0] - list_region = Region.list(self.api_client, - id=self.services["region"]["regionid"] - ) + self.assertEqual( + region_response.id, + updated_region.id, + "listRegion response does not match with region Id created" + ) - self.assertEqual( - isinstance(list_region, list), - True, - "Check for list Region response" - ) - region_response = list_region[0] + self.assertEqual( + region_response.name, + updated_region.name, + "listRegion response does not match with region name created" + ) + self.assertEqual( + region_response.endpoint, + updated_region.endpoint, + "listRegion response does not match with region endpoint created" + ) - self.assertEqual( - str(region_response.id), - self.services["region"]["regionid"], - "listRegion response does not match with region Id created" - ) + def tearDown(self): + """ Test for delete region as cleanup + """ + try: + #Clean up + cleanup_resources(self.api_client, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) - self.assertEqual( - region_response.name, - self.services["region"]["regionname"], - "listRegion response does not match with region name created" - ) - self.assertEqual( - region_response.endpoint, - self.services["region"]["regionendpoint"], - "listRegion response does not match with region endpoint created" - ) - - region.delete(self.api_client) - - return - - @attr(tags=["basic", "advanced"]) - def test_deleteRegion(self): - """ - Test for delete Region - """ - - self.services["region"]["regionid"]="4" - self.services["region"]["regionname"]="Region4" - self.services["region"]["regionendpoint"]="http://region4:8080/client" - - region = Region.create(self.api_client, - self.services["region"] - ) - - list_region = Region.list(self.api_client, - id=self.services["region"]["regionid"] - ) - - print (list_region); - - self.assertEqual( - len(list_region), - 1, - "Check for Region response" - ) - - region = region.delete(self.api_client) - - list_region = Region.list(self.api_client, - id=self.services["region"]["regionid"] - ) - - print (list_region); - - self.assertIsNone(list_region, - "Check for empty Region response" - ) - - return - - - @classmethod - def tearDown(cls): - - try: - cls.api_client = super(TestRegions, cls).getClsTestClient().getApiClient() - #Clean up - cleanup_resources(cls.api_client, cls.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + @classmethod + def tearDownClass(cls): + """ + Nothing to do + """ + pass diff --git a/test/integration/component/test_regions_accounts.py b/test/integration/component/test_regions_accounts.py new file mode 100644 index 00000000000..113f725f598 --- /dev/null +++ b/test/integration/component/test_regions_accounts.py @@ -0,0 +1,206 @@ +# 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 marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * +from nose.plugins.attrib import attr + +class Services: + def __init__(self): + self.services = { + "domain": { + "name": "testuuid", + "domainUUID": "domain1" + }, + "account": { + "email": "test@test.com", + "firstname": "Testuuid", + "lastname": "Useruuid", + "username": "test", + "password": "password", + "accountUUID": "account1", + "userUUID": "user1" + }, + "user": { + "email": "test@test.com", + "firstname": "Testuuid", + "lastname": "Useruuid", + "username": "test", + "password": "password", + "userUUID": "user2" + }, + } + + +class TestRegionsAccounts(cloudstackTestCase): + """Test Accounts in Regions - CRUD tests for accounts in regions + """ + + @classmethod + def setUpClass(cls): + cls.api_client = super(TestRegionsAccounts, cls).getClsTestClient().getApiClient() + cls.services = Services().services + cls.domain = get_domain(cls.api_client, cls.services) + cls.cleanup = [] + return + + @attr(tags=["simulator", "basic", "advanced"]) + def test_createAccountWithUUID(self): + """Test for creating account by passing id parameter + + # Validate the following + # 1.Create an Account by passing id parameter.Verify the account is created. + # 2.List this account by passing id parameter.Verify that list account is able to lis this account. + # 3.Delete account should succeed. + """ + account = Account.create( + self.api_client, + self.services["account"], + domainid=self.domain.id + ) + self.assertIn(self.services["account"]["accountUUID"], account.id, + "Account is not created with the accountId passed") + + list_account = Account.list(self.api_client, + id=account.id) + + self.assertEqual( + isinstance(list_account, list), + True, + "Check for list account response by uuid failed" + ) + + account_response = list_account[0] + self.assertEqual(account_response.id, + account.id, + "listAccount response does not match with account Id " + ) + self.assertEqual( + account_response.user[0].firstname, + self.services["account"]["firstname"], + "listAccount response does not match with account firstname" + ) + + self.cleanup.append(account) + return + + @attr(tags=["simulator", "basic", "advanced"]) + def test_createUserWithUUID(self): + """Test for creating User by passing id parameter + + # Validate the following + # 1.Create a User by passing id parameter.Verify the user is created. + # 2.List this user by passing id parameter.Verify that list user is able to list this user. + # 3.Delete User should succeed. + """ + + user = User.create( + self.api_client, + self.services["user"], + account="admin", + domainid=self.domain.id + ) + self.assertIn(self.services["user"]["userUUID"], user.id, + "User is not created successfully with the userId passed") + + list_user = User.list(self.api_client, id=user.id) + + self.assertEqual( + isinstance(list_user, list), + True, + "Check for list user response by uuid failed" + ) + + user_response = list_user[0] + + self.assertEqual(user_response.id, + user.id, + "list User response does not match with user Id " + ) + self.assertEqual( + user_response.firstname, + self.services["user"]["firstname"], + "listUser response does not match with user firstname" + ) + + user.delete(self.api_client) + + list_user = User.list(self.api_client, + id=user.id + ) + + self.assertIsNone( + list_user, + "Deletion of user failed" + ) + return + + @attr(tags=["simulator", "basic", "advanced"]) + def test_createdomainWithUUID(self): + """Test for creating Domain by passing id parameter + + # Validate the following + # 1.Create a domain by passing id parameter.Verify the domain is created. + # 2.List this domain by passing id parameter.Verify that list domain is able to list this domain. + # 3.Delete domain should succeed. + """ + + domain = Domain.create( + self.api_client, + self.services["domain"] + ) + + self.assertIn(self.services["domain"]["domainUUID"], domain.id, + "Domain is not created with the doaminId passed") + + list_domain = Domain.list(self.api_client, + id=domain.id + ) + + self.assertEqual( + isinstance(list_domain, list), + True, + "Check for list domain response by uuid failed" + ) + + domain_response = list_domain[0] + + self.assertEqual(domain_response.id, + domain.id, + "list domain response does not match with domain Id " + ) + self.assertIn( + self.services["domain"]["name"], + domain_response.name, + "list domaiin response does not match with user firstname" + ) + try: + domain.delete(self.api_client) + except Exception as e: + self.fail("Failed to delete domain: %s" % e) + return + + @classmethod + def tearDownClass(cls): + try: + #Clean up + cleanup_resources(cls.api_client, cls.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) \ No newline at end of file diff --git a/test/integration/smoke/test_regions.py b/test/integration/smoke/test_regions.py new file mode 100644 index 00000000000..5d12e74e8dd --- /dev/null +++ b/test/integration/smoke/test_regions.py @@ -0,0 +1,93 @@ +# 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 marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * +from nose.plugins.attrib import attr + +class Services: + def __init__(self): + self.services = { + "region": { + "regionid": "2", + "regionname": "Region2", + "regionendpoint": "http://region2:8080/client" + } + } + + +class TestRegions(cloudstackTestCase): + """Test Regions - basic region creation + """ + + @classmethod + def setUpClass(cls): + cls.api_client = super(TestRegions, cls).getClsTestClient().getApiClient() + cls.services = Services().services + cls.domain = get_domain(cls.api_client, cls.services) + cls.cleanup = [] + + @attr(tags=["simulator", "basic", "advanced"]) + def test_createRegion(self): + """ Test for create region + """ + region = Region.create(self.api_client, + self.services["region"] + ) + + list_region = Region.list(self.api_client, + id=self.services["region"]["regionid"] + ) + + self.assertEqual( + isinstance(list_region, list), + True, + "Check for list Region response" + ) + region_response = list_region[0] + + self.assertEqual( + str(region_response.id), + self.services["region"]["regionid"], + "listRegion response does not match with region Id created" + ) + + self.assertEqual( + region_response.name, + self.services["region"]["regionname"], + "listRegion response does not match with region name created" + ) + self.assertEqual( + region_response.endpoint, + self.services["region"]["regionendpoint"], + "listRegion response does not match with region endpoint created" + ) + self.cleanup.append(region) + return + + @classmethod + def tearDownClass(cls): + try: + #Clean up + cleanup_resources(cls.api_client, cls.cleanup) + list_region = Region.list(cls.api_client, id=cls.services["region"]["regionid"]) + assert list_region is None, "Region deletion fails" + except Exception as e: + raise Exception("Warning: Region cleanup/delete fails with : %s" % e) \ No newline at end of file diff --git a/tools/marvin/marvin/integration/lib/base.py b/tools/marvin/marvin/integration/lib/base.py index 899c203d87e..ecdc8412fdb 100755 --- a/tools/marvin/marvin/integration/lib/base.py +++ b/tools/marvin/marvin/integration/lib/base.py @@ -40,8 +40,8 @@ class Domain: cmd = createDomain.createDomainCmd() - if "domainUUID" in services: - cmd.domainid = "-".join([services["domainUUID"],random_gen()]) + if "domainUUID" in services: + cmd.domainid = "-".join([services["domainUUID"], random_gen()]) if name: cmd.name = "-".join([name, random_gen()]) @@ -3151,9 +3151,9 @@ class Region: cmd = updateRegion.updateRegionCmd() cmd.id = self.id if services["regionendpoint"]: - cmd.endpoint = services["regionendpoint"] + cmd.endpoint = services["regionendpoint"] if services["regionname"]: - cmd.name = services["regionname"] + cmd.name = services["regionname"] region = apiclient.updateRegion(cmd) return region From 93db64fc2531d72713c6b26d9e749f9aa6fd6640 Mon Sep 17 00:00:00 2001 From: Talluri Date: Wed, 8 May 2013 00:57:26 +0530 Subject: [PATCH 35/71] CLOUDSTACK-2359: fix missing network type in the test scripts test_volumes.py and test_templates.py Signed-off-by: Prasanna Santhanam --- test/integration/smoke/test_guest_vlan_range.py | 2 +- test/integration/smoke/test_templates.py | 1 + test/integration/smoke/test_volumes.py | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/test/integration/smoke/test_guest_vlan_range.py b/test/integration/smoke/test_guest_vlan_range.py index 13cf335b893..bd533430f51 100644 --- a/test/integration/smoke/test_guest_vlan_range.py +++ b/test/integration/smoke/test_guest_vlan_range.py @@ -44,7 +44,7 @@ class Services: "password": "password", }, "name": "testphysicalnetwork", - "vlan": "118-120", + "vlan": "2118-2120", } diff --git a/test/integration/smoke/test_templates.py b/test/integration/smoke/test_templates.py index fa4bc4014ec..b2ad4ca5634 100644 --- a/test/integration/smoke/test_templates.py +++ b/test/integration/smoke/test_templates.py @@ -292,6 +292,7 @@ class TestTemplates(cloudstackTestCase): # Get Zone, Domain and templates cls.domain = get_domain(cls.api_client, cls.services) cls.zone = get_zone(cls.api_client, cls.services) + cls.services['mode'] = cls.zone.networktype #populate second zone id for iso copy cmd = listZones.listZonesCmd() zones = cls.api_client.listZones(cmd) diff --git a/test/integration/smoke/test_volumes.py b/test/integration/smoke/test_volumes.py index ecac8c903c1..4bf8203e74c 100644 --- a/test/integration/smoke/test_volumes.py +++ b/test/integration/smoke/test_volumes.py @@ -287,6 +287,7 @@ class TestVolumes(cloudstackTestCase): # Get Zone, Domain and templates cls.domain = get_domain(cls.api_client, cls.services) cls.zone = get_zone(cls.api_client, cls.services) + cls.services['mode'] = cls.zone.networktype cls.disk_offering = DiskOffering.create( cls.api_client, cls.services["disk_offering"] From 8be304434e808660f17c5753abbf455a49ed7602 Mon Sep 17 00:00:00 2001 From: Talluri Date: Wed, 8 May 2013 02:41:02 +0530 Subject: [PATCH 36/71] CLOUDSTACK-2361: fix storage xenmotion test script Signed-off-by: Prasanna Santhanam --- .../component/test_storage_motion.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/test/integration/component/test_storage_motion.py b/test/integration/component/test_storage_motion.py index 086ec77b48d..c05d79e6861 100644 --- a/test/integration/component/test_storage_motion.py +++ b/test/integration/component/test_storage_motion.py @@ -98,16 +98,16 @@ class TestStorageMotion(cloudstackTestCase): # Get Zone, Domain and templates domain = get_domain(cls.api_client, cls.services) - zone = get_zone(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) cls.services['mode'] = cls.zone.networktype template = get_template( cls.api_client, - zone.id, + cls.zone.id, cls.services["ostype"] ) # Set Zones and disk offerings - cls.services["small"]["zoneid"] = zone.id + cls.services["small"]["zoneid"] = cls.zone.id cls.services["small"]["template"] = template.id # Create VMs, NAT Rules etc @@ -258,6 +258,17 @@ class TestStorageMotion(cloudstackTestCase): self.apiclient, id=volume.id ) + self.assertEqual( + isinstance(pools, list), + True, + "Check list storage pools response for valid list" + ) + self.assertNotEqual( + pools, + None, + "Check if pools exists in ListStoragePools" + ) + pool = pools[0] self.debug("Migrating Volume-ID: %s to Pool: %s" % ( volume.id, From 731cc439a363fd3b17b1ed5eeca51f92f9e993cc Mon Sep 17 00:00:00 2001 From: Talluri Date: Wed, 8 May 2013 14:12:46 +0530 Subject: [PATCH 37/71] CLOUDSTACK-2362: correct list append method fix userdata integration test --- test/integration/smoke/test_deploy_vm_with_userdata.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/integration/smoke/test_deploy_vm_with_userdata.py b/test/integration/smoke/test_deploy_vm_with_userdata.py index fd9e320addc..8ca9bd05a2d 100644 --- a/test/integration/smoke/test_deploy_vm_with_userdata.py +++ b/test/integration/smoke/test_deploy_vm_with_userdata.py @@ -111,6 +111,7 @@ class TestDeployVmWithUserData(cloudstackTestCase): vm = vms[0] self.assert_(vm.id == str(deployVmResponse.id), "Vm deployed is different from the test") self.assert_(vm.state == "Running", "VM is not in Running state") + self.cleanup.append(deployVmResponse) @attr(tags=["simulator", "devcloud", "basic", "advanced"]) def test_deployvm_userdata(self): @@ -134,6 +135,7 @@ class TestDeployVmWithUserData(cloudstackTestCase): vm = vms[0] self.assert_(vm.id == str(deployVmResponse.id), "Vm deployed is different from the test") self.assert_(vm.state == "Running", "VM is not in Running state") + self.cleanup.append(deployVmResponse) @classmethod def tearDownClass(cls): From 1fe50a8d6778e37fd0784919538fdc7afccfb4c8 Mon Sep 17 00:00:00 2001 From: Talluri Date: Wed, 8 May 2013 04:43:31 +0530 Subject: [PATCH 38/71] CLOUDSTACK-2363: fixing the scripts to conform with lib changes Signed-off-by: Prasanna Santhanam --- .../component/test_project_configs.py | 104 +++++++++--------- .../component/test_project_limits.py | 10 +- test/integration/component/test_projects.py | 50 ++++----- test/integration/smoke/test_network.py | 12 +- test/integration/smoke/test_templates.py | 8 +- 5 files changed, 92 insertions(+), 92 deletions(-) diff --git a/test/integration/component/test_project_configs.py b/test/integration/component/test_project_configs.py index fa2ee0adb2b..33409ac56eb 100644 --- a/test/integration/component/test_project_configs.py +++ b/test/integration/component/test_project_configs.py @@ -242,8 +242,8 @@ class TestUserProjectCreation(cloudstackTestCase): project = Project.create( self.apiclient, self.services["project"], - account=self.user.account.name, - domainid=self.user.account.domainid + account=self.user.name, + domainid=self.user.domainid ) # Cleanup created project at end of test self.cleanup.append(project) @@ -409,11 +409,11 @@ class TestProjectCreationNegative(cloudstackTestCase): project = Project.create( self.apiclient, self.services["project"], - account=self.user.account.name, - domainid=self.user.account.domainid + account=self.user.name, + domainid=self.user.domainid ) self.debug("Project creation with domain user: %s failed" % - self.user.account.name) + self.user.name) return @@ -531,21 +531,21 @@ class TestProjectInviteRequired(cloudstackTestCase): "Check project name from list response" ) self.debug("Adding %s user to project: %s" % ( - self.user.account.name, + self.user.name, project.name )) # Add user to the project project.addAccount( self.apiclient, - self.user.account.name, - self.user.account.email + self.user.name, + self.user.email ) # listProjectAccount to verify the user is added to project or not accounts_reponse = Project.listAccounts( self.apiclient, projectid=project.id, - account=self.user.account.name, + account=self.user.name, ) self.debug(accounts_reponse) self.assertEqual( @@ -684,22 +684,22 @@ class TestProjectInviteRequiredTrue(cloudstackTestCase): "Check project name from list response" ) self.debug("Adding %s user to project: %s" % ( - self.user.account.name, + self.user.name, project.name )) # Add user to the project project.addAccount( self.apiclient, - self.user.account.name, - self.user.account.email + self.user.name, + self.user.email ) # listProjectAccount to verify the user is added to project or not accounts_reponse = ProjectInvitation.list( self.apiclient, state='Pending', - account=self.user.account.name, - domainid=self.user.account.domainid + account=self.user.name, + domainid=self.user.domainid ) self.assertEqual( isinstance(accounts_reponse, list), @@ -853,22 +853,22 @@ class TestProjectInviteTimeout(cloudstackTestCase): "Check project name from list response" ) self.debug("Adding %s user to project: %s" % ( - self.user.account.name, + self.user.name, project.name )) # Add user to the project project.addAccount( self.apiclient, - self.user.account.name, - self.user.account.email + self.user.name, + self.user.email ) # listProjectAccount to verify the user is added to project or not accounts_reponse = ProjectInvitation.list( self.apiclient, state='Pending', - account=self.user.account.name, - domainid=self.user.account.domainid + account=self.user.name, + domainid=self.user.domainid ) self.assertEqual( isinstance(accounts_reponse, list), @@ -894,18 +894,18 @@ class TestProjectInviteTimeout(cloudstackTestCase): self.apiclient, projectid=project.id, accept=True, - account=self.user.account.name + account=self.user.name ) self.debug( "Accepting project invitation for project: %s user: %s" % ( project.name, - self.user.account.name + self.user.name )) # listProjectAccount to verify the user is added to project or not accounts_reponse = Project.listAccounts( self.apiclient, projectid=project.id, - account=self.user.account.name, + account=self.user.name, ) self.assertEqual( @@ -979,22 +979,22 @@ class TestProjectInviteTimeout(cloudstackTestCase): "Check project name from list response" ) self.debug("Adding %s user to project: %s" % ( - self.user.account.name, + self.user.name, project.name )) # Add user to the project project.addAccount( self.apiclient, - self.user.account.name, - self.user.account.email + self.user.name, + self.user.email ) # listProjectAccount to verify the user is added to project or not accounts_reponse = ProjectInvitation.list( self.apiclient, state='Pending', - account=self.user.account.name, - domainid=self.user.account.domainid + account=self.user.name, + domainid=self.user.domainid ) self.assertEqual( isinstance(accounts_reponse, list), @@ -1025,18 +1025,18 @@ class TestProjectInviteTimeout(cloudstackTestCase): self.apiclient, projectid=project.id, accept=True, - account=self.user.account.name + account=self.user.name ) self.debug( "Accepting invitation after expiry project: %s user: %s" % ( project.name, - self.user.account.name + self.user.name )) # listProjectAccount to verify the user is added to project or not accounts_reponse = ProjectInvitation.list( self.apiclient, - account=self.user.account.name, - domainid=self.user.account.domainid + account=self.user.name, + domainid=self.user.domainid ) self.assertEqual( @@ -1110,22 +1110,22 @@ class TestProjectInviteTimeout(cloudstackTestCase): "Check project name from list response" ) self.debug("Adding %s user to project: %s" % ( - self.user.account.name, + self.user.name, project.name )) # Add user to the project project.addAccount( self.apiclient, - self.user.account.name, - self.user.account.email + self.user.name, + self.user.email ) # listProjectAccount to verify the user is added to project or not accounts_reponse = ProjectInvitation.list( self.apiclient, state='Pending', - account=self.user.account.name, - domainid=self.user.account.domainid + account=self.user.name, + domainid=self.user.domainid ) self.assertEqual( isinstance(accounts_reponse, list), @@ -1151,22 +1151,22 @@ class TestProjectInviteTimeout(cloudstackTestCase): time.sleep(int(self.config.value) * 2) self.debug("Adding %s user again to project: %s" % ( - self.user.account.name, + self.user.name, project.name )) # Add user to the project project.addAccount( self.apiclient, - self.user.account.name, - self.user.account.email + self.user.name, + self.user.email ) # listProjectAccount to verify the user is added to project or not accounts_reponse = ProjectInvitation.list( self.apiclient, state='Pending', - account=self.user.account.name, - domainid=self.user.account.domainid + account=self.user.name, + domainid=self.user.domainid ) self.assertEqual( isinstance(accounts_reponse, list), @@ -1239,22 +1239,22 @@ class TestProjectInviteTimeout(cloudstackTestCase): "Check project name from list response" ) self.debug("Adding %s user to project: %s" % ( - self.user.account.name, + self.user.name, project.name )) # Add user to the project project.addAccount( self.apiclient, - self.user.account.name, - self.user.account.email + self.user.name, + self.user.email ) # listProjectAccount to verify the user is added to project or not accounts_reponse = ProjectInvitation.list( self.apiclient, state='Pending', - account=self.user.account.name, - domainid=self.user.account.domainid + account=self.user.name, + domainid=self.user.domainid ) self.assertEqual( isinstance(accounts_reponse, list), @@ -1279,18 +1279,18 @@ class TestProjectInviteTimeout(cloudstackTestCase): self.apiclient, projectid=project.id, accept=False, - account=self.user.account.name + account=self.user.name ) self.debug( "Declining invitation for project: %s user: %s" % ( project.name, - self.user.account.name + self.user.name )) # listProjectAccount to verify the user is added to project or not accounts_reponse = Project.listAccounts( self.apiclient, projectid=project.id, - account=self.user.account.name, + account=self.user.name, ) self.assertEqual( accounts_reponse, @@ -1367,19 +1367,19 @@ class TestProjectInviteTimeout(cloudstackTestCase): "Check project name from list response" ) self.debug("Adding user with email: %s to project: %s" % ( - self.user.account.email, + self.user.email, project.name )) # Add user to the project project.addAccount( self.apiclient, - email=self.user.account.user[0].email + email=self.user.user[0].email ) # Fetch the latest mail sent to user mail_content = fetch_latest_mail( self.services["mail_account"], - from_mail=self.user.account.user[0].email + from_mail=self.user.user[0].email ) return diff --git a/test/integration/component/test_project_limits.py b/test/integration/component/test_project_limits.py index 4a8b9d48227..c5d2d6deac3 100644 --- a/test/integration/component/test_project_limits.py +++ b/test/integration/component/test_project_limits.py @@ -429,14 +429,14 @@ class TestProjectLimits(cloudstackTestCase): ) self.debug("Adding %s user to project: %s" % ( - self.user.account.name, + self.user.name, project.name )) # Add user to the project project.addAccount( self.apiclient, - self.user.account.name, + self.user.name, ) # Get the resource limits for domain @@ -459,14 +459,14 @@ class TestProjectLimits(cloudstackTestCase): #with self.assertRaises(Exception): self.debug( "Attempting to update resource limit by user: %s" % ( - self.user.account.name + self.user.name )) # Update project resource limits to 3 update_resource_limit( self.apiclient, resource.resourcetype, - account=self.user.account.name, - domainid=self.user.account.domainid, + account=self.user.name, + domainid=self.user.domainid, max=3, projectid=project.id ) diff --git a/test/integration/component/test_projects.py b/test/integration/component/test_projects.py index 9fa60750afe..ccfc8ef4086 100644 --- a/test/integration/component/test_projects.py +++ b/test/integration/component/test_projects.py @@ -248,15 +248,15 @@ class TestMultipleProjectCreation(cloudstackTestCase): # Add user to the project project_1.addAccount( self.apiclient, - self.user.account.name, - self.user.account.email + self.user.name, + self.user.email ) # listProjectAccount to verify the user is added to project or not accounts_reponse = Project.listAccounts( self.apiclient, projectid=project_1.id, - account=self.user.account.name, + account=self.user.name, ) self.debug(accounts_reponse) self.assertEqual( @@ -280,15 +280,15 @@ class TestMultipleProjectCreation(cloudstackTestCase): # Add user to the project project_2.addAccount( self.apiclient, - self.user.account.name, - self.user.account.email + self.user.name, + self.user.email ) # listProjectAccount to verify the user is added to project or not accounts_reponse = Project.listAccounts( self.apiclient, projectid=project_2.id, - account=self.user.account.name, + account=self.user.name, ) self.debug(accounts_reponse) self.assertEqual( @@ -432,15 +432,15 @@ class TestCrossDomainAccountAdd(cloudstackTestCase): ) self.debug("Adding user: %s from domain: %s to project: %s" % ( - self.user.account.name, - self.user.account.domainid, + self.user.name, + self.user.domainid, project.id )) with self.assertRaises(Exception): # Add user to the project from different domain project.addAccount( self.apiclient, - self.user.account.name + self.user.name ) self.debug("User add to project failed!") return @@ -938,7 +938,7 @@ class TestProjectOwners(cloudstackTestCase): ) self.cleanup.append(self.user) self.debug("Created account with ID: %s" % - self.user.account.name) + self.user.name) list_projects_reponse = Project.list( self.apiclient, @@ -1033,20 +1033,20 @@ class TestProjectOwners(cloudstackTestCase): ) self.debug("Adding %s user to project: %s" % ( - self.user.account.name, + self.user.name, project.name )) # Add user to the project project.addAccount( self.apiclient, - self.user.account.name, + self.user.name, ) # listProjectAccount to verify the user is added to project or not accounts_reponse = Project.listAccounts( self.apiclient, projectid=project.id, - account=self.user.account.name, + account=self.user.name, ) self.assertEqual( isinstance(accounts_reponse, list), @@ -1068,19 +1068,19 @@ class TestProjectOwners(cloudstackTestCase): ) self.debug("Updating project with new Admin: %s" % - self.user.account.name) + self.user.name) # Update the project with new admin project.update( self.apiclient, - account=self.user.account.name + account=self.user.name ) # listProjectAccount to verify the user is new admin of the project accounts_reponse = Project.listAccounts( self.apiclient, projectid=project.id, - account=self.user.account.name, + account=self.user.name, ) self.debug(accounts_reponse) self.assertEqual( @@ -1248,20 +1248,20 @@ class TestProjectResources(cloudstackTestCase): "Check project name from list response" ) self.debug("Adding %s user to project: %s" % ( - self.user.account.name, + self.user.name, project.name )) # Add user to the project project.addAccount( self.apiclient, - self.user.account.name, + self.user.name, ) # listProjectAccount to verify the user is added to project or not accounts_reponse = Project.listAccounts( self.apiclient, projectid=project.id, - account=self.user.account.name, + account=self.user.name, ) self.assertEqual( isinstance(accounts_reponse, list), @@ -1370,20 +1370,20 @@ class TestProjectResources(cloudstackTestCase): ) self.cleanup.append(self.user) self.debug("Adding %s user to project: %s" % ( - self.user.account.name, + self.user.name, project.name )) # Add user to the project project.addAccount( self.apiclient, - self.user.account.name + self.user.name ) # listProjectAccount to verify the user is added to project or not accounts_reponse = Project.listAccounts( self.apiclient, projectid=project.id, - account=self.user.account.name, + account=self.user.name, ) self.assertEqual( isinstance(accounts_reponse, list), @@ -1543,20 +1543,20 @@ class TestProjectSuspendActivate(cloudstackTestCase): # account deletion. self.debug("Adding %s user to project: %s" % ( - self.user.account.name, + self.user.name, self.project.name )) # Add user to the project self.project.addAccount( self.apiclient, - self.user.account.name, + self.user.name, ) # listProjectAccount to verify the user is added to project or not accounts_reponse = Project.listAccounts( self.apiclient, projectid=self.project.id, - account=self.user.account.name, + account=self.user.name, ) self.assertEqual( isinstance(accounts_reponse, list), diff --git a/test/integration/smoke/test_network.py b/test/integration/smoke/test_network.py index 322e8c25c8e..4a7bb44da2c 100644 --- a/test/integration/smoke/test_network.py +++ b/test/integration/smoke/test_network.py @@ -151,8 +151,8 @@ class TestPublicIP(cloudstackTestCase): cls.user_network = Network.create( cls.api_client, cls.services["network"], - cls.user.account.name, - cls.user.account.domainid + cls.user.name, + cls.user.domainid ) # Create Source NAT IP addresses @@ -164,9 +164,9 @@ class TestPublicIP(cloudstackTestCase): ) user_src_nat_ip = PublicIPAddress.create( cls.api_client, - cls.user.account.name, + cls.user.name, cls.zone.id, - cls.user.account.domainid + cls.user.domainid ) cls._cleanup = [ cls.account_network, @@ -248,9 +248,9 @@ class TestPublicIP(cloudstackTestCase): ip_address = PublicIPAddress.create( self.apiclient, - self.user.account.name, + self.user.name, self.zone.id, - self.user.account.domainid + self.user.domainid ) #listPublicIpAddresses should return newly created public IP diff --git a/test/integration/smoke/test_templates.py b/test/integration/smoke/test_templates.py index b2ad4ca5634..382f56f8980 100644 --- a/test/integration/smoke/test_templates.py +++ b/test/integration/smoke/test_templates.py @@ -752,8 +752,8 @@ class TestTemplates(cloudstackTestCase): list_template_response = list_templates( self.apiclient, templatefilter='featured', - account=self.user.account.name, - domainid=self.user.account.domainid + account=self.user.name, + domainid=self.user.domainid ) self.assertEqual( isinstance(list_template_response, list), @@ -784,8 +784,8 @@ class TestTemplates(cloudstackTestCase): list_template_response = list_templates( self.apiclient, templatefilter='featured', - account=self.user.account.name, - domainid=self.user.account.domainid + account=self.user.name, + domainid=self.user.domainid ) self.assertEqual( isinstance(list_template_response, list), From b8358e109e737c454a351942c0f3d66f674febd7 Mon Sep 17 00:00:00 2001 From: Srikanteswararao Talluri Date: Wed, 8 May 2013 12:23:15 +0530 Subject: [PATCH 39/71] CLOUDSTACK-2377: change memory size to 128 mb for the tiny service offering in the integration tests Signed-off-by: Prasanna Santhanam --- test/integration/component/test_accounts.py | 2 +- test/integration/component/test_allocation_states.py | 2 +- test/integration/component/test_blocker_bugs.py | 2 +- test/integration/component/test_egress_rules.py | 2 +- test/integration/component/test_eip_elb.py | 2 +- test/integration/component/test_network_offering.py | 2 +- test/integration/component/test_project_configs.py | 2 +- test/integration/component/test_project_limits.py | 2 +- test/integration/component/test_project_resources.py | 2 +- test/integration/component/test_project_usage.py | 2 +- test/integration/component/test_projects.py | 2 +- test/integration/component/test_resource_limits.py | 2 +- test/integration/component/test_routers.py | 2 +- test/integration/component/test_security_groups.py | 2 +- test/integration/component/test_templates.py | 2 +- test/integration/component/test_usage.py | 2 +- test/integration/component/test_volumes.py | 2 +- test/integration/smoke/test_affinity_groups.py | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/test/integration/component/test_accounts.py b/test/integration/component/test_accounts.py index fb38e627582..9cbefe55fdb 100644 --- a/test/integration/component/test_accounts.py +++ b/test/integration/component/test_accounts.py @@ -60,7 +60,7 @@ class Services: "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, + "memory": 128, # In MBs }, "virtual_machine": { diff --git a/test/integration/component/test_allocation_states.py b/test/integration/component/test_allocation_states.py index fe4c35f3b9f..5ce0b21124b 100644 --- a/test/integration/component/test_allocation_states.py +++ b/test/integration/component/test_allocation_states.py @@ -49,7 +49,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "disk_offering": { "displaytext": "Small", diff --git a/test/integration/component/test_blocker_bugs.py b/test/integration/component/test_blocker_bugs.py index a6ea25a846a..d099bf1a448 100644 --- a/test/integration/component/test_blocker_bugs.py +++ b/test/integration/component/test_blocker_bugs.py @@ -51,7 +51,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "disk_offering": { "displaytext": "Small", diff --git a/test/integration/component/test_egress_rules.py b/test/integration/component/test_egress_rules.py index 4af6eee94f4..872ca2c7b5d 100644 --- a/test/integration/component/test_egress_rules.py +++ b/test/integration/component/test_egress_rules.py @@ -69,7 +69,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "security_group": { "name": 'SSH', diff --git a/test/integration/component/test_eip_elb.py b/test/integration/component/test_eip_elb.py index cb41859acd3..b01371b7643 100644 --- a/test/integration/component/test_eip_elb.py +++ b/test/integration/component/test_eip_elb.py @@ -49,7 +49,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "lbrule": { "name": "SSH", diff --git a/test/integration/component/test_network_offering.py b/test/integration/component/test_network_offering.py index 00566a0d400..e33c3765642 100644 --- a/test/integration/component/test_network_offering.py +++ b/test/integration/component/test_network_offering.py @@ -49,7 +49,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "network_offering": { "name": 'Network offering-VR services', diff --git a/test/integration/component/test_project_configs.py b/test/integration/component/test_project_configs.py index 33409ac56eb..1eef123b2ee 100644 --- a/test/integration/component/test_project_configs.py +++ b/test/integration/component/test_project_configs.py @@ -70,7 +70,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "virtual_machine": { "displayname": "Test VM", diff --git a/test/integration/component/test_project_limits.py b/test/integration/component/test_project_limits.py index c5d2d6deac3..17ddfc67da5 100644 --- a/test/integration/component/test_project_limits.py +++ b/test/integration/component/test_project_limits.py @@ -63,7 +63,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "disk_offering": { "displaytext": "Tiny Disk Offering", diff --git a/test/integration/component/test_project_resources.py b/test/integration/component/test_project_resources.py index e79254ce6ac..84141889f3f 100644 --- a/test/integration/component/test_project_resources.py +++ b/test/integration/component/test_project_resources.py @@ -64,7 +64,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "disk_offering": { "displaytext": "Tiny Disk Offering", diff --git a/test/integration/component/test_project_usage.py b/test/integration/component/test_project_usage.py index 44ef2f9a0a9..ab789e1c13d 100644 --- a/test/integration/component/test_project_usage.py +++ b/test/integration/component/test_project_usage.py @@ -52,7 +52,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "disk_offering": { "displaytext": "Small", diff --git a/test/integration/component/test_projects.py b/test/integration/component/test_projects.py index ccfc8ef4086..f013e99a0dd 100644 --- a/test/integration/component/test_projects.py +++ b/test/integration/component/test_projects.py @@ -78,7 +78,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "virtual_machine": { "displayname": "Test VM", diff --git a/test/integration/component/test_resource_limits.py b/test/integration/component/test_resource_limits.py index 418080ab052..1d876b6195f 100644 --- a/test/integration/component/test_resource_limits.py +++ b/test/integration/component/test_resource_limits.py @@ -51,7 +51,7 @@ class Services: "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, + "memory": 128, # In MBs }, "disk_offering": { diff --git a/test/integration/component/test_routers.py b/test/integration/component/test_routers.py index 96eb9aae403..bc33d754260 100644 --- a/test/integration/component/test_routers.py +++ b/test/integration/component/test_routers.py @@ -41,7 +41,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "virtual_machine": { diff --git a/test/integration/component/test_security_groups.py b/test/integration/component/test_security_groups.py index fe2561aa084..54b5c67fa4d 100644 --- a/test/integration/component/test_security_groups.py +++ b/test/integration/component/test_security_groups.py @@ -74,7 +74,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "security_group": { "name": 'SSH', diff --git a/test/integration/component/test_templates.py b/test/integration/component/test_templates.py index 3867fb44d19..1a60123b820 100644 --- a/test/integration/component/test_templates.py +++ b/test/integration/component/test_templates.py @@ -51,7 +51,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "disk_offering": { "displaytext": "Small", diff --git a/test/integration/component/test_usage.py b/test/integration/component/test_usage.py index dbd0be97b72..a3779e4dc2f 100644 --- a/test/integration/component/test_usage.py +++ b/test/integration/component/test_usage.py @@ -48,7 +48,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "disk_offering": { "displaytext": "Small", diff --git a/test/integration/component/test_volumes.py b/test/integration/component/test_volumes.py index f7eb9f92600..34a067930de 100644 --- a/test/integration/component/test_volumes.py +++ b/test/integration/component/test_volumes.py @@ -52,7 +52,7 @@ class Services: "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, # In MBs + "memory": 128, # In MBs }, "disk_offering": { "displaytext": "Small", diff --git a/test/integration/smoke/test_affinity_groups.py b/test/integration/smoke/test_affinity_groups.py index 6ccd478bf2d..e0e1a17273b 100644 --- a/test/integration/smoke/test_affinity_groups.py +++ b/test/integration/smoke/test_affinity_groups.py @@ -48,7 +48,7 @@ class Services: "cpunumber": 1, "cpuspeed": 100, # in MHz - "memory": 64, + "memory": 128, # In MBs }, "ostype": 'CentOS 5.3 (64-bit)', From 53e496517ed51bab2c81084a02f49b0408b19a37 Mon Sep 17 00:00:00 2001 From: sanjeevneelarapu Date: Mon, 6 May 2013 20:38:54 +0530 Subject: [PATCH 40/71] CLOUDSTACK-702: Tests for Multiple IP Ranges-R4 Add ip range overlapped with two ip ranges in the exiting cidr Signed-off-by: sanjeevneelarapu Signed-off-by: Prasanna Santhanam --- .../component/test_multiple_ip_ranges.py | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/test/integration/component/test_multiple_ip_ranges.py b/test/integration/component/test_multiple_ip_ranges.py index 29942bd3af2..7e9eeb1028d 100644 --- a/test/integration/component/test_multiple_ip_ranges.py +++ b/test/integration/component/test_multiple_ip_ranges.py @@ -368,3 +368,61 @@ class TestMultipleIpRanges(cloudstackTestCase): #Test will reach here there is a bug in overlap ip range checking self.fail("CS should not accept overlapped ip ranges in guest traffic, but it allowed") return + + @attr(tags=["advanced_sg", "sg"]) + def test_06_add_ip_range_overlapped_with_two_ranges(self): + """Test adding overlapped ip range in existing cidr + + 1.Add ip range in new cidr e.g:10.147.40.2-10.147.40.10 + 2.Add another ip range in the same cidr e.g:10.147.40.20-10.147.40.30 + 2.Add ip range overlapped with both the ip ranges e.g.10.147.40.10-20 + """ + #call increment_cidr function to get exiting cidr from the setup and increment it + ip2 = self.increment_cidr() + test_nw = ip2.network + ip = IPAddress(test_nw) + #Add IP range in the new CIDR + test_gateway = ip.__add__(1) + test_startIp = ip.__add__(2) + test_endIp = ip.__add__(10) + test_startIp2 = ip.__add__(20) + test_endIp2 = ip.__add__(30) + test_startIp3 = ip.__add__(10) + test_endIp3 = ip.__add__(20) + #Populating services with new IP range + self.services["vlan_ip_range"]["startip"] = test_startIp + self.services["vlan_ip_range"]["endip"] = test_endIp + self.services["vlan_ip_range"]["gateway"] = test_gateway + self.services["vlan_ip_range"]["netmask"] = self.netmask + self.services["vlan_ip_range"]["zoneid"] = self.zone.id + self.services["vlan_ip_range"]["podid"] = self.pod.id + #create new vlan ip range + new_vlan = PublicIpRange.create(self.apiclient, self.services["vlan_ip_range"]) + self.debug("Created new vlan range with startip:%s and endip:%s" %(test_startIp,test_endIp)) + self.cleanup.append(new_vlan) + new_vlan_res = new_vlan.list(self.apiclient,id=new_vlan.vlan.id) + #Compare list output with configured values + self.verify_vlan_range(new_vlan_res,self.services["vlan_ip_range"]) + #Add 2nd IP range in the same CIDR + self.services["vlan_ip_range"]["startip"] = test_startIp2 + self.services["vlan_ip_range"]["endip"] = test_endIp2 + new_vlan = PublicIpRange.create(self.apiclient, self.services["vlan_ip_range"]) + self.debug("Created new vlan range with startip:%s and endip:%s" %(test_startIp2,test_endIp2)) + self.cleanup.append(new_vlan) + new_vlan_res = new_vlan.list(self.apiclient,id=new_vlan.vlan.id) + #Compare list output with configured values + self.verify_vlan_range(new_vlan_res,self.services["vlan_ip_range"]) + #Add ip range which will overlap with two existing ip ranges in the same CIDR + #Populating services with new IP range + self.services["vlan_ip_range"]["startip"] = test_startIp3 + self.services["vlan_ip_range"]["endip"] = test_endIp3 + #Try to create ip range overlapped with exiting ip range + try: + PublicIpRange.create(self.apiclient, self.services["vlan_ip_range"]) + except cloudstackAPIException as cs: + self.debug(cs.errorMsg) + self.assertTrue(cs.errorMsg.find("already has IPs that overlap with the new range")>0, msg="Fail:CS allowed adding overlapped ip ranges in guest cidr") + return + #Test will reach here there is a bug in overlap ip range checking + self.fail("CS should not accept overlapped ip ranges in guest traffic, but it allowed") + return From 76e8afa24fdbdf7d3132c5c5b90320f19bf7ddcb Mon Sep 17 00:00:00 2001 From: Pranav Saxena Date: Wed, 8 May 2013 17:05:36 +0530 Subject: [PATCH 41/71] CLOUDSTACK-2171:Unable to Create a VM In the VMware Setup with the latest Master --- ui/scripts/system.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index dc09ea86926..2746e0d01b2 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -1018,12 +1018,7 @@ dataType: "json", success: function(json) { var jobId = json.updatephysicalnetworkresponse.jobid; - - var trafficType = getTrafficType(selectedPhysicalNetworkObj, 'Guest'); - - updateTrafficLabels(trafficType, args.data, function() { args.response.success({ _custom: { jobId: jobId }}); - }); }, error:function(json){ From 305f3cb8a503df84875fe7e066ca60fe186da22e Mon Sep 17 00:00:00 2001 From: Pranav Saxena Date: Wed, 8 May 2013 17:07:46 +0530 Subject: [PATCH 42/71] CLOUDSTACK-2387:Addition/Deletion of a VLAN Range from UI calls updateTrafficType API which makes all networklabels as undefined which finally results in failure to deploy VMs --- ui/scripts/system.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 2746e0d01b2..34ba64c917d 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -1066,10 +1066,7 @@ dataType: "json", success: function(json) { var jobId = json.updatephysicalnetworkresponse.jobid; - var trafficType = getTrafficType(selectedPhysicalNetworkObj, 'Guest'); - updateTrafficLabels(trafficType, args.data, function() { args.response.success({ _custom: { jobId: jobId }}); - }); }, error:function(json){ From 44f3f5eca529b5f9bfe08a984fed8ce23160b9c5 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Wed, 8 May 2013 17:52:02 +0530 Subject: [PATCH 43/71] CLOUDSTACK-2145 : Failed to create guest nexus port profile while deploying the First VM on Nexus VMWARE Cluster Additional stuff needs to be configured in guest port profile when Vnmc is present to provide firewall services. The xml command used to configure port profile had issues with special characters in the input value for 'org' parameter. --- utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java index fdab390557d..d86b7100658 100644 --- a/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java +++ b/utils/src/com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java @@ -546,10 +546,15 @@ public class VsmCommand { vmware.appendChild(portgroup); portProf.appendChild(vmware); - // org root/%vdc% + // org %vdc% // vservice node profile + Element vdcValue = doc.createElement(s_paramvalue); + vdcValue.setAttribute("isKey", "true"); + vdcValue.setTextContent(vdc); + Element org = doc.createElement("org"); - org.appendChild(doc.createElement(vdc)); + org.appendChild(doc.createElement("orgname")) + .appendChild(vdcValue); portProf.appendChild(org); String asaNodeName = "ASA_" + vlanid; From 99d0936314571e645f62e40bf4d227232be89632 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Wed, 8 May 2013 17:44:46 +0100 Subject: [PATCH 44/71] CLOUDSTACK-2318: update volumes.path to fix stop/start vm error after upgrade from 2.2.14 to 3.0.0 Signed-off-by: Chip Childers --- setup/db/db/schema-2214to30.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/db/db/schema-2214to30.sql b/setup/db/db/schema-2214to30.sql index 60eceea447d..e288b0fd4f9 100755 --- a/setup/db/db/schema-2214to30.sql +++ b/setup/db/db/schema-2214to30.sql @@ -664,6 +664,7 @@ ALTER TABLE `cloud`.`dc_storage_network_ip_range` ADD COLUMN `gateway` varchar(1 ALTER TABLE `cloud`.`volumes` ADD COLUMN `last_pool_id` bigint unsigned; UPDATE `cloud`.`volumes` SET `last_pool_id` = `pool_id`; +UPDATE `cloud`.`volumes` SET `path` = SUBSTRING_INDEX(`path`, '/', -1); ALTER TABLE `cloud`.`user_ip_address` ADD COLUMN `is_system` int(1) unsigned NOT NULL default '0'; ALTER TABLE `cloud`.`volumes` ADD COLUMN `update_count` bigint unsigned NOT NULL DEFAULT 0; From 738d35a61d12aa4ff11114aef89f546a077e8629 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 8 May 2013 11:40:37 -0700 Subject: [PATCH 45/71] CLOUDSTACK-1907: Debian Squeeze 6.0 (64-bit) is not experimental any more --- .../xen/discoverer/XcpServerDiscoverer.java | 7 +- .../hypervisor/xen/resource/CitrixHelper.java | 87 +++++++++++++++++++ .../xen/resource/XcpServerResource.java | 11 ++- 3 files changed, 100 insertions(+), 5 deletions(-) diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index 89bc1cf5708..562a7feb96f 100755 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -427,8 +427,11 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L prodVersion = prodVersion.trim(); } - if(prodBrand.equals("XCP") && (prodVersion.equals("1.0.0") || prodVersion.equals("1.1.0") || prodVersion.equals("5.6.100") || prodVersion.startsWith("1.4") || prodVersion.startsWith("1.6"))) - return new XcpServerResource(); + if(prodBrand.equals("XCP") && (prodVersion.equals("1.0.0") || prodVersion.equals("1.1.0") || prodVersion.equals("5.6.100") || prodVersion.startsWith("1.4"))) { + return new XcpServerResource("1.1"); + } else if (prodBrand.equals("XCP") && prodVersion.startsWith("1.6")) { + return new XcpServerResource("1.6"); + } if(prodBrand.equals("XenServer") && prodVersion.equals("5.6.0")) return new XenServer56Resource(); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixHelper.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixHelper.java index 5bcec13acb5..34b8f2981e2 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixHelper.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixHelper.java @@ -28,6 +28,7 @@ import org.apache.log4j.Logger; public class CitrixHelper { private static final Logger s_logger = Logger.getLogger(CitrixHelper.class); private static final HashMap _xcp100GuestOsMap = new HashMap(70); + private static final HashMap _xcp160GuestOsMap = new HashMap(70); private static final HashMap _xenServerGuestOsMap = new HashMap(70); private static final HashMap _xenServer56FP1GuestOsMap = new HashMap(70); private static final HashMap _xenServer56FP2GuestOsMap = new HashMap(70); @@ -114,6 +115,83 @@ public class CitrixHelper { _xcp100GuestOsMap.put("Other PV (64-bit)", "CentOS 5 (64-bit)"); } + static { + _xcp160GuestOsMap.put("CentOS 4.5 (32-bit)", "CentOS 4.5 (32-bit)"); + _xcp160GuestOsMap.put("CentOS 4.6 (32-bit)", "CentOS 4.6 (32-bit)"); + _xcp160GuestOsMap.put("CentOS 4.7 (32-bit)", "CentOS 4.7 (32-bit)"); + _xcp160GuestOsMap.put("CentOS 4.8 (32-bit)", "CentOS 4.8 (32-bit)"); + _xcp160GuestOsMap.put("CentOS 5.0 (32-bit)", "CentOS 5 (32-bit)"); + _xcp160GuestOsMap.put("CentOS 5.0 (64-bit)", "CentOS 5 (64-bit)"); + _xcp160GuestOsMap.put("CentOS 5.1 (32-bit)", "CentOS 5 (32-bit)"); + _xcp160GuestOsMap.put("CentOS 5.1 (64-bit)", "CentOS 5 (64-bit)"); + _xcp160GuestOsMap.put("CentOS 5.2 (32-bit)", "CentOS 5 (32-bit)"); + _xcp160GuestOsMap.put("CentOS 5.2 (64-bit)", "CentOS 5 (64-bit)"); + _xcp160GuestOsMap.put("CentOS 5.3 (32-bit)", "CentOS 5 (32-bit)"); + _xcp160GuestOsMap.put("CentOS 5.3 (64-bit)", "CentOS 5 (64-bit)"); + _xcp160GuestOsMap.put("CentOS 5.4 (32-bit)", "CentOS 5 (32-bit)"); + _xcp160GuestOsMap.put("CentOS 5.4 (64-bit)", "CentOS 5 (64-bit)"); + _xcp160GuestOsMap.put("CentOS 5.5 (32-bit)", "CentOS 5 (32-bit)"); + _xcp160GuestOsMap.put("CentOS 5.5 (64-bit)", "CentOS 5 (64-bit)"); + _xcp160GuestOsMap.put("Debian GNU/Linux 5.0 (32-bit)", "Debian Lenny 5.0 (32-bit)"); + _xcp160GuestOsMap.put("Debian GNU/Linux 6(32-bit)", "Debian Squeeze 6.0 (32-bit)"); + _xcp160GuestOsMap.put("Debian GNU/Linux 6(64-bit)", "Debian Squeeze 6.0 (64-bit)"); + _xcp160GuestOsMap.put("Oracle Enterprise Linux 5.0 (32-bit)", "Oracle Enterprise Linux 5 (32-bit)"); + _xcp160GuestOsMap.put("Oracle Enterprise Linux 5.0 (64-bit)", "Oracle Enterprise Linux 5 (64-bit)"); + _xcp160GuestOsMap.put("Oracle Enterprise Linux 5.1 (32-bit)", "Oracle Enterprise Linux 5 (32-bit)"); + _xcp160GuestOsMap.put("Oracle Enterprise Linux 5.1 (64-bit)", "Oracle Enterprise Linux 5 (64-bit)"); + _xcp160GuestOsMap.put("Oracle Enterprise Linux 5.2 (32-bit)", "Oracle Enterprise Linux 5 (32-bit)"); + _xcp160GuestOsMap.put("Oracle Enterprise Linux 5.2 (64-bit)", "Oracle Enterprise Linux 5 (64-bit)"); + _xcp160GuestOsMap.put("Oracle Enterprise Linux 5.3 (32-bit)", "Oracle Enterprise Linux 5 (32-bit)"); + _xcp160GuestOsMap.put("Oracle Enterprise Linux 5.3 (64-bit)", "Oracle Enterprise Linux 5 (64-bit)"); + _xcp160GuestOsMap.put("Oracle Enterprise Linux 5.4 (32-bit)", "Oracle Enterprise Linux 5 (32-bit)"); + _xcp160GuestOsMap.put("Oracle Enterprise Linux 5.4 (64-bit)", "Oracle Enterprise Linux 5 (64-bit)"); + _xcp160GuestOsMap.put("Oracle Enterprise Linux 5.5 (32-bit)", "Oracle Enterprise Linux 5 (32-bit)"); + _xcp160GuestOsMap.put("Oracle Enterprise Linux 5.5 (64-bit)", "Oracle Enterprise Linux 5 (64-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 4.5 (32-bit)", "Red Hat Enterprise Linux 4.5 (32-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 4.6 (32-bit)", "Red Hat Enterprise Linux 4.6 (32-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 4.7 (32-bit)", "Red Hat Enterprise Linux 4.7 (32-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 4.8 (32-bit)", "Red Hat Enterprise Linux 4.8 (32-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 5.0 (32-bit)", "Red Hat Enterprise Linux 5 (32-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 5.0 (64-bit)", "Red Hat Enterprise Linux 5 (64-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 5.1 (32-bit)", "Red Hat Enterprise Linux 5 (32-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 5.1 (64-bit)", "Red Hat Enterprise Linux 5 (64-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 5.2 (32-bit)", "Red Hat Enterprise Linux 5 (32-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 5.2 (64-bit)", "Red Hat Enterprise Linux 5 (64-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 5.3 (32-bit)", "Red Hat Enterprise Linux 5 (32-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 5.3 (64-bit)", "Red Hat Enterprise Linux 5 (64-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 5.4 (32-bit)", "Red Hat Enterprise Linux 5 (32-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 5.4 (64-bit)", "Red Hat Enterprise Linux 5 (64-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 5.5 (32-bit)", "Red Hat Enterprise Linux 5 (32-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 5.5 (64-bit)", "Red Hat Enterprise Linux 5 (64-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 6.0 (32-bit)", "Red Hat Enterprise Linux 6 (32-bit)"); + _xcp160GuestOsMap.put("Red Hat Enterprise Linux 6.0 (64-bit)", "Red Hat Enterprise Linux 6 (64-bit)"); + _xcp160GuestOsMap.put("SUSE Linux Enterprise Server 9 SP4 (32-bit)", "SUSE Linux Enterprise Server 9 SP4"); + _xcp160GuestOsMap.put("SUSE Linux Enterprise Server 10 SP1 (32-bit)", "SUSE Linux Enterprise Server 10 SP1"); + _xcp160GuestOsMap.put("SUSE Linux Enterprise Server 10 SP1 (64-bit)", "SUSE Linux Enterprise Server 10 SP1 x64"); + _xcp160GuestOsMap.put("SUSE Linux Enterprise Server 10 SP2 (32-bit)", "SUSE Linux Enterprise Server 10 SP2"); + _xcp160GuestOsMap.put("SUSE Linux Enterprise Server 10 SP2 (64-bit)", "SUSE Linux Enterprise Server 10 SP2 x64"); + _xcp160GuestOsMap.put("SUSE Linux Enterprise Server 10 SP3 (64-bit)", "Other install media"); + _xcp160GuestOsMap.put("SUSE Linux Enterprise Server 11 (32-bit)", "SUSE Linux Enterprise Server 11"); + _xcp160GuestOsMap.put("SUSE Linux Enterprise Server 11 (64-bit)", "SUSE Linux Enterprise Server 11 x64"); + _xcp160GuestOsMap.put("SUSE Linux Enterprise Server 11 SP1 (32-bit)", "SUSE Linux Enterprise Server 11 SP1 (32-bit)"); + _xcp160GuestOsMap.put("SUSE Linux Enterprise Server 11 SP1 (64-bit)", "SUSE Linux Enterprise Server 11 SP1 (64-bit)"); + _xcp160GuestOsMap.put("Windows 7 (32-bit)", "Windows 7 (32-bit)"); + _xcp160GuestOsMap.put("Windows 7 (64-bit)", "Windows 7 (64-bit)"); + _xcp160GuestOsMap.put("Windows Server 2003 (32-bit)", "Windows Server 2003 (32-bit)"); + _xcp160GuestOsMap.put("Windows Server 2003 (64-bit)", "Windows Server 2003 (64-bit)"); + _xcp160GuestOsMap.put("Windows Server 2008 (32-bit)", "Windows Server 2008 (32-bit)"); + _xcp160GuestOsMap.put("Windows Server 2008 (64-bit)", "Windows Server 2008 (64-bit)"); + _xcp160GuestOsMap.put("Windows Server 2008 R2 (64-bit)", "Windows Server 2008 R2 (64-bit)"); + _xcp160GuestOsMap.put("Windows XP SP3 (32-bit)", "Windows XP SP3 (32-bit)"); + _xcp160GuestOsMap.put("Windows Vista (32-bit)", "Windows Vista (32-bit)"); + _xcp160GuestOsMap.put("Ubuntu 10.04 (32-bit)", "Ubuntu Lucid Lynx 10.04 (32-bit) (experimental)"); + _xcp160GuestOsMap.put("Ubuntu 10.04 (64-bit)", "Ubuntu Lucid Lynx 10.04 (64-bit) (experimental)"); + _xcp160GuestOsMap.put("Other Linux (32-bit)", "Other install media"); + _xcp160GuestOsMap.put("Other Linux (64-bit)", "Other install media"); + _xcp160GuestOsMap.put("Other PV (32-bit)", "CentOS 5 (32-bit)"); + _xcp160GuestOsMap.put("Other PV (64-bit)", "CentOS 5 (64-bit)"); + } + static { _xenServerGuestOsMap.put("CentOS 4.5 (32-bit)", "CentOS 4.5 (32-bit)"); @@ -694,6 +772,15 @@ public class CitrixHelper { return guestOS; } + public static String getXcp160GuestOsType(String stdType) { + String guestOS = _xcp160GuestOsMap.get(stdType); + if (guestOS == null) { + s_logger.debug("Can't find the guest os: " + stdType + " mapping into XCP's guestOS type, start it as HVM guest"); + guestOS = "Other install media"; + } + return guestOS; + } + public static String getXenServerGuestOsType(String stdType, boolean bootFromCD) { String guestOS = _xenServerGuestOsMap.get(stdType); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpServerResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpServerResource.java index 7a958708e76..6baf6a09e3f 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpServerResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpServerResource.java @@ -39,9 +39,10 @@ import com.xensource.xenapi.Types.XenAPIException; @Local(value=ServerResource.class) public class XcpServerResource extends CitrixResourceBase { private final static Logger s_logger = Logger.getLogger(XcpServerResource.class); - - public XcpServerResource() { + private String version; + public XcpServerResource(String version) { super(); + this.version = version; } @Override @@ -55,7 +56,11 @@ public class XcpServerResource extends CitrixResourceBase { @Override protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXcpGuestOsType(stdType); + if (version.equalsIgnoreCase("1.6")) { + return CitrixHelper.getXcp160GuestOsType(stdType); + } else { + return CitrixHelper.getXcpGuestOsType(stdType); + } } @Override From 3c59747635bd859bc0db6aa1f4ede6a37732237f Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Wed, 8 May 2013 15:37:29 -0700 Subject: [PATCH 46/71] Made a cast so we don't get warnings --- .../src/com/cloud/resource/ResourceManagerImpl.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index c9c3f9c3722..0ab35dd00a2 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -30,7 +30,6 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import com.cloud.dc.*; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd; import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd; @@ -74,6 +73,13 @@ import com.cloud.cluster.ManagementServerNode; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.ClusterDetailsDao; +import com.cloud.dc.ClusterDetailsVO; +import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenterIpAddressVO; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; +import com.cloud.dc.PodCluster; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.ClusterVSMMapDao; import com.cloud.dc.dao.DataCenterDao; @@ -1638,10 +1644,10 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, private Object dispatchToStateAdapters(ResourceStateAdapter.Event event, boolean singleTaker, Object... args) { synchronized (_resourceStateAdapters) { - Iterator it = _resourceStateAdapters.entrySet().iterator(); + Iterator> it = _resourceStateAdapters.entrySet().iterator(); Object result = null; while (it.hasNext()) { - Map.Entry item = (Map.Entry) it + Map.Entry item = it .next(); ResourceStateAdapter adapter = item.getValue(); From 6ef615e40dd56f57813f0fec78ad2bd9e394b8c7 Mon Sep 17 00:00:00 2001 From: Mice Xia Date: Thu, 9 May 2013 11:03:43 +0800 Subject: [PATCH 47/71] fix bug CLOUDSTACK-2341 remove network from VM is not removing PF/LB/static nat rules for the VM --- .../com/cloud/network/rules/RulesManager.java | 3 ++ .../cloud/network/rules/RulesManagerImpl.java | 38 ++++++++++++++ .../src/com/cloud/vm/UserVmManagerImpl.java | 6 +++ .../cloud/vm/VirtualMachineManagerImpl.java | 50 ++++++++++++++----- .../cloud/network/MockRulesManagerImpl.java | 8 +++ 5 files changed, 92 insertions(+), 13 deletions(-) diff --git a/server/src/com/cloud/network/rules/RulesManager.java b/server/src/com/cloud/network/rules/RulesManager.java index 4b83e04eb28..cede987280d 100644 --- a/server/src/com/cloud/network/rules/RulesManager.java +++ b/server/src/com/cloud/network/rules/RulesManager.java @@ -24,6 +24,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.IpAddress; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.Nic; import com.cloud.vm.VirtualMachine; /** @@ -87,4 +88,6 @@ public interface RulesManager extends RulesService { */ boolean applyStaticNatForNetwork(long networkId, boolean continueOnError, Account caller, boolean forRevoke); + List listAssociatedRulesForGuestNic(Nic nic); + } diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index 23556354e3a..c9b47b44bab 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -50,8 +50,11 @@ import com.cloud.network.dao.FirewallRulesCidrsDao; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.LoadBalancerVMMapDao; +import com.cloud.network.dao.LoadBalancerVMMapVO; import com.cloud.network.rules.FirewallRule.FirewallRuleType; import com.cloud.network.rules.FirewallRule.Purpose; +import com.cloud.network.rules.FirewallRule.TrafficType; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.vpc.VpcManager; import com.cloud.offering.NetworkOffering; @@ -77,6 +80,7 @@ import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; +import com.cloud.utils.net.NetUtils; import com.cloud.vm.Nic; import com.cloud.vm.NicSecondaryIp; import com.cloud.vm.UserVmVO; @@ -132,6 +136,8 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules VpcManager _vpcMgr; @Inject NicSecondaryIpDao _nicSecondaryDao; + @Inject + LoadBalancerVMMapDao _loadBalancerVMMapDao; @Override public void checkIpAndUserVm(IpAddress ipAddress, UserVm userVm, Account caller) { @@ -1467,4 +1473,36 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules protected void removePFRule(PortForwardingRuleVO rule) { _portForwardingDao.remove(rule.getId()); } + + @Override + public List listAssociatedRulesForGuestNic(Nic nic){ + List result = new ArrayList(); + // add PF rules + result.addAll(_portForwardingDao.listByDestIpAddr(nic.getIp4Address())); + // add static NAT rules + List staticNatRules = _firewallDao.listStaticNatByVmId(nic.getInstanceId()); + for(FirewallRuleVO rule : staticNatRules){ + if(rule.getNetworkId() == nic.getNetworkId()) + result.add(rule); + } + List staticNatIps = _ipAddressDao.listStaticNatPublicIps(nic.getNetworkId()); + for(IpAddress ip : staticNatIps){ + if(ip.getVmIp() != null && ip.getVmIp().equals(nic.getIp4Address())){ + VMInstanceVO vm = _vmInstanceDao.findById(nic.getInstanceId()); + // generate a static Nat rule on the fly because staticNATrule does not persist into db anymore + // FIX ME + FirewallRuleVO staticNatRule = new FirewallRuleVO(null, ip.getId(), 0, 65535, NetUtils.ALL_PROTO.toString(), + nic.getNetworkId(), vm.getAccountId(), vm.getDomainId(), Purpose.StaticNat, null, null, null, null, null); + result.add(staticNatRule); + } + } + // add LB rules + List lbMapList = _loadBalancerVMMapDao.listByInstanceId(nic.getInstanceId()); + for(LoadBalancerVMMapVO lb : lbMapList){ + FirewallRuleVO lbRule = _firewallDao.findById(lb.getLoadBalancerId()); + if(lbRule.getNetworkId() == nic.getNetworkId()) + result.add(lbRule); + } + return result; + } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index bc25bedde45..644f5ed773f 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -831,6 +831,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use if(network == null) { throw new InvalidParameterValueException("unable to find a network with id " + networkId); } + List allNics = _nicDao.listByVmId(vmInstance.getId()); + for(NicVO nic : allNics){ + if(nic.getNetworkId() == network.getId()) + throw new CloudRuntimeException("A NIC already exists for VM:" + vmInstance.getInstanceName() + " in network: " + network.getUuid()); + } + NicProfile profile = new NicProfile(null, null); if(ipAddress != null) { profile = new NicProfile(ipAddress, null); diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index afffbec436b..521b5e0c582 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -24,7 +24,6 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -37,40 +36,56 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import com.cloud.capacity.CapacityManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; - -import com.cloud.dc.*; -import com.cloud.agent.api.*; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager.OnError; import com.cloud.agent.Listener; +import com.cloud.agent.api.AgentControlAnswer; +import com.cloud.agent.api.AgentControlCommand; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckVirtualMachineAnswer; +import com.cloud.agent.api.CheckVirtualMachineCommand; +import com.cloud.agent.api.ClusterSyncAnswer; +import com.cloud.agent.api.ClusterSyncCommand; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.MigrateAnswer; +import com.cloud.agent.api.MigrateCommand; +import com.cloud.agent.api.PingRoutingCommand; +import com.cloud.agent.api.PrepareForMigrationAnswer; +import com.cloud.agent.api.PrepareForMigrationCommand; +import com.cloud.agent.api.RebootAnswer; +import com.cloud.agent.api.RebootCommand; +import com.cloud.agent.api.ScaleVmCommand; +import com.cloud.agent.api.StartAnswer; +import com.cloud.agent.api.StartCommand; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StartupRoutingCommand.VmState; +import com.cloud.agent.api.StopAnswer; +import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; -import com.cloud.agent.api.to.StorageFilerTO; -import com.cloud.agent.api.to.VolumeTO; import com.cloud.agent.manager.Commands; import com.cloud.agent.manager.allocator.HostAllocator; import com.cloud.alert.AlertManager; +import com.cloud.capacity.CapacityManager; import com.cloud.cluster.ClusterManager; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.ClusterDetailsDao; +import com.cloud.dc.ClusterDetailsVO; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; -import com.cloud.consoleproxy.ConsoleProxyManager; +import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; import com.cloud.deploy.DataCenterDeployment; @@ -109,6 +124,7 @@ import com.cloud.network.NetworkManager; import com.cloud.network.NetworkModel; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; +import com.cloud.network.rules.RulesManager; import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; import com.cloud.resource.ResourceManager; @@ -126,9 +142,9 @@ import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -154,12 +170,12 @@ import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.dao.UserVmDetailsDao; import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.snapshot.VMSnapshot; import com.cloud.vm.snapshot.VMSnapshotManager; import com.cloud.vm.snapshot.VMSnapshotVO; import com.cloud.vm.snapshot.dao.VMSnapshotDao; -import com.cloud.vm.dao.UserVmDetailsDao; @Local(value = VirtualMachineManager.class) public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMachineManager, Listener { @@ -235,6 +251,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected VolumeDataFactory volFactory; @Inject protected ResourceLimitService _resourceLimitMgr; + @Inject + protected RulesManager rulesMgr; protected List _planners; public List getPlanners() { @@ -2845,6 +2863,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.warn("Failed to remove nic from " + vm + " in " + network + ", nic is default."); throw new CloudRuntimeException("Failed to remove nic from " + vm + " in " + network + ", nic is default."); } + + // if specified nic is associated with PF/LB/Static NAT + if(rulesMgr.listAssociatedRulesForGuestNic(nic).size() > 0){ + throw new CloudRuntimeException("Failed to remove nic from " + vm + " in " + network + + ", nic has associated Port forwarding or Load balancer or Static NAT rules."); + } NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(network.getId(), vm.getId()), diff --git a/server/test/com/cloud/network/MockRulesManagerImpl.java b/server/test/com/cloud/network/MockRulesManagerImpl.java index 200fd2c7462..82a3e9346e3 100644 --- a/server/test/com/cloud/network/MockRulesManagerImpl.java +++ b/server/test/com/cloud/network/MockRulesManagerImpl.java @@ -28,6 +28,7 @@ import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.PortForwardingRuleVO; import com.cloud.network.rules.RulesManager; @@ -40,6 +41,7 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.net.Ip; +import com.cloud.vm.Nic; import com.cloud.vm.VirtualMachine; @Local(value = {RulesManager.class, RulesService.class}) @@ -310,4 +312,10 @@ public class MockRulesManagerImpl extends ManagerBase implements RulesManager, R return null; } + @Override + public List listAssociatedRulesForGuestNic(Nic nic) { + // TODO Auto-generated method stub + return null; + } + } From 600f140df67e8521e118691f92b460d55e7ec656 Mon Sep 17 00:00:00 2001 From: Mice Xia Date: Thu, 9 May 2013 14:27:13 +0800 Subject: [PATCH 48/71] fix CLOUDSTACK-2277 Add approriate message for the user informing about the absence of vm-tools when adding nics to vm on vmware --- .../vmware/resource/VmwareResource.java | 18 ++++++++++++++++++ server/src/com/cloud/vm/UserVmManagerImpl.java | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 030eff0148a..d87da64040b 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -237,6 +237,7 @@ import com.vmware.vim25.ClusterDasConfigInfo; import com.vmware.vim25.ComputeResourceSummary; import com.vmware.vim25.DatastoreSummary; import com.vmware.vim25.DynamicProperty; +import com.vmware.vim25.GuestInfo; import com.vmware.vim25.HostCapability; import com.vmware.vim25.HostFirewallInfo; import com.vmware.vim25.HostFirewallRuleset; @@ -1326,6 +1327,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa throw new Exception(msg); } + if(!isVMWareToolsInstalled(vmMo)){ + String errMsg = "vmware tools is not installed or not running, cannot add nic to vm " + vmName; + s_logger.debug(errMsg); + return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + errMsg); + } + // TODO need a way to specify the control of NIC device type VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.E1000; @@ -1400,6 +1407,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa throw new Exception(msg); } + if(!isVMWareToolsInstalled(vmMo)){ + String errMsg = "vmware tools not installed or not running, cannot remove nic from vm " + vmName; + s_logger.debug(errMsg); + return new UnPlugNicAnswer(cmd, false, "Unable to execute unPlugNicCommand due to " + errMsg); + } + VirtualDevice nic = findVirtualNicDevice(vmMo, cmd.getNic().getMac()); if ( nic == null ) { return new UnPlugNicAnswer(cmd, true, "success"); @@ -5237,4 +5250,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // TODO Auto-generated method stub } + + private boolean isVMWareToolsInstalled(VirtualMachineMO vmMo) throws Exception{ + GuestInfo guestInfo = vmMo.getVmGuestInfo(); + return (guestInfo != null && guestInfo.getGuestState() != null && guestInfo.getGuestState().equalsIgnoreCase("running")); + } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 644f5ed773f..eee8503b3f5 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -4248,7 +4248,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use _agentMgr.send(dest.getHost().getId(),cmds); PlugNicAnswer plugNicAnswer = cmds.getAnswer(PlugNicAnswer.class); if (!(plugNicAnswer != null && plugNicAnswer.getResult())) { - s_logger.warn("Unable to plug nic for " + vmVO); + s_logger.warn("Unable to plug nic for " + vmVO + " due to: " + " due to: " + plugNicAnswer.getDetails()); return false; } } catch (OperationTimedoutException e) { @@ -4276,7 +4276,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use _agentMgr.send(dest.getHost().getId(),cmds); UnPlugNicAnswer unplugNicAnswer = cmds.getAnswer(UnPlugNicAnswer.class); if (!(unplugNicAnswer != null && unplugNicAnswer.getResult())) { - s_logger.warn("Unable to unplug nic for " + vmVO); + s_logger.warn("Unable to unplug nic for " + vmVO + " due to: " + unplugNicAnswer.getDetails()); return false; } } catch (OperationTimedoutException e) { From 2e1877af33a49d4d18d3e024abca16b3d72dbf4e Mon Sep 17 00:00:00 2001 From: Milamber Date: Thu, 9 May 2013 10:46:05 +0100 Subject: [PATCH 49/71] CLOUDSTACK-2413 - Display the Name of compute offering in dialog box Change Service Offering (was Description field before) --- ui/scripts/instances.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index e5d7d14569b..c76d843ed6e 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -934,7 +934,7 @@ var serviceofferings = json.listserviceofferingsresponse.serviceoffering; var items = []; $(serviceofferings).each(function() { - items.push({id: this.id, description: this.displaytext}); + items.push({id: this.id, description: this.name}); }); args.response.success({data: items}); } From 2e2106002865cff8eb06b5c3a42bfd6f0f6848fb Mon Sep 17 00:00:00 2001 From: Rajesh Battala Date: Wed, 8 May 2013 18:46:51 +0530 Subject: [PATCH 50/71] CLOUDSTACK-869 nTier Apps 2.0 : Support NetScalar as external LB provider --- .../com/cloud/network/vpc/VpcOffering.java | 1 + .../network/element/NetscalerElement.java | 34 ++- server/pom.xml | 4 +- .../com/cloud/network/NetworkServiceImpl.java | 6 +- .../guru/ExternalGuestNetworkGuru.java | 40 +-- .../com/cloud/network/vpc/VpcManagerImpl.java | 32 ++- server/test/com/cloud/vpc/VpcTest.java | 269 ++++++++++++++++++ .../CreateNetworkOfferingTest.java | 43 +++ 8 files changed, 406 insertions(+), 23 deletions(-) create mode 100644 server/test/com/cloud/vpc/VpcTest.java diff --git a/api/src/com/cloud/network/vpc/VpcOffering.java b/api/src/com/cloud/network/vpc/VpcOffering.java index 3961d0aaba7..3ec81e693af 100644 --- a/api/src/com/cloud/network/vpc/VpcOffering.java +++ b/api/src/com/cloud/network/vpc/VpcOffering.java @@ -26,6 +26,7 @@ public interface VpcOffering extends InternalIdentity, Identity { } public static final String defaultVPCOfferingName = "Default VPC offering"; + public static final String defaultVPCNSOfferingName = "Default VPC offering with Netscaler"; /** * diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java index 7bd9c2ec8b3..b8144301810 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java @@ -61,6 +61,9 @@ import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.LbStickinessMethod; import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; import com.cloud.network.rules.StaticNat; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRouteProfile; +import com.cloud.network.vpc.Vpc; import com.cloud.offering.NetworkOffering; import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.DB; @@ -85,7 +88,7 @@ import java.util.*; @Local(value = {NetworkElement.class, StaticNatServiceProvider.class, LoadBalancingServiceProvider.class, GslbServiceProvider.class}) public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl implements LoadBalancingServiceProvider, NetscalerLoadBalancerElementService, ExternalLoadBalancerDeviceManager, IpDeployer, StaticNatServiceProvider, - GslbServiceProvider { + GslbServiceProvider, VpcProvider { private static final Logger s_logger = Logger.getLogger(NetscalerElement.class); public static final AutoScaleCounterType AutoScaleCounterSnmp = new AutoScaleCounterType("snmp"); @@ -957,4 +960,33 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } return null; } + + @Override + public boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + return true; + } + + @Override + public boolean shutdownVpc(Vpc vpc, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException { + return true; + } + + @Override + public boolean createPrivateGateway(PrivateGateway gateway) throws ConcurrentOperationException, + ResourceUnavailableException { + return true; + } + + @Override + public boolean deletePrivateGateway(PrivateGateway privateGateway) throws ConcurrentOperationException, + ResourceUnavailableException { + return true; + } + + @Override + public boolean applyStaticRoutes(Vpc vpc, List routes) throws ResourceUnavailableException { + return true; + } } diff --git a/server/pom.xml b/server/pom.xml index 808dd3eee0a..004d9c8e068 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -154,7 +154,9 @@ com/cloud/network/vpn/RemoteAccessVpnTest.java com/cloud/network/security/SecurityGroupManagerImpl2Test.java com/cloud/network/security/SecurityGroupManagerImpl2Test.java - com/cloud/vpc/* + com/cloud/vpc/VpcTestConfiguration.java + com/cloud/vpc/VpcApiUnitTest.java + com/cloud/vpc/VpcManagerTest.java diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 5e8be92fdb5..f44688c7594 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -1121,7 +1121,11 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { // validate if CIDR specified overlaps with any of the CIDR's allocated for isolated networks and shared networks in the zone checkSharedNetworkCidrOverlap(zoneId, pNtwk.getId(), cidr); } else { - throw new InvalidParameterValueException("Cannot specify CIDR when using network offering with external devices!"); + // if the guest network is for the VPC, if any External Provider are supported in VPC + // cidr will not be null as it is generated from the super cidr of vpc. + // if cidr is not null and network is not part of vpc then throw the exception + if (vpcId == null) + throw new InvalidParameterValueException("Cannot specify CIDR when using network offering with external devices!"); } } diff --git a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java index b1606db71b1..fe9e01f558d 100644 --- a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java @@ -118,7 +118,7 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru { if (Boolean.parseBoolean(_configDao.getValue(Config.OvsTunnelNetwork.key()))) { return null; } - + if (!_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId())) { return super.implement(config, offering, dest, context); } @@ -145,25 +145,31 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru { implemented.setBroadcastUri(config.getBroadcastUri()); } - // Determine the offset from the lowest vlan tag - int offset = getVlanOffset(config.getPhysicalNetworkId(), vlanTag); - // Determine the new gateway and CIDR String[] oldCidr = config.getCidr().split("/"); String oldCidrAddress = oldCidr[0]; - int cidrSize = getGloballyConfiguredCidrSize(); - - // If the offset has more bits than there is room for, return null - long bitsInOffset = 32 - Integer.numberOfLeadingZeros(offset); - if (bitsInOffset > (cidrSize - 8)) { - throw new CloudRuntimeException("The offset " + offset + " needs " + bitsInOffset + " bits, but only have " + (cidrSize - 8) + " bits to work with."); + int cidrSize = Integer.parseInt(oldCidr[1]); + long newCidrAddress = (NetUtils.ip2Long(oldCidrAddress)); + // if the implementing network is for vpc, no need to generate newcidr, use the cidr that came from super cidr + if (config.getVpcId() != null) { + implemented.setGateway(config.getGateway()); + implemented.setCidr(config.getCidr()); + implemented.setState(State.Implemented); + } else { + // Determine the offset from the lowest vlan tag + int offset = getVlanOffset(config.getPhysicalNetworkId(), vlanTag); + cidrSize = getGloballyConfiguredCidrSize(); + // If the offset has more bits than there is room for, return null + long bitsInOffset = 32 - Integer.numberOfLeadingZeros(offset); + if (bitsInOffset > (cidrSize - 8)) { + throw new CloudRuntimeException("The offset " + offset + " needs " + bitsInOffset + " bits, but only have " + (cidrSize - 8) + " bits to work with."); + } + newCidrAddress = (NetUtils.ip2Long(oldCidrAddress) & 0xff000000) | (offset << (32 - cidrSize)); + implemented.setGateway(NetUtils.long2Ip(newCidrAddress + 1)); + implemented.setCidr(NetUtils.long2Ip(newCidrAddress) + "/" + cidrSize); + implemented.setState(State.Implemented); } - long newCidrAddress = (NetUtils.ip2Long(oldCidrAddress) & 0xff000000) | (offset << (32 - cidrSize)); - implemented.setGateway(NetUtils.long2Ip(newCidrAddress + 1)); - implemented.setCidr(NetUtils.long2Ip(newCidrAddress) + "/" + cidrSize); - implemented.setState(State.Implemented); - // Mask the Ipv4 address of all nics that use this network with the new guest VLAN offset List nicsInNetwork = _nicDao.listByNetworkId(config.getId()); for (NicVO nic : nicsInNetwork) { @@ -172,8 +178,8 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru { nic.setIp4Address(NetUtils.long2Ip(newCidrAddress | ipMask)); _nicDao.persist(nic); } - } - + } + // Mask the destination address of all port forwarding rules in this network with the new guest VLAN offset List pfRulesInNetwork = _pfRulesDao.listByNetwork(config.getId()); for (PortForwardingRuleVO pfRule : pfRulesInNetwork) { diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index a7f06e988dd..9be22084e11 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -184,8 +184,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker")); private List vpcElements = null; private final List nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall); - private final List supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp); - + private final List supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.Netscaler); int _cleanupInterval; int _maxNetworks; SearchBuilder IpAddressSearch; @@ -215,7 +214,27 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, true, State.Enabled); } - + + //configure default vpc offering with Netscaler as LB Provider + if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCNSOfferingName ) == null) { + s_logger.debug("Creating default VPC offering with Netscaler as LB Provider" + VpcOffering.defaultVPCNSOfferingName); + Map> svcProviderMap = new HashMap>(); + Set defaultProviders = new HashSet(); + defaultProviders.add(Provider.VPCVirtualRouter); + for (Service svc : getSupportedServices()) { + if (svc == Service.Lb) { + Set lbProviders = new HashSet(); + lbProviders.add(Provider.Netscaler); + lbProviders.add(Provider.VPCVirtualRouter); + svcProviderMap.put(svc, lbProviders); + } else { + svcProviderMap.put(svc, defaultProviders); + } + } + createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, + svcProviderMap, false, State.Enabled); + } + txn.commit(); Map configs = _configDao.getConfiguration(params); @@ -1084,6 +1103,12 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis if (guestNtwkOff.isConserveMode()) { throw new InvalidParameterValueException("Only networks with conserve mode Off can belong to VPC"); } + + //5) If Netscaler is LB provider make sure it is in dedicated mode + if ( providers.contains(Provider.Netscaler) && !guestNtwkOff.getDedicatedLB() ) { + throw new InvalidParameterValueException("Netscaler only with Dedicated LB can belong to VPC"); + } + return ; } @DB @@ -1155,6 +1180,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis if (vpcElements == null) { vpcElements = new ArrayList(); vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Provider.VPCVirtualRouter.getName())); + vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Provider.Netscaler.getName())); } if (vpcElements == null) { diff --git a/server/test/com/cloud/vpc/VpcTest.java b/server/test/com/cloud/vpc/VpcTest.java new file mode 100644 index 00000000000..52e837ec5ca --- /dev/null +++ b/server/test/com/cloud/vpc/VpcTest.java @@ -0,0 +1,269 @@ +// 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.vpc; + +import com.cloud.configuration.ConfigurationManager; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkModel; +import com.cloud.network.NetworkService; +import com.cloud.network.dao.FirewallRulesDao; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.Site2SiteVpnGatewayDao; +import com.cloud.network.vpc.*; +import com.cloud.network.vpc.dao.PrivateIpDao; +import com.cloud.network.vpc.dao.StaticRouteDao; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.network.vpc.dao.VpcGatewayDao; +import com.cloud.network.vpc.dao.VpcOfferingDao; +import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao; +import com.cloud.network.vpc.dao.VpcServiceMapDao; +import com.cloud.network.vpn.Site2SiteVpnManager; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; +import com.cloud.server.ConfigurationServer; +import com.cloud.tags.dao.ResourceTagDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; +import com.cloud.user.ResourceLimitService; +import com.cloud.user.UserContext; +import com.cloud.utils.component.ComponentContext; +import com.cloud.vm.dao.DomainRouterDao; + +import junit.framework.TestCase; +import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd; +import org.apache.cloudstack.api.command.user.vpc.CreateVPCCmd; +import org.apache.cloudstack.test.utils.SpringUtils; +import org.apache.log4j.Logger; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.classreading.MetadataReaderFactory; +import org.springframework.core.type.filter.TypeFilter; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import javax.inject.Inject; +import java.io.IOException; +import java.util.UUID; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(loader = AnnotationConfigContextLoader.class) +public class VpcTest extends TestCase { + + @Inject + VpcService _vpcService; + + @Inject + AccountManager _accountMgr; + + @Inject + VpcManager _vpcMgr; + + @Inject + VpcDao _vpcDao; + + @Inject + VpcOfferingDao _vpcOfferinDao; + + private VpcVO vpc; + private static final Logger s_logger = Logger.getLogger(VpcTest.class); + + @Before + public void setUp() { + ComponentContext.initComponentsLifeCycle(); + Account account = new AccountVO("testaccount", 1, "testdomain", (short) 0, UUID.randomUUID().toString()); + UserContext.registerContext(1, account, null, true); + vpc = new VpcVO(1, "myvpc", "myvpc", 2, 1, 1, "10.0.1.0/16", "mydomain"); + } + + @Test + public void testCreateVpc() throws Exception { + Mockito.when( + _vpcMgr.createVpc(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyString(), + Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(vpc); + Mockito.when(_vpcOfferinDao.persist(Mockito.any(VpcOfferingVO.class))).thenReturn( + new VpcOfferingVO("test", "test", 1L)); + Vpc vpc1 = _vpcMgr.createVpc(1, 1, 1, "myVpc", "my Vpc", "10.0.0.0/16", "test"); + assertNotNull("Vpc is created", vpc1); + } + + @Configuration + @ComponentScan(basePackageClasses = { VpcManager.class }, includeFilters = { @ComponentScan.Filter(value = VpcTestConfiguration.Library.class, type = FilterType.CUSTOM) }, useDefaultFilters = false) + public static class VpcTestConfiguration extends SpringUtils.CloudStackTestConfiguration { + + @Bean + public AccountManager accountManager() { + return Mockito.mock(AccountManager.class); + } + + @Bean + public NetworkManager networkManager() { + return Mockito.mock(NetworkManager.class); + } + + @Bean + public NetworkModel networkModel() { + return Mockito.mock(NetworkModel.class); + } + + @Bean + public VpcManager vpcManager() { + return Mockito.mock(VpcManager.class); + } + + @Bean + public ResourceTagDao resourceTagDao() { + return Mockito.mock(ResourceTagDao.class); + } + + @Bean + public VpcDao VpcDao() { + return Mockito.mock(VpcDao.class); + } + + @Bean + public VpcOfferingDao vpcOfferingDao() { + return Mockito.mock(VpcOfferingDao.class); + } + + @Bean + public VpcOfferingServiceMapDao vpcOfferingServiceMapDao() { + return Mockito.mock(VpcOfferingServiceMapDao.class); + } + + @Bean + public ConfigurationDao configurationDao() { + return Mockito.mock(ConfigurationDao.class); + } + + @Bean + public ConfigurationManager configurationManager() { + return Mockito.mock(ConfigurationManager.class); + } + + @Bean + public NetworkDao networkDao() { + return Mockito.mock(NetworkDao.class); + } + + @Bean + public NetworkACLManager networkACLManager() { + return Mockito.mock(NetworkACLManager.class); + } + + @Bean + public IPAddressDao ipAddressDao() { + return Mockito.mock(IPAddressDao.class); + } + + @Bean + public DomainRouterDao domainRouterDao() { + return Mockito.mock(DomainRouterDao.class); + } + + @Bean + public VpcGatewayDao vpcGatewayDao() { + return Mockito.mock(VpcGatewayDao.class); + } + + @Bean + public PrivateIpDao privateIpDao() { + return Mockito.mock(PrivateIpDao.class); + } + + @Bean + public StaticRouteDao staticRouteDao() { + return Mockito.mock(StaticRouteDao.class); + } + + @Bean + public NetworkOfferingServiceMapDao networkOfferingServiceMapDao() { + return Mockito.mock(NetworkOfferingServiceMapDao.class); + } + + @Bean + public PhysicalNetworkDao physicalNetworkDao() { + return Mockito.mock(PhysicalNetworkDao.class); + } + + @Bean + public FirewallRulesDao firewallRulesDao() { + return Mockito.mock(FirewallRulesDao.class); + } + + @Bean + public Site2SiteVpnGatewayDao site2SiteVpnGatewayDao() { + return Mockito.mock(Site2SiteVpnGatewayDao.class); + } + + @Bean + public Site2SiteVpnManager site2SiteVpnManager() { + return Mockito.mock(Site2SiteVpnManager.class); + } + + @Bean + public VlanDao vlanDao() { + return Mockito.mock(VlanDao.class); + } + + @Bean + public ResourceLimitService resourceLimitService() { + return Mockito.mock(ResourceLimitService.class); + } + + @Bean + public VpcServiceMapDao vpcServiceMapDao() { + return Mockito.mock(VpcServiceMapDao.class); + } + + @Bean + public NetworkService networkService() { + return Mockito.mock(NetworkService.class); + } + + @Bean + public DataCenterDao dataCenterDao() { + return Mockito.mock(DataCenterDao.class); + } + + @Bean + public ConfigurationServer configurationServer() { + return Mockito.mock(ConfigurationServer.class); + } + + public static class Library implements TypeFilter { + @Override + public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { + mdr.getClassMetadata().getClassName(); + ComponentScan cs = VpcTestConfiguration.class.getAnnotation(ComponentScan.class); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + } + } + } + +} diff --git a/server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java b/server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java index cbb6c00e397..7946c1aa740 100644 --- a/server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java +++ b/server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java @@ -41,6 +41,7 @@ import com.cloud.network.Network; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.vpc.VpcManager; import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offerings.NetworkOfferingServiceMapVO; import com.cloud.offerings.NetworkOfferingVO; @@ -72,6 +73,9 @@ public class CreateNetworkOfferingTest extends TestCase{ @Inject AccountManager accountMgr; + @Inject + VpcManager vpcMgr; + @Before public void setUp() { ComponentContext.initComponentsLifeCycle(); @@ -180,4 +184,43 @@ public class CreateNetworkOfferingTest extends TestCase{ assertNotNull("Isolated network offering with specifyIpRanges=true and with no sourceNatService, failed to create", off); } + + @Test + public void createVpcNtwkOff() { + Map> serviceProviderMap = new HashMap>(); + Set vrProvider = new HashSet(); + vrProvider.add(Provider.VPCVirtualRouter); + serviceProviderMap.put(Network.Service.Dhcp , vrProvider); + serviceProviderMap.put(Network.Service.Dns , vrProvider); + serviceProviderMap.put(Network.Service.Lb , vrProvider); + serviceProviderMap.put(Network.Service.SourceNat , vrProvider); + serviceProviderMap.put(Network.Service.Gateway , vrProvider); + serviceProviderMap.put(Network.Service.Lb , vrProvider); + NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, true, + Availability.Optional, 200, serviceProviderMap, false, Network.GuestType.Isolated, false, + null, false, null, false, false); + // System.out.println("Creating Vpc Network Offering"); + assertNotNull("Vpc Isolated network offering with Vpc provider ", off); + } + + @Test + public void createVpcNtwkOffWithNetscaler() { + Map> serviceProviderMap = new HashMap>(); + Set vrProvider = new HashSet(); + Set lbProvider = new HashSet(); + vrProvider.add(Provider.VPCVirtualRouter); + lbProvider.add(Provider.Netscaler); + serviceProviderMap.put(Network.Service.Dhcp, vrProvider); + serviceProviderMap.put(Network.Service.Dns, vrProvider); + serviceProviderMap.put(Network.Service.Lb, vrProvider); + serviceProviderMap.put(Network.Service.SourceNat, vrProvider); + serviceProviderMap.put(Network.Service.Gateway, vrProvider); + serviceProviderMap.put(Network.Service.Lb, lbProvider); + NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, true, + Availability.Optional, 200, serviceProviderMap, false, Network.GuestType.Isolated, false, null, false, + null, false, false); + // System.out.println("Creating Vpc Network Offering"); + assertNotNull("Vpc Isolated network offering with Vpc and Netscaler provider ", off); + } + } From bde9ad3c13397758cce0b69414c0a70904947d11 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Thu, 9 May 2013 15:49:36 +0530 Subject: [PATCH 51/71] CLOUDSTACK-2408: Object name is Null with list VNMC/List ASA API response Setting object name correctly in response --- .../ListCiscoAsa1000vResourcesCmd.java | 1 + .../commands/ListCiscoVnmcResourcesCmd.java | 15 ++++--- .../CiscoAsa1000vResourceResponse.java | 45 +++++++++++-------- .../response/CiscoVnmcResourceResponse.java | 42 ++++++++++------- 4 files changed, 62 insertions(+), 41 deletions(-) diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoAsa1000vResourcesCmd.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoAsa1000vResourcesCmd.java index 509d39fb5f9..7a4db69e7e2 100755 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoAsa1000vResourcesCmd.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoAsa1000vResourcesCmd.java @@ -89,6 +89,7 @@ public class ListCiscoAsa1000vResourcesCmd extends BaseListCmd { if (ciscoAsa1000vDevices != null && !ciscoAsa1000vDevices.isEmpty()) { for (CiscoAsa1000vDevice ciscoAsa1000vDeviceVO : ciscoAsa1000vDevices) { CiscoAsa1000vResourceResponse ciscoAsa1000vResourceResponse = _ciscoAsa1000vService.createCiscoAsa1000vResourceResponse(ciscoAsa1000vDeviceVO); + ciscoAsa1000vResourceResponse.setObjectName("asa1000v"); ciscoAsa1000vResourcesResponse.add(ciscoAsa1000vResourceResponse); } } diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoVnmcResourcesCmd.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoVnmcResourcesCmd.java index ab553ee94ac..b15c4e1c43e 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoVnmcResourcesCmd.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoVnmcResourcesCmd.java @@ -77,18 +77,19 @@ public class ListCiscoVnmcResourcesCmd extends BaseListCmd { @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { try { - List CiscoVnmcResources = _ciscoVnmcElementService.listCiscoVnmcResources(this); + List ciscoVnmcResources = _ciscoVnmcElementService.listCiscoVnmcResources(this); ListResponse response = new ListResponse(); - List CiscoVnmcResourcesResponse = new ArrayList(); + List ciscoVnmcResourcesResponse = new ArrayList(); - if (CiscoVnmcResources != null && !CiscoVnmcResources.isEmpty()) { - for (CiscoVnmcController CiscoVnmcResourceVO : CiscoVnmcResources) { - CiscoVnmcResourceResponse CiscoVnmcResourceResponse = _ciscoVnmcElementService.createCiscoVnmcResourceResponse(CiscoVnmcResourceVO); - CiscoVnmcResourcesResponse.add(CiscoVnmcResourceResponse); + if (ciscoVnmcResources != null && !ciscoVnmcResources.isEmpty()) { + for (CiscoVnmcController ciscoVnmcResourceVO : ciscoVnmcResources) { + CiscoVnmcResourceResponse ciscoVnmcResourceResponse = _ciscoVnmcElementService.createCiscoVnmcResourceResponse(ciscoVnmcResourceVO); + ciscoVnmcResourceResponse.setObjectName("vnmc"); + ciscoVnmcResourcesResponse.add(ciscoVnmcResourceResponse); } } - response.setResponses(CiscoVnmcResourcesResponse); + response.setResponses(ciscoVnmcResourcesResponse); response.setResponseName(getCommandName()); this.setResponseObject(response); } catch (InvalidParameterValueException invalidParamExcp) { diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/response/CiscoAsa1000vResourceResponse.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/api/response/CiscoAsa1000vResourceResponse.java index 9cd87da66a1..f857b352b4a 100755 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/response/CiscoAsa1000vResourceResponse.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/api/response/CiscoAsa1000vResourceResponse.java @@ -29,60 +29,69 @@ import com.google.gson.annotations.SerializedName; @EntityReference(value = CiscoAsa1000vDevice.class) public class CiscoAsa1000vResourceResponse extends BaseResponse { - public static final String RESOURCE_NAME = "resourcename"; - @SerializedName(ApiConstants.RESOURCE_ID) @Parameter(description="resource id of the Cisco ASA 1000v appliance") + @SerializedName(ApiConstants.RESOURCE_ID) + @Parameter(description="resource id of the Cisco ASA 1000v appliance") private String id; @SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) @Parameter(description="the physical network to which this ASA 1000v belongs to", entityType = PhysicalNetworkResponse.class) - private Long physicalNetworkId ; - - public Long getPhysicalNetworkId() { - return physicalNetworkId; - } + private Long physicalNetworkId; @SerializedName(ApiConstants.HOST_NAME) @Parameter(description="management ip address of ASA 1000v") private String managementIp; - public String getManagementIp() { - return managementIp; - } - @SerializedName(ApiConstants.ASA_INSIDE_PORT_PROFILE) - @Parameter(description="management ip address of ASA 1000v") + @Parameter(description="port profile associated with inside interface of ASA 1000v") private String inPortProfile; - public String getInPortProfile() { - return inPortProfile; - } - @SerializedName(ApiConstants.NETWORK_ID) @Parameter(description="the guest network to which ASA 1000v is associated", entityType = NetworkResponse.class) private Long guestNetworkId; - public Long getGuestNetworkId() { - return guestNetworkId; + public String getId() { + return id; } public void setId(String ciscoAsa1000vResourceId) { this.id = ciscoAsa1000vResourceId; } + public Long getPhysicalNetworkId() { + return physicalNetworkId; + } + public void setPhysicalNetworkId(Long physicalNetworkId) { this.physicalNetworkId = physicalNetworkId; } + public String getManagementIp() { + return managementIp; + } + public void setManagementIp(String managementIp) { this.managementIp = managementIp; } + public String getInPortProfile() { + return inPortProfile; + } + public void setInPortProfile(String inPortProfile) { this.inPortProfile = inPortProfile; } + public Long getGuestNetworkId() { + return guestNetworkId; + } + public void setGuestNetworkId(Long guestNetworkId) { this.guestNetworkId = guestNetworkId; } + + @Override + public String getObjectId() { + return this.getId(); + } } diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/response/CiscoVnmcResourceResponse.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/api/response/CiscoVnmcResourceResponse.java index f5c9b727f8f..92a766d1bbf 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/response/CiscoVnmcResourceResponse.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/api/response/CiscoVnmcResourceResponse.java @@ -25,6 +25,7 @@ import org.apache.cloudstack.api.response.PhysicalNetworkResponse; import com.cloud.network.cisco.CiscoVnmcController; import com.google.gson.annotations.SerializedName; + @EntityReference(value = CiscoVnmcController.class) public class CiscoVnmcResourceResponse extends BaseResponse { public static final String RESOURCE_NAME = "resourcename"; @@ -33,43 +34,52 @@ public class CiscoVnmcResourceResponse extends BaseResponse { @Parameter(description="resource id of the Cisco VNMC controller") private String id; - @SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) + @SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) @Parameter(description="the physical network to which this VNMC belongs to", entityType = PhysicalNetworkResponse.class) private Long physicalNetworkId; - public Long getPhysicalNetworkId() { - return physicalNetworkId; - } - - public String getProviderName() { - return providerName; - } - - public String getResourceName() { - return resourceName; - } - - @SerializedName(ApiConstants.PROVIDER) @Parameter(description="name of the provider") + @SerializedName(ApiConstants.PROVIDER) + @Parameter(description="name of the provider") private String providerName; - @SerializedName(RESOURCE_NAME) + @SerializedName(RESOURCE_NAME) @Parameter(description="Cisco VNMC resource name") private String resourceName; + public String getId() { + return id; + } + public void setId(String ciscoVnmcResourceId) { this.id = ciscoVnmcResourceId; } + public Long getPhysicalNetworkId() { + return physicalNetworkId; + } + public void setPhysicalNetworkId(Long physicalNetworkId) { this.physicalNetworkId = physicalNetworkId; } + public String getProviderName() { + return providerName; + } + public void setProviderName(String providerName) { this.providerName = providerName; } + public String getResourceName() { + return resourceName; + } + public void setResourceName(String resourceName) { this.resourceName = resourceName; - } + } + @Override + public String getObjectId() { + return this.getId(); + } } From 8f9a42e0af7424517c7853197a781c0c81addad1 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Thu, 9 May 2013 15:58:59 +0530 Subject: [PATCH 52/71] CLOUDSTACK-2408: Object name is Null with list VNMC/List ASA API response Made the object name consistent between list and add api responses --- .../com/cloud/api/commands/ListCiscoAsa1000vResourcesCmd.java | 2 +- .../src/com/cloud/api/commands/ListCiscoVnmcResourcesCmd.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoAsa1000vResourcesCmd.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoAsa1000vResourcesCmd.java index 7a4db69e7e2..88ea2709325 100755 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoAsa1000vResourcesCmd.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoAsa1000vResourcesCmd.java @@ -89,7 +89,7 @@ public class ListCiscoAsa1000vResourcesCmd extends BaseListCmd { if (ciscoAsa1000vDevices != null && !ciscoAsa1000vDevices.isEmpty()) { for (CiscoAsa1000vDevice ciscoAsa1000vDeviceVO : ciscoAsa1000vDevices) { CiscoAsa1000vResourceResponse ciscoAsa1000vResourceResponse = _ciscoAsa1000vService.createCiscoAsa1000vResourceResponse(ciscoAsa1000vDeviceVO); - ciscoAsa1000vResourceResponse.setObjectName("asa1000v"); + ciscoAsa1000vResourceResponse.setObjectName("CiscoAsa1000vResource"); ciscoAsa1000vResourcesResponse.add(ciscoAsa1000vResourceResponse); } } diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoVnmcResourcesCmd.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoVnmcResourcesCmd.java index b15c4e1c43e..73128ecec2b 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoVnmcResourcesCmd.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoVnmcResourcesCmd.java @@ -84,7 +84,7 @@ public class ListCiscoVnmcResourcesCmd extends BaseListCmd { if (ciscoVnmcResources != null && !ciscoVnmcResources.isEmpty()) { for (CiscoVnmcController ciscoVnmcResourceVO : ciscoVnmcResources) { CiscoVnmcResourceResponse ciscoVnmcResourceResponse = _ciscoVnmcElementService.createCiscoVnmcResourceResponse(ciscoVnmcResourceVO); - ciscoVnmcResourceResponse.setObjectName("vnmc"); + ciscoVnmcResourceResponse.setObjectName("CiscoVnmcResource"); ciscoVnmcResourcesResponse.add(ciscoVnmcResourceResponse); } } From 2660a6b7a7f226ab757d2175222db62571813120 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 9 May 2013 11:05:54 -0700 Subject: [PATCH 53/71] CLOUDSTACK-747: Internal LB between VPC tiers support Squashed commit of the following: commit def0861d5a12202260cb6672c12d77075a0de26e Author: Alena Prokharchyk Date: Thu May 9 10:53:09 2013 -0700 Inernallb: added internalLbVm to the list of network elements for nonoss build commit 56d94fc074db52ef00ace1703081a342dfb63db0 Merge: d828c15 8f9a42e Author: Alena Prokharchyk Date: Thu May 9 09:51:36 2013 -0700 Merge branch 'master' into internallb1 Conflicts: plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java server/src/com/cloud/network/vpc/VpcManagerImpl.java commit d828c154fd05fbfeb9c142b27e3d26e7dd755c77 Author: Alena Prokharchyk Date: Wed May 8 14:58:22 2013 -0700 internallb: Fixed nonoss build commit 1b8a6986a6fd1808ba7285589f9a007b52feb7e5 Merge: 9e74fa9 738d35a Author: Alena Prokharchyk Date: Wed May 8 13:20:07 2013 -0700 Merge branch 'master' into internallb1 Conflicts: api/src/com/cloud/async/AsyncJob.java api/src/com/cloud/network/NetworkModel.java api/src/com/cloud/network/rules/LoadBalancerContainer.java api/src/org/apache/cloudstack/api/BaseCmd.java api/src/org/apache/cloudstack/api/ResponseGenerator.java api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerContainer.java client/tomcatconf/commands.properties.in engine/schema/src/com/cloud/network/dao/LoadBalancerDaoImpl.java server/src/com/cloud/api/ApiResponseHelper.java server/src/com/cloud/network/NetworkManagerImpl.java server/src/com/cloud/network/NetworkModelImpl.java server/src/com/cloud/network/NetworkServiceImpl.java server/src/com/cloud/server/ManagementServerImpl.java server/test/com/cloud/network/MockNetworkModelImpl.java server/test/com/cloud/vpc/MockNetworkManagerImpl.java server/test/com/cloud/vpc/MockNetworkModelImpl.java server/test/resources/appLoadBalancer.xml setup/db/db/schema-410to420.sql test/integration/component/test_multiple_ip_ranges.py test/integration/smoke/test_guest_vlan_range.py tools/marvin/marvin/integration/lib/base.py commit 9e74fa94067997f0ae6d469f3564df602dd274a6 Author: Prasanna Santhanam Date: Thu May 9 00:11:40 2013 +0530 marvin changes for internallbvm provider - changed the simulator context to load the internallb bean - fixed deployDataCenter to use the additional provider by default - fixed the sandbox script and the setup script for simulator checkin tests Signed-off-by: Prasanna Santhanam commit 0a2d49301b170171ebe8d6646236854f488d06ba Author: Jessica Wang Date: Tue May 7 15:50:41 2013 -0700 Internal LB - UI - zone wizard - advanced zone - enable internal LB element, enable internal LB provider. commit 43e1667f90b01e2b4095009b997b3b2665087fb4 Author: Alena Prokharchyk Date: Tue May 7 13:26:53 2013 -0700 Moved all DAOs and VOs to the cloud-engine-schema project commit 2fd94c8bbe24da86e6bd004ee8165e08038a3e1d Author: Radhika PC Date: Tue May 7 18:26:08 2013 +0530 CLOUDSTACK-893 api commit 12b64d6c00940a4b5c4aa059f2c36ae7cc1b79bd Author: Prasanna Santhanam Date: Tue May 7 17:06:15 2013 +0530 Fixing the gmaven configuration for marvin/pom.xml For the marvin checkin test custom properties had a typo when run for the *nix environment. Signed-off-by: Prasanna Santhanam commit 1e4274dd9f55a6eea7121d50e361babcafe70725 Author: Prasanna Santhanam Date: Tue May 7 15:28:43 2013 +0530 Renaming TesDedicateVlanRange -> TestDedicateVlanRange Signed-off-by: Prasanna Santhanam commit 9264ac526f854c980afb669631177c99e4bbbed7 Author: Prasanna Santhanam Date: Tue May 7 15:28:20 2013 +0530 Adding isolation method to the zone creation of marvin Signed-off-by: Prasanna Santhanam commit 3a0dc67de0285fffa7739b25286df71f92470ddf Author: Prasanna Santhanam Date: Tue May 7 15:27:26 2013 +0530 adding ACL for dedicateGuestVlanRange set of APIs Signed-off-by: Prasanna Santhanam commit 79f6e11368d4b6227e9055bb58cce8e5b9872cfe Author: Prasanna Santhanam Date: Tue May 7 15:26:48 2013 +0530 add debug logs when access checkers fail to find API When the access checkers fail for api discovery, we fail silently. instead record a debug message. Signed-off-by: Prasanna Santhanam commit 92cb7d3e0f3ef052104f698e005ab8dd243f9885 Author: Hugo Trippaers Date: Tue May 7 11:44:23 2013 +0200 commit e0d8f01ecd92a1a7b74558d02a28be3b2f20a10d enabled all tests. Fix AWSAPI build by removing broken tests and excluding failing tests. commit 4a391464c7359689915c4230dfa07d728acfb752 Author: Hugo Trippaers Date: Tue May 7 10:57:23 2013 +0200 commit e0d8f01ecd92a1a7b74558d02a28be3b2f20a10d enabled all tests, but the tests in vmware-base are horribly broken and will not compile with the current CloudStack. Removing the tests to fix the nonoss build and they are so broken they should be rewritten from scratch anyway. commit 2ca03a851360c733ddacbe6a5490b6812dfc6bec Author: Prasanna Santhanam Date: Tue May 7 13:51:34 2013 +0530 moving test data to top level dictionary Signed-off-by: Prasanna Santhanam commit ceaa4e1b0d77ccb811a7e1f56ae212034b3f4a90 Author: Prasanna Santhanam Date: Tue May 7 13:50:56 2013 +0530 Adding tracelogs to the API discovery service Signed-off-by: Prasanna Santhanam commit a3f5f01c7e78e045fdc1302ab484282b0d43e014 Author: Prasanna Santhanam Date: Tue May 7 13:50:12 2013 +0530 dedicateGuestVlanRange is admin only API Adding ACL for the dedicateGuestVlanRange API. Signed-off-by: Prasanna Santhanam commit 1c4c80fe91c7aeec0689fa9a06ae80d2bdf1b0c0 Author: Hugo Trippaers Date: Tue May 7 09:58:16 2013 +0200 Recent pom switcharoo caused the client to lose the dependecy on console-proxy, which it needs to include the systemvm commit 8103f3c386a8f57c520388ea73965a4cb7f15b91 Author: Radhika PC Date: Tue May 7 11:30:17 2013 +0530 CLOUDSTACK-893 first cut commit 67d0411d739417aae4910251e86981e6d1340da0 Author: Dave Cahill Date: Fri Apr 19 17:31:44 2013 +0900 Add docs for MidoNet networking plugin [CLOUDSTACK-996] Signed-off-by: Dave Cahill commit c745e6d28e63ef1cacdf18a98ce47d162d260978 Author: Alex Huang Date: Mon May 6 16:34:03 2013 -0700 Fixed up the simulator to run with windows paths in cygwin commit be91c037021ad17f16b22599acbdd46062a665a8 Author: Alex Huang Date: Mon May 6 10:34:22 2013 -0700 Moved over the VLAN daos commit dcc09f8472d4c94cebae5b430b7eb983037a9935 Author: Alex Huang Date: Mon May 6 06:31:47 2013 -0700 Missing file and updated .gitignore commit e9953cd1a8b1247ce569d22ffa820f51d072c841 Author: Alex Huang Date: Mon May 6 06:29:59 2013 -0700 Fixed up unit testing to use only an in class TestConfiguration commit 67275714035ea2a55c11ee7acf1e915598670845 Author: Alex Huang Date: Thu May 2 15:20:49 2013 -0700 Fixed an incorrect unit test for affinity group. Removed some useless pom.xml. commit d015fb352023a5d2ec07b4d66612836e0a928679 Author: Alex Huang Date: Thu May 2 06:50:38 2013 -0700 Moved most of the VOs and DAOs from server package into engine-schema as well commit 77547a58df5f529031516273015bb770717c5b88 Author: Alex Huang Date: Wed May 1 15:15:57 2013 -0700 Removed files that are no longer used and further separated out the files in the core project commit 345f3d34828a9b573971104cbb6132a777a58ed4 Author: Alex Huang Date: Wed May 1 05:46:15 2013 -0700 Moved agent commands to core and out of api commit e91ca00571ddf078150165a33cd3cbcee5564fe2 Author: Alex Huang Date: Tue Apr 30 19:06:20 2013 -0700 Removed framework-api which is completely useless. Changed framework-ipc to reference gson itself. Move VOs into engine-schema. commit f64564e49001ee0f52120a10665979887fd0ebd1 Author: Dennis Lawler Date: Mon Apr 29 15:10:09 2013 -0700 Removing filterwin2k option Signed-off-by: Chiradeep Vittal commit 944a7ea5d6e6728903074ec18754ce2041aaf7a3 Author: Wei Zhou Date: Mon May 6 20:57:02 2013 +0100 CLOUDSTACK-2319: fix "unable to add egress rules" in SecurityGroup Signed-off-by: Chip Childers commit ff7f8ba3623927b6cef2deb0069e7f839d933fd5 Author: Wei Zhou Date: Mon May 6 20:56:06 2013 +0100 CLOUDSTACK-2322: update network.gateway to fix deployVm error on SharedNetwork after ipv6 support Signed-off-by: Chip Childers commit a153373c7eade440c707bfaeeb9831f8179ab51a Author: Alena Prokharchyk Date: Mon May 6 11:45:19 2013 -0700 CLOUDSTACK-129: added new API - listNetworkIsolationMethods - for displaying isolation methods supported by the cloudStack commit 46f59cd49effc43ffea610cc5b7cab90f601b011 Author: Prasanna Santhanam Date: Mon May 6 20:39:36 2013 +0530 Fixed the incorrect assertion in noncontiguous_vlan test The assertion fails if the VLAN is found in which case find returns a positive number. So here the assertion should infact assert < 0 result. Signed-off-by: Prasanna Santhanam commit bd1dcc10b381b33ab5503f42075999365197168b Author: Prasanna Santhanam Date: Mon May 6 19:53:42 2013 +0530 Affinity Groups requires multiple storage pools Fixing the affinity group test which would fail to find the appropriate storage pool to satisfy the anti-affinity group of the second VM Signed-off-by: Prasanna Santhanam commit 7f853cdb8f8074408205f38c5e63c2dce187b40b Author: Prasanna Santhanam Date: Mon May 6 19:16:15 2013 +0530 fixing double calls to VM deploy This fixes regression introduced in commit 2f40a90c that made duplicate calls to deployVirtualMachine. Signed-off-by: Prasanna Santhanam commit 646e810fcf0f2c0c3fac02a37eb4301fd913b008 Author: Prasanna Santhanam Date: Mon May 6 18:51:53 2013 +0530 fixing wildcard imports Signed-off-by: Prasanna Santhanam commit b29b6e8525ed367cb6f481c7eb116abe1fb847a2 Author: Hugo Trippaers Date: Fri May 3 14:03:53 2013 +0200 BigSwitch should only respond if it is the actual provider on the network. This fixes an NPE during the release call. commit 6fcc9b009b5609756fd5195847557b56f9642ecd Author: Hugo Trippaers Date: Thu May 2 17:38:27 2013 +0200 Prevent Nicira NVP tags from exceeding the 40 character limit. commit d8e61a1c0a02cef67377f1fd1f638d77652edecf Author: Sanjay Tripathi Date: Thu May 2 13:45:39 2013 +0530 CLOUDSTACK-2188 : Parsing error with Download Monitor while checking the health of downloaded templates Signed-off-by: Sateesh Chodapuneedi commit 5b6e1140f90b4625d02b9a0bb035342139c1b6f4 Author: Sebastien Goasguen Date: Mon May 6 05:35:58 2013 -0400 CLOUDSTACK-2339: Adding libcloud example commit 7be62d2374ef5910728627b583ac33498ad7fdce Author: Sebastien Goasguen Date: Mon May 6 05:35:19 2013 -0400 CLOUDSTACK-2338: Adding example of how to sign api requests in python commit 156fd689026ca23e583fa32e5013183e13086a57 Author: Talluri Date: Fri May 3 23:11:56 2013 +0530 CLOUDSTACK-2323: fix test scripts to conform with library changes Signed-off-by: Prasanna Santhanam commit 33ff5e91079b262562b17701d5266bcfd2674ffd Author: sanjeevneelarapu Date: Tue Apr 30 20:09:46 2013 +0530 CLOUDSTACK-702: Tests for Multiple IP Ranges 1.Deleting IP Range from the existing CIDR 2.Add non-contiguous guest IP range in new CIDR 3.Add overlapped guest IP range in existing CIDR Signed-off-by: sanjeevneelarapu Signed-off-by: Prasanna Santhanam commit 33059d1f66fdc7d925f6b087a97912b8bc4598d5 Author: Pranav Saxena Date: Mon May 6 14:08:40 2013 +0530 scaleUp VM response change corresponding UI changes commit 92e18d81060a9e766e1cfce3f41bbd6ddd6d5ff5 Author: Pranav Saxena Date: Mon May 6 13:45:32 2013 +0530 CLOUDSTACK-2337:Resize button available for root/domain admin and normal users commit d5cd3f7e006d688d052f7fe797180753dae989e7 Author: Likitha Shetty Date: Wed May 1 13:47:26 2013 +0530 Dedicate guest vlan range to account commit 12c79c8377d45df2ccec217bbcb9023840a2c064 Author: Pranav Saxena Date: Sun May 5 12:02:32 2013 +0530 scale up virtual machine response change in the backend commit 94bac276228fb2ede08de063e1b789d917c8425f Author: Rohit Yadav Date: Sun May 5 09:58:04 2013 +0530 appliance: Upgrade systemvm appliance from rc1 to Debian7 GA Signed-off-by: Rohit Yadav commit c598bb0038750c18223115026774c56de1366696 Author: Isaac Chiang Date: Sun May 5 01:57:35 2013 +0530 CLOUDSTACK-2076:Listview widget infinte scrolling error commit d0615ea9a1560b7330066544f5ddf4d5c2713f70 Author: Pranav Saxena Date: Sun May 5 01:15:14 2013 +0530 CLOUDSTACK-2274:Detail view loading problem when deleting a zone commit 733b513c3ac10dadf33f187d29651494197678b4 Author: Isaac Chiang Date: Sat May 4 13:41:02 2013 +0530 CLOUDSTACK-2160:Refresh button functionality for security groups and statistics tab commit 418d75d7a4dd4f9785846e3ecbe9f0135d751fe3 Author: Marcus Sorensen Date: Fri May 3 14:09:52 2013 -0600 Summary: Release old DHCP entries Detail: Refresh dnsmasq with updated entries live, no outage BUG-ID: CLOUDSTACK-2299 Submitted-by: Dennis Lawler Signed-off-by: Marcus Sorensen 1367611792 -0600 commit b3dce6457739c0f737ed8f2f61ad108bfee13eba Author: Kelven Yang Date: Tue May 7 10:57:19 2013 -0700 fix unitest commit b17885f0f68affe060a95e3f264b9ac5e3a98a4b Author: Alena Prokharchyk Date: Tue May 7 09:55:47 2013 -0700 InternalLb: some fixes to the unittest commit 1cff609347eed3fb3a5e2e3a76b2f36404ea0b81 Merge: 053e184 a3a5c13 Author: Alena Prokharchyk Date: Fri May 3 11:23:08 2013 -0700 Merge branch 'master' into internallb1 Conflicts: server/src/com/cloud/network/NetworkModelImpl.java server/src/com/cloud/network/NetworkServiceImpl.java server/src/com/cloud/server/ManagementServerImpl.java server/test/com/cloud/network/MockNetworkManagerImpl.java server/test/com/cloud/vpc/MockNetworkManagerImpl.java commit 053e18454d105e9785768123259bacc48383bcea Author: Alena Prokharchyk Date: Fri May 3 11:07:07 2013 -0700 InternalLB: marvin integration test for internal lb feature commit 2e8e2f98f59eecfc37a2645bd353de7f592d8149 Author: Alena Prokharchyk Date: Wed May 1 13:53:20 2013 -0700 InternalLB: don't allow to upgrade the network from the network offering with internal LB to the offering with public LB, and vice versa commit c773d204c8e3b4715b3466f732bdff3100f58cfe Author: Chiradeep Vittal Date: Wed May 1 13:21:52 2013 -0700 Internal LB: if we detect that we are inside an internal lb vm, call out to the ilb script to perform LB configuration Signed-off-by: Chiradeep Vittal commit 8c8845bf77f1258e54998f509df6163df82ce24e Merge: 7e95545 471ca30 Author: Alena Prokharchyk Date: Wed May 1 10:14:06 2013 -0700 Merge branch 'master' into internallb1 commit 7e9554596f3d0e1d68ada880c2c17c01a526b0f5 Author: Alena Prokharchyk Date: Wed May 1 10:01:16 2013 -0700 InternalLb: boot args parameters cleanup for the internal lb vm commit b7cf8700749893abcac1d3a3d20ec32c4cb5d37f Author: Alena Prokharchyk Date: Tue Apr 30 10:31:28 2013 -0700 InternalLb: more unittests for internal lb element commit 63bb98ebe2fa8279138f8b32aa4264b547726224 Author: Chiradeep Vittal Date: Mon Apr 29 18:29:25 2013 -0700 allow ssh on eth1 Signed-off-by: Chiradeep Vittal commit ca1c313c2901a2ce1e7e6e3ce3a566bbf4c817b4 Author: Alena Prokharchyk Date: Mon Apr 29 17:58:45 2013 -0700 InternalLb: DB upgrade - update existing physical networks with InternalLbVm provider commit ed50caa01c12320c4fa5ff7d4e0818840a6c764d Author: Alena Prokharchyk Date: Mon Apr 29 17:48:36 2013 -0700 InternalLbVM: handle the scenario when sourceIpAddress is not passed when create internal Lb rule commit 4c22c911a9ca5d7e05e9eaf0e971cbe56345fa52 Author: Chiradeep Vittal Date: Mon Apr 29 15:56:00 2013 -0700 backend support for Internal LB Signed-off-by: Chiradeep Vittal commit 7b24a7640c53e5b5ab4493de309b43714f4646c6 Merge: 440e848 a0dbf89 Author: Alena Prokharchyk Date: Mon Apr 29 15:49:48 2013 -0700 Merge branch 'master' into internallb1 Conflicts: server/src/com/cloud/api/ApiResponseHelper.java server/src/com/cloud/api/query/QueryManagerImpl.java server/src/com/cloud/configuration/ConfigurationManagerImpl.java server/src/com/cloud/network/NetworkManagerImpl.java server/src/com/cloud/network/firewall/FirewallManagerImpl.java setup/db/db/schema-410to420.sql commit 440e8484d66e3e0366b6d61f930fa13a07d0ce5f Author: Alena Prokharchyk Date: Mon Apr 29 13:27:06 2013 -0700 InternalLB: unittests for InternalLoadBalancerVMManager commit 63babe4b7e8baa1027ac66a7d0b505caafc36d5e Author: Alena Prokharchyk Date: Fri Apr 26 13:44:01 2013 -0700 InternalLb: 1) Added unittests for InternalLoadBalancerVMService 2) Added unittests for InternalLoadBalancerElementService commit 4f9c47ce54915f9c9eb8042936f3a1b19553399d Author: Alena Prokharchyk Date: Thu Apr 25 14:46:42 2013 -0700 InternalLb: create internal lb vm specific service offering commit 408ee59d1fe64ce5d6a5e57b76e25cc505fda5dc Author: Alena Prokharchyk Date: Wed Apr 24 17:08:08 2013 -0700 Internallb: new set of Web services APIs for managing Internal LB VMs commit 7680e1cc10b4e48be78668b31ba1af44d1528a67 Author: Alena Prokharchyk Date: Wed Apr 24 17:08:08 2013 -0700 Internallb: 1) InternalLb and PublicLb can't be enabled on the same network offering 2) Can have internalLb only on VPC tier commit d73ca7ef73ce8f16cd355e48a96c0fc35b037fed Author: Alena Prokharchyk Date: Wed Apr 24 13:02:32 2013 -0700 InternalLb: 1) fixed the bug when the guest nic on internal lb vm wasnt set to be default 2) Don't send the rules to the internal lb vm if its in Stopped state commit ca2fc30655eace01857181ac50789a6632f51d29 Merge: 8057567 04a2b2d Author: Alena Prokharchyk Date: Tue Apr 23 16:56:11 2013 -0700 Merge branch 'master' into internallb1 Conflicts: server/src/com/cloud/network/vpc/VpcManagerImpl.java server/src/com/cloud/server/ManagementServerImpl.java setup/db/db/schema-410to420.sql commit 8057567aaab5000b2f6d3aec8ace65631092adc1 Author: Alena Prokharchyk Date: Tue Apr 23 13:15:36 2013 -0700 Internallb: more unittests for ApplicationLoadBalancerService commit 35c0273b857073a7018fb1a59a33f43f6f112a9c Author: Alena Prokharchyk Date: Fri Apr 19 16:17:45 2013 -0700 InternalLb: unittests for ApplicationLoadBalancerService commit 69b23f700348a56f97bc2118166799332a47b3a5 Author: Alena Prokharchyk Date: Thu Apr 18 14:01:10 2013 -0700 InternalLb: create/configure/listInternalLoadBalancerElement - fixes to the API response commit a3321ce617eab795288ab75357345d45794db93d Author: Alena Prokharchyk Date: Thu Apr 18 13:31:16 2013 -0700 Internal LB : renamed the classes responsible for managing internal lb elements. Now the names are InternalLoadBalancerVMManager, InternalLoadBalancerVMService and InternalLoadBalancerVMManagerImpl commit 2baf7c365c4847ae49cd90ee25d4e3d7d346464d Author: Alena Prokharchyk Date: Thu Apr 18 10:02:17 2013 -0700 Internallb: verify requested IP for LB rule (if specified) against guest network cidr commit 0cfe96bd00a79ccb9ddebed760c6dde257599074 Merge: 501f2ff 11162f5 Author: Alena Prokharchyk Date: Wed Apr 17 15:41:51 2013 -0700 Merge branch 'master' into internallb1 Conflicts: api/src/com/cloud/network/IpAddress.java server/src/com/cloud/network/NetworkServiceImpl.java setup/db/db/schema-410to420.sql commit 501f2ffa0b07e80c17e4d6f7a73721d034c8e46a Author: Alena Prokharchyk Date: Tue Apr 16 17:03:50 2013 -0700 InternalLb: validate source ip network as a part of LB rule creation commit 4d9a7dfd85f010918749dfe3166d75fe4db68d90 Author: Alena Prokharchyk Date: Tue Apr 16 16:03:32 2013 -0700 InternalLB: in VPC, restrict public LB to one tier only. Internal LB can be supported on multiple tiers commit 8689bf9eb38a416997d5ae4d326c51b57b57553e Author: Alena Prokharchyk Date: Tue Apr 16 15:59:56 2013 -0700 Internal LB: added internal lb vm to the list of supported providers in VPC default offering commit b7709b89ff94a7c1eeb0e6dff0eca6220a0aed25 Author: Alena Prokharchyk Date: Tue Apr 16 11:04:22 2013 -0700 Internal Lb: added 2 boolean fields - internal_lb and public_lb - to the network offering. Define if internal or public LB service is supported. In the current release it's either one or another; in the future releases we might support both on the same network commit 014689e45eeaedd9b695ec20dfb2db631f433e14 Merge: b3b16ba 90e8158 Author: Alena Prokharchyk Date: Tue Apr 16 09:55:45 2013 -0700 Merge branch 'master' into internallb1 Conflicts: api/src/com/cloud/network/Network.java plugins/network-elements/f5/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java server/src/com/cloud/network/NetworkManagerImpl.java server/src/com/cloud/network/NetworkServiceImpl.java server/test/com/cloud/network/MockNetworkManagerImpl.java server/test/com/cloud/vpc/MockNetworkManagerImpl.java setup/db/db/schema-410to420.sql commit b3b16bae48976c027e3439f2e0a84cfb2cb72166 Author: Alena Prokharchyk Date: Mon Apr 15 17:00:31 2013 -0700 InternalLB: allow to specify more than one provider for the LB service when create network offering as diff providers can support internal and public LB for the same network commit a4fc1d7d65191da6a49bce9fa0a64ce6e46ac85d Author: Alena Prokharchyk Date: Mon Apr 15 13:45:25 2013 -0700 Internal LB: 1) Added network_offering_details DB table and corresponding VO/DAO objects. Change createNetworkOffering web services api to accept the map of key/value pairs as details. 2) Allow to have multiple providers for the same service for the network to support the case when LB service can have separate providers for Internal LB and Public LB commit 4530cebf2bef515f86fa29b3798d51e81089f92f Author: Alena Prokharchyk Date: Mon Apr 15 10:06:10 2013 -0700 InternalLbVm: support for start/stop Internal lb vm commit ae69f0ae5612834b8bc911bd074cfb050c0b164c Author: Alena Prokharchyk Date: Fri Apr 12 17:25:02 2013 -0700 InternalLb: fixed prepare() in InternalLbElement - have to prepare nics of User vms only commit 888a83c22111f3792850e6bb6235d30a93408d1d Author: Alena Prokharchyk Date: Fri Apr 12 15:58:27 2013 -0700 InternalLb: Start/deploy internal LB vms for the existing LB rules as a part of network implement commit 3b41d5bee1ac04d3e9cf837a2be4398b7597d1a0 Merge: bb73531 4b1a9f1 Author: Alena Prokharchyk Date: Fri Apr 12 15:32:40 2013 -0700 Merge branch 'master' into internallb1 Conflicts: server/src/com/cloud/network/NetworkModelImpl.java server/src/com/cloud/server/ManagementServerImpl.java commit bb73531fed72cc81012624fd3bae5ec22d23daa2 Author: Alena Prokharchyk Date: Fri Apr 12 15:13:55 2013 -0700 Internal Lb: list internal lb vms as a part of listRouters response. Introduced new parameter - role (can be virtual_router or internal_lb_vm) commit c113ea184b575ccae5d2be411c5bbc345473e35e Author: Alena Prokharchyk Date: Fri Apr 12 12:00:09 2013 -0700 Add Internal Lb Provider/Element as a part of adding a physical network commit 78c9db79dae3bc38699050b05baae32fd02204f6 Author: Alena Prokharchyk Date: Fri Apr 12 10:05:28 2013 -0700 InternalLbVm: destroy the internal lb vm when the last rule for the ip is being revoked commit af6201257b28a0d9177330c8c76b0ec979725870 Author: Alena Prokharchyk Date: Thu Apr 11 16:55:37 2013 -0700 Internal LB: fixed some bugs in internal lb vm startup process commit 1db240c2b668e6cbbea4e09979c34d84fe54a624 Author: Alena Prokharchyk Date: Thu Apr 11 14:23:55 2013 -0700 InternalLb: fixed searchCriteria constructor in ApplicationLoadBalancerDaoImpl commit 3795048fcc68ef23c24d82c9064946dfc082b1b6 Merge: f4c2b53 5f8a278 Author: Alena Prokharchyk Date: Thu Apr 11 14:09:31 2013 -0700 Merge branch 'master' into internallb1 Conflicts: api/src/com/cloud/async/AsyncJob.java api/src/org/apache/cloudstack/api/ApiConstants.java api/src/org/apache/cloudstack/api/BaseCmd.java api/src/org/apache/cloudstack/api/ResponseGenerator.java client/tomcatconf/commands.properties.in server/src/com/cloud/api/ApiDBUtils.java server/src/com/cloud/api/ApiResponseHelper.java server/src/com/cloud/server/ManagementServerImpl.java setup/db/db/schema-410to420.sql commit f4c2b53c218b2d11d510b9acc6baeb0d62042e5c Author: Alena Prokharchyk Date: Thu Apr 11 13:46:47 2013 -0700 InternalLB: modified InternalLbElement to start the Internal Lb vm for each ip address (if not already started) commit 76a4b1cf81610d931d6098ca94fa509c9ba2e274 Author: Alena Prokharchyk Date: Thu Apr 11 11:41:47 2013 -0700 InternalLB: added logic for acquiring guest ip address for the Internal LB rule commit 915e39fbaa9a6b6898e2aa13cbf8ef60a7b9d70e Author: Alena Prokharchyk Date: Thu Apr 11 10:19:18 2013 -0700 Removed unused methods doing ipAllocation from GuestNetworkGuru and NetworkServiceImpl. The correct method is located in NetworkModelImpl commit 3f2a62c7f62d23da23f65ff3842049243ef268e3 Merge: 20beb7a a0b5ebc Author: Alena Prokharchyk Date: Wed Apr 10 17:16:07 2013 -0700 Merge branch 'master' into internallb1 commit 20beb7a16c1a592cd7500148ea8988fe119d34fb Author: Alena Prokharchyk Date: Wed Apr 10 15:28:12 2013 -0700 Internal LB: applyLoadBalancerRules - put not null check for sourceIpAddressId (can be null when Schema is not Public) commit 87e5f5b9a6b006893ee30662fc06ea430e7b70dc Author: Alena Prokharchyk Date: Wed Apr 10 15:17:58 2013 -0700 Internal LB: intermediate checkin - added InternalLBAppliance manager and managerImpl commit 53b9c0d142bd2b99dd00c17987dcf5dc54e3ef56 Author: Alena Prokharchyk Date: Tue Apr 9 17:55:10 2013 -0700 Internal LB: added @Since to API docs for Internal LB related commands commit 867b305ea852dcbe224645dc4e5ffb950d8db8f7 Author: Alena Prokharchyk Date: Tue Apr 9 17:51:19 2013 -0700 Internal LB: Made InternalLbElement to extend the ip deployer as the LB service implements IPDeployerRequester commit 7b9af2809410132db451e48b7b829bf019512a92 Author: Alena Prokharchyk Date: Tue Apr 9 15:45:30 2013 -0700 InternalLb: new set of Web Services APIs to add InternalLB as a network element to the cloudStack (the element is packaged as an independent plugin). New APIs: 1) configureInternalLoadBalancerElement 2) createInternalLoadBalancerElement 3) listInternalLoadBalancerElements commit 039e303d4aec5618cc3914ee1a581d2f7b926e1c Author: Alena Prokharchyk Date: Tue Apr 9 14:01:11 2013 -0700 InternalLB: Modified pluggable service VirtualRouterElementService to accept only VirtualRouter and VpcVirtualRouter as a VirtualRouterProvider type when add/configure elements. Other VirtualRouterProviderTypes are are taken care by elb/internal lb plugins. commit f0018b451281bf02964dbe71d704c9a931783cae Author: Alena Prokharchyk Date: Tue Apr 9 12:56:42 2013 -0700 Internal LB: 1)Added InternalLoadBalancerManager and corresponding Impl 2)Add InternalLbVm as a default CS provider. DB upgrade is covered as well commit e344cf250af6a67a17f082f1c646e6ef5ce9a0a7 Author: Alena Prokharchyk Date: Mon Apr 8 16:57:47 2013 -0700 InternalLB - removed unused code from LoadBalancerDao commit 3588f468482e43181802730ed5a059897eb85458 Author: Alena Prokharchyk Date: Mon Apr 8 16:23:03 2013 -0700 Internal LB - added network-element plugin for internal lb service commit 76325e61681c7e191308b27514ba69e523cf12bd Author: Alena Prokharchyk Date: Mon Apr 8 13:58:08 2013 -0700 Internal Lb: 1) When network has both kinds of LB rules - Public and Internal - never send them in the same set to the provider 2) Added extra checks on the provider side to validate if the schema - Public or Internal - is supported. commit 56c2fe1d376c407a248fba789dd67ff36493a0ed Author: Alena Prokharchyk Date: Mon Apr 8 12:34:59 2013 -0700 InternalLB: 1) Added new capability for the LB service - LbSchemes. Can take 2 values - Internal and Public. 2) F5 and Netscaler LB providers - changes all LB related methods to accept LoadBalancingRule instead of ? extends FirewallRule. commit 34bcb2d026e1951f7b115d71830c69e1ad5ed89a Author: Alena Prokharchyk Date: Mon Apr 8 12:11:11 2013 -0700 InternalLB: implemented list/delete/create web services API commands that will be used for Internal LB creation commit 9ab31e11f7ebd431f9ebdf9d8582f5c126b14928 Author: Alena Prokharchyk Date: Fri Apr 5 15:59:55 2013 -0700 InternalLB: change LoadBalancingRule - reference sourceIpAddress of th load balancer by its value, not DB id commit 08f855d4e4b3888b3b4a163ce73c0e444b91e6b7 Author: Alena Prokharchyk Date: Thu Apr 4 09:26:21 2013 -0700 InternalLB: 1) Added new set of Interfaces - including the new VO - for the internal load balancer 2) DB change - added source_ip_address/source_ip_address_network_id/scheme (Internal/Public) fields to the load_balancer table --- api/src/com/cloud/async/AsyncJob.java | 2 + api/src/com/cloud/event/EventTypes.java | 24 +- api/src/com/cloud/network/IpAddress.java | 3 + api/src/com/cloud/network/Network.java | 19 +- api/src/com/cloud/network/NetworkModel.java | 7 + .../VirtualNetworkApplianceService.java | 2 + .../cloud/network/VirtualRouterProvider.java | 3 +- .../cloud/network/lb/LoadBalancingRule.java | 83 +- .../network/lb/LoadBalancingRulesService.java | 16 +- .../cloud/network/router/VirtualRouter.java | 2 +- .../com/cloud/network/rules/LoadBalancer.java | 10 +- .../network/rules/LoadBalancerContainer.java | 33 + .../com/cloud/offering/NetworkOffering.java | 11 + .../com/cloud/offering/ServiceOffering.java | 1 + api/src/com/cloud/vm/VirtualMachine.java | 3 +- .../apache/cloudstack/api/ApiConstants.java | 6 + .../org/apache/cloudstack/api/BaseCmd.java | 7 + .../cloudstack/api/ResponseGenerator.java | 44 +- ...nfigureInternalLoadBalancerElementCmd.java | 114 +++ .../CreateInternalLoadBalancerElementCmd.java | 116 +++ .../internallb/ListInternalLBVMsCmd.java | 151 +++ .../ListInternalLoadBalancerElementsCmd.java | 99 ++ .../internallb/StartInternalLBVMCmd.java | 120 +++ .../admin/internallb/StopInternalLBVMCmd.java | 123 +++ .../network/CreateNetworkOfferingCmd.java | 15 +- .../router/CreateVirtualRouterElementCmd.java | 21 +- .../command/admin/router/ListRoutersCmd.java | 7 +- .../command/admin/router/StartRouterCmd.java | 10 +- .../command/admin/router/StopRouterCmd.java | 11 +- .../CreateApplicationLoadBalancerCmd.java | 218 ++++ .../CreateLoadBalancerRuleCmd.java | 6 +- .../DeleteApplicationLoadBalancerCmd.java | 116 +++ .../ListApplicationLoadBalancersCmd.java | 131 +++ ...plicationLoadBalancerInstanceResponse.java | 63 ++ .../ApplicationLoadBalancerResponse.java | 142 +++ .../ApplicationLoadBalancerRuleResponse.java | 51 + .../api/response/DomainRouterResponse.java | 13 +- .../InternalLoadBalancerElementResponse.java | 51 + .../api/response/NetworkOfferingResponse.java | 9 + .../VirtualRouterProviderResponse.java | 1 + .../InternalLoadBalancerElementService.java | 56 ++ .../lb/ApplicationLoadBalancerContainer.java | 28 + .../lb/ApplicationLoadBalancerRule.java | 24 + .../lb/ApplicationLoadBalancerService.java | 42 + .../lb/InternalLoadBalancerVMService.java | 34 + .../apache/cloudstack/query/QueryService.java | 3 + client/pom.xml | 5 + client/tomcatconf/applicationContext.xml.in | 9 +- client/tomcatconf/commands.properties.in | 16 + client/tomcatconf/componentContext.xml.in | 2 + .../tomcatconf/nonossComponentContext.xml.in | 2 + .../simulatorComponentContext.xml.in | 1 + .../cloud/network/dao/FirewallRulesDao.java | 1 - .../com/cloud/network/dao/IPAddressVO.java | 9 +- .../cloud/network/dao/LoadBalancerDao.java | 10 +- .../network/dao/LoadBalancerDaoImpl.java | 74 +- .../com/cloud/network/dao/LoadBalancerVO.java | 18 + .../network/dao/NetworkServiceMapDao.java | 1 + .../network/dao/NetworkServiceMapDaoImpl.java | 9 + .../src/com/cloud/network/dao/NetworkVO.java | 3 - .../cloud/network/rules/FirewallRuleVO.java | 2 - .../offerings/NetworkOfferingDetailsVO.java | 90 ++ .../cloud/offerings/NetworkOfferingVO.java | 44 +- .../offerings/dao/NetworkOfferingDao.java | 4 + .../offerings/dao/NetworkOfferingDaoImpl.java | 24 + .../dao/NetworkOfferingDetailsDao.java | 31 + .../dao/NetworkOfferingDetailsDaoImpl.java | 79 ++ .../cloud/upgrade/dao/Upgrade410to420.java | 95 +- .../schema/src/com/cloud/vm/dao/NicDao.java | 2 +- .../src/com/cloud/vm/dao/NicDaoImpl.java | 2 +- .../lb/ApplicationLoadBalancerRuleVO.java | 133 +++ .../dao/ApplicationLoadBalancerRuleDao.java | 35 + .../ApplicationLoadBalancerRuleDaoImpl.java | 115 +++ .../config/etc/init.d/cloud-early-config | 26 + .../debian/config/etc/iptables/iptables-ilbvm | 33 + .../debian/config/opt/cloud/bin/ilb.sh | 211 ++++ .../config/opt/cloud/bin/patchsystemvm.sh | 23 + .../config/opt/cloud/bin/vpc_loadbalancer.sh | 23 + .../element/ElasticLoadBalancerElement.java | 22 +- .../lb/ElasticLoadBalancerManager.java | 4 +- .../lb/ElasticLoadBalancerManagerImpl.java | 32 +- .../F5ExternalLoadBalancerElement.java | 87 +- .../internal-loadbalancer/pom.xml | 50 + .../element/InternalLoadBalancerElement.java | 548 ++++++++++ .../lb/InternalLoadBalancerVMManager.java | 90 ++ .../lb/InternalLoadBalancerVMManagerImpl.java | 951 ++++++++++++++++++ .../ElementChildTestConfiguration.java | 124 +++ .../InternalLbElementServiceTest.java | 190 ++++ .../InternalLbElementTest.java | 226 +++++ .../InternalLBVMManagerTest.java | 388 +++++++ .../InternalLBVMServiceTest.java | 291 ++++++ .../LbChildTestConfiguration.java | 170 ++++ .../test/resources/lb_element.xml | 46 + .../test/resources/lb_mgr.xml | 46 + .../test/resources/lb_svc.xml | 46 + .../network/element/NetscalerElement.java | 108 +- plugins/pom.xml | 1 + server/src/com/cloud/api/ApiDBUtils.java | 10 +- .../src/com/cloud/api/ApiResponseHelper.java | 108 +- .../com/cloud/api/query/QueryManagerImpl.java | 45 +- .../query/dao/DomainRouterJoinDaoImpl.java | 9 +- .../api/query/vo/DomainRouterJoinVO.java | 17 +- .../src/com/cloud/configuration/Config.java | 5 +- .../configuration/ConfigurationManager.java | 10 +- .../ConfigurationManagerImpl.java | 123 ++- .../ExternalLoadBalancerDeviceManager.java | 6 +- ...ExternalLoadBalancerDeviceManagerImpl.java | 33 +- .../ExternalLoadBalancerUsageManagerImpl.java | 34 +- .../src/com/cloud/network/NetworkManager.java | 3 +- .../com/cloud/network/NetworkManagerImpl.java | 103 +- .../com/cloud/network/NetworkModelImpl.java | 57 +- .../com/cloud/network/NetworkServiceImpl.java | 68 +- .../network/element/VirtualRouterElement.java | 56 +- .../network/firewall/FirewallManagerImpl.java | 77 +- .../cloud/network/guru/GuestNetworkGuru.java | 43 +- .../network/lb/LBHealthCheckManager.java | 4 +- .../network/lb/LBHealthCheckManagerImpl.java | 9 +- .../network/lb/LoadBalancingRulesManager.java | 24 +- .../lb/LoadBalancingRulesManagerImpl.java | 410 +++++--- .../VirtualNetworkApplianceManager.java | 4 + .../VirtualNetworkApplianceManagerImpl.java | 59 +- ...VpcVirtualNetworkApplianceManagerImpl.java | 2 +- .../com/cloud/network/vpc/VpcManagerImpl.java | 14 +- .../cloud/server/ConfigurationServerImpl.java | 14 +- .../cloud/server/ManagementServerImpl.java | 580 ++++++++--- .../ApplicationLoadBalancerManagerImpl.java | 524 ++++++++++ .../cloud/network/MockNetworkManagerImpl.java | 27 +- .../cloud/network/MockNetworkModelImpl.java | 17 + .../vpc/MockConfigurationManagerImpl.java | 2 +- .../com/cloud/vpc/MockNetworkManagerImpl.java | 56 +- .../com/cloud/vpc/MockNetworkModelImpl.java | 17 + ...MockVpcVirtualNetworkApplianceManager.java | 14 +- .../vpc/dao/MockNetworkOfferingDaoImpl.java | 12 +- .../vpc/dao/MockNetworkServiceMapDaoImpl.java | 6 + .../lb/ApplicationLoadBalancerTest.java | 292 ++++++ .../cloudstack/lb/ChildTestConfiguration.java | 103 ++ .../CreateNetworkOfferingTest.java | 21 +- server/test/resources/appLoadBalancer.xml | 43 + setup/db/db/schema-40to410.sql | 4 +- setup/db/db/schema-410to420.sql | 45 +- setup/dev/advanced.cfg | 4 + .../component/test_multiple_ip_ranges.py | 1 + .../smoke/test_guest_vlan_range.py | 15 + test/integration/smoke/test_internal_lb.py | 250 +++++ tools/apidoc/gen_toc.py | 1 + tools/marvin/marvin/deployDataCenter.py | 12 + .../marvin/sandbox/advanced/advanced_env.py | 5 + .../marvin/sandbox/advanced/sandbox.cfg | 209 ++++ ui/scripts/zoneWizard.js | 104 ++ 149 files changed, 9497 insertions(+), 817 deletions(-) create mode 100644 api/src/com/cloud/network/rules/LoadBalancerContainer.java create mode 100644 api/src/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java create mode 100644 api/src/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java create mode 100644 api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java create mode 100644 api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java create mode 100644 api/src/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java create mode 100644 api/src/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java create mode 100644 api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateApplicationLoadBalancerCmd.java create mode 100644 api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteApplicationLoadBalancerCmd.java create mode 100644 api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListApplicationLoadBalancersCmd.java create mode 100644 api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerInstanceResponse.java create mode 100644 api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerResponse.java create mode 100644 api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerRuleResponse.java create mode 100644 api/src/org/apache/cloudstack/api/response/InternalLoadBalancerElementResponse.java create mode 100644 api/src/org/apache/cloudstack/network/element/InternalLoadBalancerElementService.java create mode 100644 api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerContainer.java create mode 100644 api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerRule.java create mode 100644 api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerService.java create mode 100644 api/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMService.java create mode 100644 engine/schema/src/com/cloud/offerings/NetworkOfferingDetailsVO.java create mode 100644 engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDetailsDao.java create mode 100644 engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDetailsDaoImpl.java create mode 100644 engine/schema/src/org/apache/cloudstack/lb/ApplicationLoadBalancerRuleVO.java create mode 100644 engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDao.java create mode 100644 engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java create mode 100755 patches/systemvm/debian/config/etc/iptables/iptables-ilbvm create mode 100755 patches/systemvm/debian/config/opt/cloud/bin/ilb.sh create mode 100644 plugins/network-elements/internal-loadbalancer/pom.xml create mode 100644 plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java create mode 100644 plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManager.java create mode 100644 plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java create mode 100644 plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/ElementChildTestConfiguration.java create mode 100644 plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementServiceTest.java create mode 100644 plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementTest.java create mode 100644 plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/InternalLBVMManagerTest.java create mode 100644 plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/InternalLBVMServiceTest.java create mode 100644 plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/LbChildTestConfiguration.java create mode 100644 plugins/network-elements/internal-loadbalancer/test/resources/lb_element.xml create mode 100644 plugins/network-elements/internal-loadbalancer/test/resources/lb_mgr.xml create mode 100644 plugins/network-elements/internal-loadbalancer/test/resources/lb_svc.xml create mode 100644 server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java create mode 100644 server/test/org/apache/cloudstack/lb/ApplicationLoadBalancerTest.java create mode 100644 server/test/org/apache/cloudstack/lb/ChildTestConfiguration.java create mode 100644 server/test/resources/appLoadBalancer.xml create mode 100644 test/integration/smoke/test_internal_lb.py create mode 100644 tools/marvin/marvin/sandbox/advanced/sandbox.cfg diff --git a/api/src/com/cloud/async/AsyncJob.java b/api/src/com/cloud/async/AsyncJob.java index d384a7ad920..ccdc40620b7 100644 --- a/api/src/com/cloud/async/AsyncJob.java +++ b/api/src/com/cloud/async/AsyncJob.java @@ -50,7 +50,9 @@ public interface AsyncJob extends Identity, InternalIdentity { AutoScaleVmProfile, AutoScaleVmGroup, GlobalLoadBalancerRule, + LoadBalancerRule, AffinityGroup, + InternalLbVm, DedicatedGuestVlanRange } diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 26c40abb4fb..45a904e426c 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -16,6 +16,9 @@ // under the License. package com.cloud.event; +import java.util.HashMap; +import java.util.Map; + import com.cloud.configuration.Configuration; import com.cloud.dc.DataCenter; import com.cloud.dc.Pod; @@ -23,8 +26,18 @@ import com.cloud.dc.StorageNetworkIpRange; import com.cloud.dc.Vlan; import com.cloud.domain.Domain; import com.cloud.host.Host; -import com.cloud.network.*; -import com.cloud.network.as.*; +import com.cloud.network.GuestVlan; +import com.cloud.network.Network; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PhysicalNetworkTrafficType; +import com.cloud.network.PublicIpAddress; +import com.cloud.network.RemoteAccessVpn; +import com.cloud.network.as.AutoScaleCounter; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.network.as.Condition; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.LoadBalancer; import com.cloud.network.rules.StaticNat; @@ -43,9 +56,6 @@ import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.vm.VirtualMachine; -import java.util.HashMap; -import java.util.Map; - public class EventTypes { //map of Event and corresponding entity for which Event is applicable @@ -389,11 +399,15 @@ public class EventTypes { public static final String EVENT_AFFINITY_GROUP_ASSIGN = "AG.ASSIGN"; public static final String EVENT_AFFINITY_GROUP_REMOVE = "AG.REMOVE"; public static final String EVENT_VM_AFFINITY_GROUP_UPDATE = "VM.AG.UPDATE"; + + public static final String EVENT_INTERNAL_LB_VM_START = "INTERNALLBVM.START"; + public static final String EVENT_INTERNAL_LB_VM_STOP = "INTERNALLBVM.STOP"; // Dedicated guest vlan range public static final String EVENT_GUEST_VLAN_RANGE_DEDICATE = "GUESTVLANRANGE.DEDICATE"; public static final String EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE = "GUESTVLANRANGE.RELEASE"; + static { // TODO: need a way to force author adding event types to declare the entity details as well, with out braking diff --git a/api/src/com/cloud/network/IpAddress.java b/api/src/com/cloud/network/IpAddress.java index 71c9b4e0bf3..c48e8b97ca8 100644 --- a/api/src/com/cloud/network/IpAddress.java +++ b/api/src/com/cloud/network/IpAddress.java @@ -81,4 +81,7 @@ public interface IpAddress extends ControlledEntity, Identity, InternalIdentity Long getVpcId(); String getVmIp(); + + Long getNetworkId(); + } diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 4472dbacc53..fa062c6a694 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -16,18 +16,19 @@ // under the License. package com.cloud.network; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; import com.cloud.utils.fsm.StateMachine2; import com.cloud.utils.fsm.StateObject; -import org.apache.cloudstack.acl.ControlledEntity; -import org.apache.cloudstack.api.Identity; -import org.apache.cloudstack.api.InternalIdentity; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; /** * owned by an account. @@ -50,7 +51,7 @@ public interface Network extends ControlledEntity, StateObject, I Capability.MultipleIps, Capability.TrafficStatistics, Capability.SupportedTrafficDirection, Capability.SupportedEgressProtocols); public static final Service Lb = new Service("Lb", Capability.SupportedLBAlgorithms, Capability.SupportedLBIsolation, Capability.SupportedProtocols, Capability.TrafficStatistics, Capability.LoadBalancingSupportedIps, - Capability.SupportedStickinessMethods, Capability.ElasticLb); + Capability.SupportedStickinessMethods, Capability.ElasticLb, Capability.LbSchemes); public static final Service UserData = new Service("UserData"); public static final Service SourceNat = new Service("SourceNat", Capability.SupportedSourceNatTypes, Capability.RedundantRouter); public static final Service StaticNat = new Service("StaticNat", Capability.ElasticIp); @@ -124,6 +125,7 @@ public interface Network extends ControlledEntity, StateObject, I public static final Provider None = new Provider("None", false); // NiciraNvp is not an "External" provider, otherwise we get in trouble with NetworkServiceImpl.providersConfiguredForExternalNetworking public static final Provider NiciraNvp = new Provider("NiciraNvp", false); + public static final Provider InternalLbVm = new Provider("InternalLbVm", false); public static final Provider CiscoVnmc = new Provider("CiscoVnmc", true); private String name; @@ -177,6 +179,7 @@ public interface Network extends ControlledEntity, StateObject, I public static final Capability SupportedTrafficDirection = new Capability("SupportedTrafficDirection"); public static final Capability SupportedEgressProtocols = new Capability("SupportedEgressProtocols"); public static final Capability HealthCheckPolicy = new Capability("HealthCheckPolicy"); + public static final Capability LbSchemes = new Capability("LbSchemes"); private String name; diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java index 555a09fc53e..f84a8b0c76a 100644 --- a/api/src/com/cloud/network/NetworkModel.java +++ b/api/src/com/cloud/network/NetworkModel.java @@ -33,6 +33,7 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.element.NetworkElement; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.offering.NetworkOffering; +import com.cloud.offering.NetworkOffering.Detail; import com.cloud.user.Account; import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; @@ -264,5 +265,11 @@ public interface NetworkModel { Nic getPlaceholderNicForRouter(Network network, Long podId); + IpAddress getPublicIpAddress(String ipAddress, long zoneId); + + List getUsedIpsInNetwork(Network network); + + Map getNtwkOffDetails(long offId); + Networks.IsolationType[] listNetworkIsolationMethods(); } \ No newline at end of file diff --git a/api/src/com/cloud/network/VirtualNetworkApplianceService.java b/api/src/com/cloud/network/VirtualNetworkApplianceService.java index 250ecb24e91..58eead2af07 100644 --- a/api/src/com/cloud/network/VirtualNetworkApplianceService.java +++ b/api/src/com/cloud/network/VirtualNetworkApplianceService.java @@ -63,5 +63,7 @@ public interface VirtualNetworkApplianceService { VirtualRouter startRouter(long id) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException; VirtualRouter destroyRouter(long routerId, Account caller, Long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException; + + VirtualRouter findRouter(long routerId); } diff --git a/api/src/com/cloud/network/VirtualRouterProvider.java b/api/src/com/cloud/network/VirtualRouterProvider.java index ed6a2741ba0..f67686e6b08 100644 --- a/api/src/com/cloud/network/VirtualRouterProvider.java +++ b/api/src/com/cloud/network/VirtualRouterProvider.java @@ -23,7 +23,8 @@ public interface VirtualRouterProvider extends InternalIdentity, Identity { public enum VirtualRouterProviderType { VirtualRouter, ElasticLoadBalancerVm, - VPCVirtualRouter + VPCVirtualRouter, + InternalLbVm } public VirtualRouterProviderType getType(); diff --git a/api/src/com/cloud/network/lb/LoadBalancingRule.java b/api/src/com/cloud/network/lb/LoadBalancingRule.java index 3e11e8c7c2c..4b37782a8c7 100644 --- a/api/src/com/cloud/network/lb/LoadBalancingRule.java +++ b/api/src/com/cloud/network/lb/LoadBalancingRule.java @@ -25,111 +25,83 @@ import com.cloud.network.as.Condition; import com.cloud.network.as.Counter; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LoadBalancer; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.utils.Pair; +import com.cloud.utils.net.Ip; -public class LoadBalancingRule implements FirewallRule, LoadBalancer { +public class LoadBalancingRule { private LoadBalancer lb; + private Ip sourceIp; private List destinations; private List stickinessPolicies; private LbAutoScaleVmGroup autoScaleVmGroup; private List healthCheckPolicies; public LoadBalancingRule(LoadBalancer lb, List destinations, - List stickinessPolicies, List healthCheckPolicies) { + List stickinessPolicies, List healthCheckPolicies, Ip sourceIp) { this.lb = lb; this.destinations = destinations; this.stickinessPolicies = stickinessPolicies; this.healthCheckPolicies = healthCheckPolicies; + this.sourceIp = sourceIp; } - @Override public long getId() { return lb.getId(); } - @Override - public long getAccountId() { - return lb.getAccountId(); - } - - @Override - public long getDomainId() { - return lb.getDomainId(); - } - - @Override public String getName() { return lb.getName(); } - @Override public String getDescription() { return lb.getDescription(); } - @Override public int getDefaultPortStart() { return lb.getDefaultPortStart(); } - @Override public int getDefaultPortEnd() { return lb.getDefaultPortEnd(); } - @Override public String getAlgorithm() { return lb.getAlgorithm(); } - @Override public String getUuid() { return lb.getUuid(); } - @Override public String getXid() { return lb.getXid(); } - @Override - public Long getSourceIpAddressId() { - return lb.getSourceIpAddressId(); - } - - @Override public Integer getSourcePortStart() { return lb.getSourcePortStart(); } - @Override public Integer getSourcePortEnd() { return lb.getSourcePortEnd(); } - @Override public String getProtocol() { return lb.getProtocol(); } - @Override - public Purpose getPurpose() { - return Purpose.LoadBalancing; + public FirewallRule.Purpose getPurpose() { + return FirewallRule.Purpose.LoadBalancing; } - @Override - public State getState() { + public FirewallRule.State getState() { return lb.getState(); } - @Override public long getNetworkId() { return lb.getNetworkId(); } - public LoadBalancer getLb() { - return lb; - } public void setDestinations(List destinations) { this.destinations = destinations; @@ -287,36 +259,6 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer { } } - @Override - public Integer getIcmpCode() { - return null; - } - - @Override - public Integer getIcmpType() { - return null; - } - - @Override - public List getSourceCidrList() { - return null; - } - - @Override - public Long getRelated() { - return null; - } - - @Override - public TrafficType getTrafficType() { - return null; - } - - @Override - public FirewallRuleType getType() { - return FirewallRuleType.User; - } - public LbAutoScaleVmGroup getAutoScaleVmGroup() { return autoScaleVmGroup; } @@ -473,4 +415,11 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer { } } + public Ip getSourceIp() { + return sourceIp; + } + + public Scheme getScheme() { + return lb.getScheme(); + } } diff --git a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java index ed39bedaa6f..5fc41e34c34 100644 --- a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java +++ b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java @@ -17,10 +17,10 @@ package com.cloud.network.lb; import java.util.List; +import java.util.Map; import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd; import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd; -import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerRuleCmd; import org.apache.cloudstack.api.command.user.loadbalancer.ListLBHealthCheckPoliciesCmd; import org.apache.cloudstack.api.command.user.loadbalancer.ListLBStickinessPoliciesCmd; import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRuleInstancesCmd; @@ -30,12 +30,13 @@ import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRul import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; import com.cloud.network.rules.HealthCheckPolicy; import com.cloud.network.rules.LoadBalancer; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.rules.StickinessPolicy; import com.cloud.uservm.UserVm; import com.cloud.utils.Pair; +import com.cloud.utils.net.Ip; public interface LoadBalancingRulesService { @@ -49,7 +50,9 @@ public interface LoadBalancingRulesService { * @return the newly created LoadBalancerVO if successful, null otherwise * @throws InsufficientAddressCapacityException */ - LoadBalancer createLoadBalancerRule(CreateLoadBalancerRuleCmd lb, boolean openFirewall) throws NetworkRuleConflictException, InsufficientAddressCapacityException; + LoadBalancer createPublicLoadBalancerRule(String xId, String name, String description, + int srcPortStart, int srcPortEnd, int defPortStart, int defPortEnd, Long ipAddrId, String protocol, String algorithm, + long networkId, long lbOwnerId, boolean openFirewall) throws NetworkRuleConflictException, InsufficientAddressCapacityException; LoadBalancer updateLoadBalancerRule(UpdateLoadBalancerRuleCmd cmd); @@ -134,8 +137,9 @@ public interface LoadBalancingRulesService { List searchForLBHealthCheckPolicies(ListLBHealthCheckPoliciesCmd cmd); - List listByNetworkId(long networkId); - LoadBalancer findById(long LoadBalancer); - public void updateLBHealthChecks() throws ResourceUnavailableException; + + public void updateLBHealthChecks(Scheme scheme) throws ResourceUnavailableException; + + Map getLbInstances(long lbId); } diff --git a/api/src/com/cloud/network/router/VirtualRouter.java b/api/src/com/cloud/network/router/VirtualRouter.java index d7239dd3452..2311f489918 100755 --- a/api/src/com/cloud/network/router/VirtualRouter.java +++ b/api/src/com/cloud/network/router/VirtualRouter.java @@ -23,7 +23,7 @@ import com.cloud.vm.VirtualMachine; */ public interface VirtualRouter extends VirtualMachine { public enum Role { - VIRTUAL_ROUTER, LB + VIRTUAL_ROUTER, LB, INTERNAL_LB_VM } Role getRole(); boolean getIsRedundantRouter(); diff --git a/api/src/com/cloud/network/rules/LoadBalancer.java b/api/src/com/cloud/network/rules/LoadBalancer.java index ab6085aceb7..e6dadcaee97 100644 --- a/api/src/com/cloud/network/rules/LoadBalancer.java +++ b/api/src/com/cloud/network/rules/LoadBalancer.java @@ -19,16 +19,10 @@ package com.cloud.network.rules; /** * Definition for a LoadBalancer */ -public interface LoadBalancer extends FirewallRule { - - String getName(); - - String getDescription(); - +public interface LoadBalancer extends FirewallRule, LoadBalancerContainer { + int getDefaultPortStart(); int getDefaultPortEnd(); - String getAlgorithm(); - } diff --git a/api/src/com/cloud/network/rules/LoadBalancerContainer.java b/api/src/com/cloud/network/rules/LoadBalancerContainer.java new file mode 100644 index 00000000000..9d5ea595c9d --- /dev/null +++ b/api/src/com/cloud/network/rules/LoadBalancerContainer.java @@ -0,0 +1,33 @@ +// 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.rules; + +public interface LoadBalancerContainer { + + public enum Scheme { + Public, Internal; + } + + String getName(); + + String getDescription(); + + String getAlgorithm(); + + Scheme getScheme(); + +} diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index 6f0b9937854..72e2a2bbbab 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -16,6 +16,8 @@ // under the License. package com.cloud.offering; +import java.util.Map; + import org.apache.cloudstack.acl.InfrastructureEntity; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; @@ -38,6 +40,11 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, Disabled, Enabled } + + public enum Detail { + InternalLbProvider, + PublicLbProvider + } public final static String SystemPublicNetwork = "System-Public-Network"; public final static String SystemControlNetwork = "System-Control-Network"; @@ -116,5 +123,9 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, boolean isInline(); boolean getIsPersistent(); + + boolean getInternalLb(); + + boolean getPublicLb(); } diff --git a/api/src/com/cloud/offering/ServiceOffering.java b/api/src/com/cloud/offering/ServiceOffering.java index d6c215f42f0..165369c5e9b 100755 --- a/api/src/com/cloud/offering/ServiceOffering.java +++ b/api/src/com/cloud/offering/ServiceOffering.java @@ -30,6 +30,7 @@ public interface ServiceOffering extends InfrastructureEntity, InternalIdentity, public static final String ssvmDefaultOffUniqueName = "Cloud.com-SecondaryStorage"; public static final String routerDefaultOffUniqueName = "Cloud.Com-SoftwareRouter"; public static final String elbVmDefaultOffUniqueName = "Cloud.Com-ElasticLBVm"; + public static final String internalLbVmDefaultOffUniqueName = "Cloud.Com-InternalLBVm"; public enum StorageType { local, diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index 8f807d450c7..ce9add62469 100755 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -186,6 +186,7 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I SecondaryStorageVm, ElasticIpVm, ElasticLoadBalancerVm, + InternalLoadBalancerVm, /* * UserBareMetal is only used for selecting VirtualMachineGuru, there is no @@ -196,7 +197,7 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I public static boolean isSystemVM(VirtualMachine.Type vmtype) { if (DomainRouter.equals(vmtype) || ConsoleProxy.equals(vmtype) - || SecondaryStorageVm.equals(vmtype)) { + || SecondaryStorageVm.equals(vmtype) || InternalLoadBalancerVm.equals(vmtype)) { return true; } return false; diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index d57fe058d93..c76506afc10 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -480,6 +480,12 @@ public class ApiConstants { public static final String HEALTHCHECK_HEALTHY_THRESHOLD = "healthythreshold"; public static final String HEALTHCHECK_UNHEALTHY_THRESHOLD = "unhealthythreshold"; public static final String HEALTHCHECK_PINGPATH = "pingpath"; + public static final String SOURCE_PORT = "sourceport"; + public static final String INSTANCE_PORT = "instanceport"; + public static final String SOURCE_IP = "sourceipaddress"; + public static final String SOURCE_IP_NETWORK_ID = "sourceipaddressnetworkid"; + public static final String SCHEME = "scheme"; + public static final String PROVIDER_TYPE = "providertype"; public static final String AFFINITY_GROUP_IDS = "affinitygroupids"; public static final String AFFINITY_GROUP_NAMES = "affinitygroupnames"; public static final String ASA_INSIDE_PORT_PROFILE = "insideportprofile"; diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java index 48d18d029fb..8d66a8327f0 100644 --- a/api/src/org/apache/cloudstack/api/BaseCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseCmd.java @@ -28,6 +28,9 @@ import java.util.regex.Pattern; import javax.inject.Inject; import org.apache.cloudstack.affinity.AffinityGroupService; +import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; +import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService; +import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService; import org.apache.cloudstack.query.QueryService; import org.apache.cloudstack.usage.UsageService; import org.apache.log4j.Logger; @@ -139,7 +142,11 @@ public abstract class BaseCmd { @Inject public VMSnapshotService _vmSnapshotService; @Inject public DataStoreProviderApiService dataStoreProviderApiService; @Inject public VpcProvisioningService _vpcProvSvc; + @Inject public ApplicationLoadBalancerService _newLbSvc; + @Inject public ApplicationLoadBalancerService _appLbService; @Inject public AffinityGroupService _affinityGroupService; + @Inject public InternalLoadBalancerElementService _internalLbElementSvc; + @Inject public InternalLoadBalancerVMService _internalLbSvc; @Inject public NetworkModel _ntwkModel; public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException; diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index 3433003cbed..ab8f99583a8 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -19,14 +19,15 @@ package org.apache.cloudstack.api; import java.text.DecimalFormat; import java.util.EnumSet; import java.util.List; +import java.util.Map; -import com.cloud.vm.NicSecondaryIp; import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.ApiConstants.HostDetails; import org.apache.cloudstack.api.ApiConstants.VMDetails; import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd; import org.apache.cloudstack.api.response.AccountResponse; +import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse; import org.apache.cloudstack.api.response.AsyncJobResponse; import org.apache.cloudstack.api.response.AutoScalePolicyResponse; import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse; @@ -44,11 +45,15 @@ import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.ExtractResponse; import org.apache.cloudstack.api.response.FirewallResponse; import org.apache.cloudstack.api.response.FirewallRuleResponse; +import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse; import org.apache.cloudstack.api.response.GuestOSResponse; +import org.apache.cloudstack.api.response.GuestVlanRangeResponse; +import org.apache.cloudstack.api.response.HostForMigrationResponse; import org.apache.cloudstack.api.response.HostResponse; import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse; import org.apache.cloudstack.api.response.IPAddressResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; +import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse; import org.apache.cloudstack.api.response.IpForwardingRuleResponse; import org.apache.cloudstack.api.response.IsolationMethodResponse; import org.apache.cloudstack.api.response.LBHealthCheckResponse; @@ -84,6 +89,7 @@ import org.apache.cloudstack.api.response.SnapshotResponse; import org.apache.cloudstack.api.response.SnapshotScheduleResponse; import org.apache.cloudstack.api.response.StaticRouteResponse; import org.apache.cloudstack.api.response.StorageNetworkIpRangeResponse; +import org.apache.cloudstack.api.response.StoragePoolForMigrationResponse; import org.apache.cloudstack.api.response.StoragePoolResponse; import org.apache.cloudstack.api.response.SwiftResponse; import org.apache.cloudstack.api.response.SystemVmInstanceResponse; @@ -103,6 +109,7 @@ import org.apache.cloudstack.api.response.VpcOfferingResponse; import org.apache.cloudstack.api.response.VpcResponse; import org.apache.cloudstack.api.response.VpnUsersResponse; import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule; import org.apache.cloudstack.region.Region; import org.apache.cloudstack.usage.Usage; @@ -119,10 +126,25 @@ import com.cloud.domain.Domain; import com.cloud.event.Event; import com.cloud.host.Host; import com.cloud.hypervisor.HypervisorCapabilities; -import com.cloud.network.*; +import com.cloud.network.GuestVlan; +import com.cloud.network.IpAddress; +import com.cloud.network.Network; import com.cloud.network.Network.Service; import com.cloud.network.Networks.IsolationType; -import com.cloud.network.as.*; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PhysicalNetworkTrafficType; +import com.cloud.network.RemoteAccessVpn; +import com.cloud.network.Site2SiteCustomerGateway; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnGateway; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VpnUser; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.network.as.AutoScaleVmProfile; +import com.cloud.network.as.Condition; +import com.cloud.network.as.Counter; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.HealthCheckPolicy; @@ -145,7 +167,12 @@ import com.cloud.projects.ProjectAccount; import com.cloud.projects.ProjectInvitation; import com.cloud.region.ha.GlobalLoadBalancerRule; import com.cloud.server.ResourceTag; -import com.cloud.storage.*; +import com.cloud.storage.GuestOS; +import com.cloud.storage.S3; +import com.cloud.storage.Snapshot; +import com.cloud.storage.StoragePool; +import com.cloud.storage.Swift; +import com.cloud.storage.Volume; import com.cloud.storage.snapshot.SnapshotPolicy; import com.cloud.storage.snapshot.SnapshotSchedule; import com.cloud.template.VirtualMachineTemplate; @@ -153,11 +180,12 @@ import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.user.UserAccount; import com.cloud.uservm.UserVm; +import com.cloud.utils.net.Ip; import com.cloud.vm.InstanceGroup; import com.cloud.vm.Nic; -import com.cloud.vm.snapshot.VMSnapshot; +import com.cloud.vm.NicSecondaryIp; import com.cloud.vm.VirtualMachine; -import org.apache.cloudstack.api.response.*; +import com.cloud.vm.snapshot.VMSnapshot; public interface ResponseGenerator { UserResponse createUserResponse(UserAccount user); @@ -397,9 +425,13 @@ public interface ResponseGenerator { NicSecondaryIpResponse createSecondaryIPToNicResponse(NicSecondaryIp result); public NicResponse createNicResponse(Nic result); + ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb, Map lbInstances); + AffinityGroupResponse createAffinityGroupResponse(AffinityGroup group); Long getAffinityGroupId(String name, long entityOwnerId); + InternalLoadBalancerElementResponse createInternalLbElementResponse(VirtualRouterProvider result); + IsolationMethodResponse createIsolationMethodResponse(IsolationType method); } diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java new file mode 100644 index 00000000000..7c3d1e95e57 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.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.admin.internallb; + +import java.util.List; + +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; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse; +import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; +import org.apache.log4j.Logger; + +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@APICommand(name = "configureInternalLoadBalancerElement", responseObject=InternalLoadBalancerElementResponse.class, + description="Configures an Internal Load Balancer element.", since="4.2.0") +public class ConfigureInternalLoadBalancerElementCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(ConfigureInternalLoadBalancerElementCmd.class.getName()); + private static final String s_name = "configureinternalloadbalancerelementresponse"; + + @Inject + private List _service; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = InternalLoadBalancerElementResponse.class, + required=true, description="the ID of the internal lb provider") + private Long id; + + @Parameter(name=ApiConstants.ENABLED, type=CommandType.BOOLEAN, required=true, description="Enables/Disables the Internal Load Balancer element") + private Boolean enabled; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + public Long getId() { + return id; + } + + public Boolean getEnabled() { + return enabled; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_NETWORK_ELEMENT_CONFIGURE; + } + + @Override + public String getEventDescription() { + return "configuring internal load balancer element: " + id; + } + + @Override + public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException{ + s_logger.debug("hello alena"); + UserContext.current().setEventDetails("Internal load balancer element: " + id); + s_logger.debug("hello alena"); + VirtualRouterProvider result = _service.get(0).configureInternalLoadBalancerElement(getId(), getEnabled()); + s_logger.debug("hello alena"); + if (result != null){ + InternalLoadBalancerElementResponse routerResponse = _responseGenerator.createInternalLbElementResponse(result); + routerResponse.setResponseName(getCommandName()); + this.setResponseObject(routerResponse); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to configure the internal load balancer element"); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java new file mode 100644 index 00000000000..2902f7ae18a --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java @@ -0,0 +1,116 @@ +// 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.internallb; + +import java.util.List; + +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.BaseAsyncCreateCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse; +import org.apache.cloudstack.api.response.ProviderResponse; +import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; +import org.apache.log4j.Logger; + +import com.cloud.event.EventTypes; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@APICommand(name = "createInternalLoadBalancerElement", responseObject=InternalLoadBalancerElementResponse.class, description="Create an Internal Load Balancer element.",since="4.2.0") +public class CreateInternalLoadBalancerElementCmd extends BaseAsyncCreateCmd { + public static final Logger s_logger = Logger.getLogger(CreateInternalLoadBalancerElementCmd.class.getName()); + private static final String s_name = "createinternalloadbalancerelementresponse"; + + @Inject + private List _service; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.NETWORK_SERVICE_PROVIDER_ID, type=CommandType.UUID, entityType = ProviderResponse.class, required=true, description="the network service provider ID of the internal load balancer element") + private Long nspId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public void setNspId(Long nspId) { + this.nspId = nspId; + } + + public Long getNspId() { + return nspId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute(){ + UserContext.current().setEventDetails("Virtual router element Id: "+getEntityId()); + VirtualRouterProvider result = _service.get(0).getInternalLoadBalancerElement(getEntityId()); + if (result != null) { + InternalLoadBalancerElementResponse response = _responseGenerator.createInternalLbElementResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + }else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Virtual Router entity to physical network"); + } + } + + @Override + public void create() throws ResourceAllocationException { + VirtualRouterProvider result = _service.get(0).addInternalLoadBalancerElement(getNspId()); + if (result != null) { + setEntityId(result.getId()); + setEntityUuid(result.getUuid()); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Internal Load Balancer entity to physical network"); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_SERVICE_PROVIDER_CREATE; + } + + @Override + public String getEventDescription() { + return "Adding physical network element Internal Load Balancer: " + getEntityId(); + } +} diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java new file mode 100644 index 00000000000..e314b3245c7 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java @@ -0,0 +1,151 @@ +// 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.internallb; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.DomainRouterResponse; +import org.apache.cloudstack.api.response.HostResponse; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.api.response.PodResponse; +import org.apache.cloudstack.api.response.UserVmResponse; +import org.apache.cloudstack.api.response.VpcResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.log4j.Logger; + +import com.cloud.async.AsyncJob; +import com.cloud.network.router.VirtualRouter.Role; + +@APICommand(name = "listInternalLoadBalancerVMs", description="List internal LB VMs.", responseObject=DomainRouterResponse.class) +public class ListInternalLBVMsCmd extends BaseListProjectAndAccountResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListInternalLBVMsCmd.class.getName()); + + private static final String s_name = "listinternallbvmssresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.HOST_ID, type=CommandType.UUID, entityType=HostResponse.class, + description="the host ID of the Internal LB VM") + private Long hostId; + + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class, + description="the ID of the Internal LB VM") + private Long id; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the Internal LB VM") + private String routerName; + + @Parameter(name=ApiConstants.POD_ID, type=CommandType.UUID, entityType=PodResponse.class, + description="the Pod ID of the Internal LB VM") + private Long podId; + + @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="the state of the Internal LB VM") + private String state; + + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class, + description="the Zone ID of the Internal LB VM") + private Long zoneId; + + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, entityType=NetworkResponse.class, + description="list by network id") + private Long networkId; + + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.UUID, entityType=VpcResponse.class, + description="List Internal LB VMs by VPC") + private Long vpcId; + + @Parameter(name=ApiConstants.FOR_VPC, type=CommandType.BOOLEAN, description="if true is passed for this parameter, list only VPC Internal LB VMs") + private Boolean forVpc; + + @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") + private String zoneType; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getHostId() { + return hostId; + } + + public Long getId() { + return id; + } + + public String getRouterName() { + return routerName; + } + + public Long getPodId() { + return podId; + } + + public String getState() { + return state; + } + + public Long getZoneId() { + return zoneId; + } + + public Long getNetworkId() { + return networkId; + } + + public Long getVpcId() { + return vpcId; + } + + public Boolean getForVpc() { + return forVpc; + } + + public String getRole() { + return Role.INTERNAL_LB_VM.toString(); + } + + public String getZoneType() { + return zoneType; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.DomainRouter; + } + + @Override + public void execute(){ + ListResponse response = _queryService.searchForInternalLbVms(this); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } +} diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java new file mode 100644 index 00000000000..18536191995 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java @@ -0,0 +1,99 @@ +// 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.internallb; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseListCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.ProviderResponse; +import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; +import org.apache.log4j.Logger; + +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.VirtualRouterProvider; + +@APICommand(name = "listInternalLoadBalancerElements", description="Lists all available Internal Load Balancer elements.", + responseObject=InternalLoadBalancerElementResponse.class, since="4.2.0") +public class ListInternalLoadBalancerElementsCmd extends BaseListCmd { + public static final Logger s_logger = Logger.getLogger(ListInternalLoadBalancerElementsCmd.class.getName()); + private static final String _name = "listinternalloadbalancerelementsresponse"; + + @Inject + private InternalLoadBalancerElementService _service; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = InternalLoadBalancerElementResponse.class, + description="list internal load balancer elements by id") + private Long id; + + @Parameter(name=ApiConstants.NSP_ID, type=CommandType.UUID, entityType = ProviderResponse.class, + description="list internal load balancer elements by network service provider id") + private Long nspId; + + @Parameter(name=ApiConstants.ENABLED, type=CommandType.BOOLEAN, description="list internal load balancer elements by enabled state") + private Boolean enabled; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public Long getNspId() { + return nspId; + } + + public Boolean getEnabled() { + return enabled; + } + + @Override + public String getCommandName() { + return _name; + } + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + List providers = _service.searchForInternalLoadBalancerElements(getId(), getNspId(), getEnabled()); + ListResponse response = new ListResponse(); + List providerResponses = new ArrayList(); + for (VirtualRouterProvider provider : providers) { + InternalLoadBalancerElementResponse providerResponse = _responseGenerator.createInternalLbElementResponse(provider); + providerResponses.add(providerResponse); + } + response.setResponses(providerResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + + } +} diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java new file mode 100644 index 00000000000..31d132b5c9c --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java @@ -0,0 +1,120 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command.admin.internallb; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.DomainRouterResponse; +import org.apache.log4j.Logger; + +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.user.UserContext; + +@APICommand(name = "startInternalLoadBalancerVM", responseObject=DomainRouterResponse.class, description="Starts an existing internal lb vm.") +public class StartInternalLBVMCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(StartInternalLBVMCmd.class.getName()); + private static final String s_name = "startinternallbvmresponse"; + + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=DomainRouterResponse.class, + required=true, description="the ID of the internal lb vm") + private Long id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + public static String getResultObjectName() { + return "router"; + } + + @Override + public long getEntityOwnerId() { + VirtualRouter router = _entityMgr.findById(VirtualRouter.class, getId()); + if (router != null && router.getRole() == Role.INTERNAL_LB_VM) { + return router.getAccountId(); + } else { + throw new InvalidParameterValueException("Unable to find internal lb vm by id"); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_INTERNAL_LB_VM_START; + } + + @Override + public String getEventDescription() { + return "starting internal lb vm: " + getId(); + } + + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.InternalLbVm; + } + + public Long getInstanceId() { + return getId(); + } + + @Override + public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException{ + UserContext.current().setEventDetails("Internal Lb Vm Id: "+getId()); + VirtualRouter result = null; + VirtualRouter router = _routerService.findRouter(getId()); + if (router == null || router.getRole() != Role.INTERNAL_LB_VM) { + throw new InvalidParameterValueException("Can't find internal lb vm by id"); + } else { + result = _internalLbSvc.startInternalLbVm(getId(), UserContext.current().getCaller(), UserContext.current().getCallerUserId()); + } + + if (result != null){ + DomainRouterResponse routerResponse = _responseGenerator.createDomainRouterResponse(result); + routerResponse.setResponseName(getCommandName()); + this.setResponseObject(routerResponse); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to start internal lb vm"); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java new file mode 100644 index 00000000000..f40db49b417 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java @@ -0,0 +1,123 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command.admin.internallb; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.DomainRouterResponse; +import org.apache.log4j.Logger; + +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.user.UserContext; + +@APICommand(name = "stopInternalLoadBalancerVM", description = "Stops an Internal LB vm.", responseObject = DomainRouterResponse.class) +public class StopInternalLBVMCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(StopInternalLBVMCmd.class.getName()); + private static final String s_name = "stopinternallbvmresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, + required = true, description = "the ID of the internal lb vm") + private Long id; + + @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force stop the VM. The caller knows the VM is stopped.") + private Boolean forced; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + VirtualRouter vm = _entityMgr.findById(VirtualRouter.class, getId()); + if (vm != null && vm.getRole() == Role.INTERNAL_LB_VM) { + return vm.getAccountId(); + } else { + throw new InvalidParameterValueException("Unable to find internal lb vm by id"); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_INTERNAL_LB_VM_STOP; + } + + @Override + public String getEventDescription() { + return "stopping internal lb vm: " + getId(); + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.InternalLbVm; + } + + @Override + public Long getInstanceId() { + return getId(); + } + + public boolean isForced() { + return (forced != null) ? forced : false; + } + + @Override + public void execute() throws ConcurrentOperationException, ResourceUnavailableException { + UserContext.current().setEventDetails("Internal lb vm Id: "+getId()); + VirtualRouter result = null; + VirtualRouter vm = _routerService.findRouter(getId()); + if (vm == null || vm.getRole() != Role.INTERNAL_LB_VM) { + throw new InvalidParameterValueException("Can't find internal lb vm by id"); + } else { + result = _internalLbSvc.stopInternalLbVm(getId(), isForced(), UserContext.current().getCaller(), UserContext.current().getCallerUserId()); + } + + if (result != null) { + DomainRouterResponse response = _responseGenerator.createDomainRouterResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to stop internal lb vm"); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java index b48bf9e763e..6410715727c 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java @@ -31,7 +31,6 @@ import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.NetworkOfferingResponse; import org.apache.cloudstack.api.response.ServiceOfferingResponse; - import org.apache.log4j.Logger; import com.cloud.exception.InvalidParameterValueException; @@ -95,6 +94,10 @@ public class CreateNetworkOfferingCmd extends BaseCmd { @Parameter(name=ApiConstants.IS_PERSISTENT, type=CommandType.BOOLEAN, description="true if network offering supports persistent networks; defaulted to false if not specified") private Boolean isPersistent; + + @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, since="4.2.0", description="Template details in key/value pairs." + + " Supported keys are internallbprovider/publiclbprovider with service provider as a value") + protected Map details; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -215,6 +218,16 @@ public class CreateNetworkOfferingCmd extends BaseCmd { return capabilityMap; } + + public Map getDetails() { + if (details == null || details.isEmpty()) { + return null; + } + + Collection paramsCollection = details.values(); + Map params = (Map) (paramsCollection.toArray())[0]; + return params; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java index 39fac136233..b3fca5addf1 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java @@ -31,6 +31,7 @@ import org.apache.cloudstack.api.response.VirtualRouterProviderResponse; import org.apache.log4j.Logger; import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.network.VirtualRouterProvider; import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; @@ -52,6 +53,9 @@ public class CreateVirtualRouterElementCmd extends BaseAsyncCreateCmd { @Parameter(name=ApiConstants.NETWORK_SERVICE_PROVIDER_ID, type=CommandType.UUID, entityType = ProviderResponse.class, required=true, description="the network service provider ID of the virtual router element") private Long nspId; + + @Parameter(name=ApiConstants.PROVIDER_TYPE, type=CommandType.UUID, entityType = ProviderResponse.class, description="The provider type. Supported types are VirtualRouter (default) and VPCVirtualRouter") + private String providerType; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -61,16 +65,27 @@ public class CreateVirtualRouterElementCmd extends BaseAsyncCreateCmd { this.nspId = nspId; } - - public Long getNspId() { return nspId; } + + public VirtualRouterProviderType getProviderType() { + if (providerType != null) { + if (providerType.equalsIgnoreCase(VirtualRouterProviderType.VirtualRouter.toString())) { + return VirtualRouterProviderType.VirtualRouter; + } else if (providerType.equalsIgnoreCase(VirtualRouterProviderType.VPCVirtualRouter.toString())) { + return VirtualRouterProviderType.VPCVirtualRouter; + } else throw new InvalidParameterValueException("Invalid providerType specified"); + } + return VirtualRouterProviderType.VirtualRouter; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// + + @Override public String getCommandName() { return s_name; @@ -96,7 +111,7 @@ public class CreateVirtualRouterElementCmd extends BaseAsyncCreateCmd { @Override public void create() throws ResourceAllocationException { - VirtualRouterProvider result = _service.get(0).addElement(getNspId(), VirtualRouterProviderType.VirtualRouter); + VirtualRouterProvider result = _service.get(0).addElement(getNspId(), getProviderType()); if (result != null) { setEntityId(result.getId()); setEntityUuid(result.getUuid()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java index 9fbc9401532..78c3554ae73 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java @@ -31,6 +31,7 @@ import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.log4j.Logger; import com.cloud.async.AsyncJob; +import com.cloud.network.router.VirtualRouter.Role; @APICommand(name = "listRouters", description="List routers.", responseObject=DomainRouterResponse.class) public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { @@ -77,7 +78,7 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { @Parameter(name=ApiConstants.FOR_VPC, type=CommandType.BOOLEAN, description="if true is passed for this parameter, list only VPC routers") private Boolean forVpc; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -121,6 +122,10 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { public Boolean getForVpc() { return forVpc; } + + public String getRole() { + return Role.VIRTUAL_ROUTER.toString(); + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java index 1d3930b6b63..ad0461e0eb7 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java @@ -29,8 +29,10 @@ import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VirtualRouter.Role; import com.cloud.user.Account; import com.cloud.user.UserContext; @@ -100,7 +102,13 @@ public class StartRouterCmd extends BaseAsyncCmd { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException{ UserContext.current().setEventDetails("Router Id: "+getId()); - VirtualRouter result = _routerService.startRouter(id); + VirtualRouter result = null; + VirtualRouter router = _routerService.findRouter(getId()); + if (router == null || router.getRole() != Role.VIRTUAL_ROUTER) { + throw new InvalidParameterValueException("Can't find router by id"); + } else { + result = _routerService.startRouter(getId()); + } if (result != null){ DomainRouterResponse routerResponse = _responseGenerator.createDomainRouterResponse(result); routerResponse.setResponseName(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java index 60dd9386c75..94473cf9ffc 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java @@ -28,8 +28,10 @@ import org.apache.log4j.Logger; import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VirtualRouter.Role; import com.cloud.user.Account; import com.cloud.user.UserContext; @@ -103,7 +105,14 @@ public class StopRouterCmd extends BaseAsyncCmd { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException { UserContext.current().setEventDetails("Router Id: "+getId()); - VirtualRouter result = _routerService.stopRouter(getId(), isForced()); + VirtualRouter result = null; + VirtualRouter router = _routerService.findRouter(getId()); + if (router == null || router.getRole() != Role.VIRTUAL_ROUTER) { + throw new InvalidParameterValueException("Can't find router by id"); + } else { + result = _routerService.stopRouter(getId(), isForced()); + } + if (result != null) { DomainRouterResponse response = _responseGenerator.createDomainRouterResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateApplicationLoadBalancerCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateApplicationLoadBalancerCmd.java new file mode 100644 index 00000000000..17ae959aa6e --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateApplicationLoadBalancerCmd.java @@ -0,0 +1,218 @@ +// 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.user.loadbalancer; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCreateCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse; +import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule; +import org.apache.log4j.Logger; + +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; +import com.cloud.user.UserContext; +import com.cloud.utils.net.NetUtils; + +@APICommand(name = "createLoadBalancer", description="Creates a Load Balancer", responseObject=ApplicationLoadBalancerResponse.class, since="4.2.0") +public class CreateApplicationLoadBalancerCmd extends BaseAsyncCreateCmd { + public static final Logger s_logger = Logger.getLogger(CreateApplicationLoadBalancerCmd.class.getName()); + + private static final String s_name = "createloadbalancerresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="name of the Load Balancer") + private String loadBalancerName; + + @Parameter(name=ApiConstants.DESCRIPTION, type=CommandType.STRING, description="the description of the Load Balancer", length=4096) + private String description; + + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, required=true, entityType = NetworkResponse.class, + description="The guest network the Load Balancer will be created for") + private Long networkId; + + @Parameter(name=ApiConstants.SOURCE_PORT, type=CommandType.INTEGER, required=true, description="the source port the network traffic will be load balanced from") + private Integer sourcePort; + + @Parameter(name=ApiConstants.ALGORITHM, type=CommandType.STRING, required=true, description="load balancer algorithm (source, roundrobin, leastconn)") + private String algorithm; + + @Parameter(name=ApiConstants.INSTANCE_PORT, type=CommandType.INTEGER, required=true, description="the TCP port of the virtual machine where the network traffic will be load balanced to") + private Integer instancePort; + + @Parameter(name=ApiConstants.SOURCE_IP, type=CommandType.STRING, description="the source ip address the network traffic will be load balanced from") + private String sourceIp; + + @Parameter(name=ApiConstants.SOURCE_IP_NETWORK_ID, type=CommandType.UUID, entityType = NetworkResponse.class, required=true, + description="the network id of the source ip address") + private Long sourceIpNetworkId; + + @Parameter(name=ApiConstants.SCHEME, type=CommandType.STRING, required=true, description="the load balancer scheme. Supported value in this release is Internal") + private String scheme; + + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getAlgorithm() { + return algorithm; + } + + public String getDescription() { + return description; + } + + public String getLoadBalancerName() { + return loadBalancerName; + } + + public Integer getPrivatePort() { + return instancePort; + } + + public long getNetworkId() { + return networkId; + } + + public String getName() { + return loadBalancerName; + } + + public Integer getSourcePort() { + return sourcePort.intValue(); + } + + public String getProtocol() { + return NetUtils.TCP_PROTO; + } + + public long getAccountId() { + //get account info from the network object + Network ntwk = _networkService.getNetwork(networkId); + if (ntwk == null) { + throw new InvalidParameterValueException("Invalid network id specified"); + } + + return ntwk.getAccountId(); + + } + + public int getInstancePort() { + return instancePort.intValue(); + } + + @Override + public String getEventType() { + return EventTypes.EVENT_LOAD_BALANCER_CREATE; + } + + @Override + public String getEventDescription() { + return "creating load balancer: " + getName() + " account: " + getAccountId(); + + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.LoadBalancerRule; + } + + public String getSourceIp() { + return sourceIp; + } + + public long getSourceIpNetworkId() { + return sourceIpNetworkId; + } + + public Scheme getScheme() { + if (scheme.equalsIgnoreCase(Scheme.Internal.toString())) { + return Scheme.Internal; + } else { + throw new InvalidParameterValueException("Invalid value for scheme. Supported value is Internal"); + } + } + + @Override + public long getEntityOwnerId() { + return getAccountId(); + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute() throws ResourceAllocationException, ResourceUnavailableException { + ApplicationLoadBalancerRule rule = null; + try { + UserContext.current().setEventDetails("Load Balancer Id: " + getEntityId()); + // 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())); + setResponseObject(lbResponse); + lbResponse.setResponseName(getCommandName()); + } catch (Exception ex) { + s_logger.warn("Failed to create Load Balancer due to exception ", ex); + } finally { + if (rule == null) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create Load Balancer"); + } + } + } + + @Override + public void create() { + try { + + ApplicationLoadBalancerRule result = _appLbService.createApplicationLoadBalancer(getName(), getDescription(), getScheme(), + getSourceIpNetworkId(), getSourceIp(), getSourcePort(), getInstancePort(), getAlgorithm(), getNetworkId(), getEntityOwnerId()); + this.setEntityId(result.getId()); + this.setEntityUuid(result.getUuid()); + }catch (NetworkRuleConflictException e) { + s_logger.warn("Exception: ", e); + throw new ServerApiException(ApiErrorCode.NETWORK_RULE_CONFLICT_ERROR, e.getMessage()); + } catch (InsufficientAddressCapacityException e) { + s_logger.warn("Exception: ", e); + throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, e.getMessage()); + } catch (InsufficientVirtualNetworkCapcityException e) { + s_logger.warn("Exception: ", e); + throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, e.getMessage()); + } + } +} + diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java index 5f1d97b2803..f6cc1f130bd 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java @@ -148,7 +148,7 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements } - public Long getNetworkId() { + public long getNetworkId() { if (networkId != null) { return networkId; } @@ -278,7 +278,9 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command"); } try { - LoadBalancer result = _lbService.createLoadBalancerRule(this, getOpenFirewall()); + LoadBalancer result = _lbService.createPublicLoadBalancerRule(getXid(), getName(), getDescription(), + getSourcePortStart(), getSourcePortEnd(), getDefaultPortStart(), getDefaultPortEnd(), getSourceIpAddressId(), getProtocol(), getAlgorithm(), + getNetworkId(), getEntityOwnerId(), getOpenFirewall()); this.setEntityId(result.getId()); this.setEntityUuid(result.getUuid()); } catch (NetworkRuleConflictException e) { diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteApplicationLoadBalancerCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteApplicationLoadBalancerCmd.java new file mode 100644 index 00000000000..bc6cd09526c --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteApplicationLoadBalancerCmd.java @@ -0,0 +1,116 @@ +// 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.user.loadbalancer; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.FirewallRuleResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule; +import org.apache.log4j.Logger; + +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.user.UserContext; + +@APICommand(name = "deleteLoadBalancer", description="Deletes a load balancer", responseObject=SuccessResponse.class, since="4.2.0") +public class DeleteApplicationLoadBalancerCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeleteApplicationLoadBalancerCmd.class.getName()); + private static final String s_name = "deleteloadbalancerresponse"; + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = FirewallRuleResponse.class, + required=true, description="the ID of the Load Balancer") + private Long id; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + ApplicationLoadBalancerRule lb = _entityMgr.findById(ApplicationLoadBalancerRule.class, getId()); + if (lb != null) { + return lb.getAccountId(); + } else { + throw new InvalidParameterValueException("Can't find load balancer by id specified"); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_LOAD_BALANCER_DELETE; + } + + @Override + public String getEventDescription() { + return "deleting load balancer: " + getId(); + } + + @Override + public void execute(){ + UserContext.current().setEventDetails("Load balancer Id: " + getId()); + boolean result = _appLbService.deleteApplicationLoadBalancer(getId()); + + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete load balancer"); + } + } + + @Override + public String getSyncObjType() { + return BaseAsyncCmd.networkSyncObject; + } + + @Override + public Long getSyncObjId() { + ApplicationLoadBalancerRule lb = _appLbService.getApplicationLoadBalancer(id); + if(lb == null){ + throw new InvalidParameterValueException("Unable to find load balancer by id "); + } + return lb.getNetworkId(); + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.FirewallRule; + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListApplicationLoadBalancersCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListApplicationLoadBalancersCmd.java new file mode 100644 index 00000000000..8e5df31ed29 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListApplicationLoadBalancersCmd.java @@ -0,0 +1,131 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command.user.loadbalancer; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse; +import org.apache.cloudstack.api.response.FirewallRuleResponse; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule; +import org.apache.log4j.Logger; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; +import com.cloud.utils.Pair; + +@APICommand(name = "listLoadBalancers", description = "Lists Load Balancers", responseObject = ApplicationLoadBalancerResponse.class, since="4.2.0") +public class ListApplicationLoadBalancersCmd extends BaseListTaggedResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListApplicationLoadBalancersCmd.class.getName()); + + private static final String s_name = "listloadbalancerssresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = FirewallRuleResponse.class, + description = "the ID of the Load Balancer") + private Long id; + + @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the Load Balancer") + private String loadBalancerName; + + @Parameter(name = ApiConstants.SOURCE_IP, type = CommandType.STRING, description = "the source ip address of the Load Balancer") + private String sourceIp; + + @Parameter(name=ApiConstants.SOURCE_IP_NETWORK_ID, type=CommandType.UUID, entityType = NetworkResponse.class, + description="the network id of the source ip address") + private Long sourceIpNetworkId; + + @Parameter(name = ApiConstants.SCHEME, type = CommandType.STRING, description = "the scheme of the Load Balancer. Supported value is Internal in the current release") + private String scheme; + + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, entityType = NetworkResponse.class, + description="the network id of the Load Balancer") + private Long networkId; + + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public String getLoadBalancerRuleName() { + return loadBalancerName; + } + + public String getLoadBalancerName() { + return loadBalancerName; + } + + public String getSourceIp() { + return sourceIp; + } + + public Long getSourceIpNetworkId() { + return sourceIpNetworkId; + } + + @Override + public String getCommandName() { + return s_name; + } + + public Scheme getScheme() { + if (scheme != null) { + if (scheme.equalsIgnoreCase(Scheme.Internal.toString())) { + return Scheme.Internal; + } else { + throw new InvalidParameterValueException("Invalid value for scheme. Supported value is Internal"); + } + } + return null; + } + + public Long getNetworkId() { + return networkId; + } + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public void execute() { + Pair, Integer> loadBalancers = _appLbService.listApplicationLoadBalancers(this); + ListResponse response = new ListResponse(); + List lbResponses = new ArrayList(); + for (ApplicationLoadBalancerRule loadBalancer : loadBalancers.first()) { + ApplicationLoadBalancerResponse lbResponse = _responseGenerator.createLoadBalancerContainerReponse(loadBalancer, _lbService.getLbInstances(loadBalancer.getId())); + lbResponse.setObjectName("loadbalancer"); + lbResponses.add(lbResponse); + } + response.setResponses(lbResponses, loadBalancers.second()); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + +} diff --git a/api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerInstanceResponse.java b/api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerInstanceResponse.java new file mode 100644 index 00000000000..2d6614d217b --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerInstanceResponse.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 org.apache.cloudstack.api.response; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +/** + * + * Load Balancer instance is the User Vm instance participating in the Load Balancer + * + */ + +@SuppressWarnings("unused") +public class ApplicationLoadBalancerInstanceResponse extends BaseResponse{ + + @SerializedName(ApiConstants.ID) @Param(description = "the instance ID") + private String id; + + @SerializedName(ApiConstants.NAME) @Param(description = "the name of the instance") + private String name; + + @SerializedName(ApiConstants.STATE) @Param(description="the state of the instance") + private String state; + + @SerializedName(ApiConstants.IP_ADDRESS) + @Param(description="the ip address of the instance") + private String ipAddress; + + + public void setId(String id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setState(String state) { + this.state = state; + } + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } +} diff --git a/api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerResponse.java b/api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerResponse.java new file mode 100644 index 00000000000..de9bce6c658 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerResponse.java @@ -0,0 +1,142 @@ +// 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 java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("unused") +public class ApplicationLoadBalancerResponse extends BaseResponse implements ControlledEntityResponse{ + @SerializedName(ApiConstants.ID) @Param(description = "the Load Balancer ID") + private String id; + + @SerializedName(ApiConstants.NAME) @Param(description = "the name of the Load Balancer") + private String name; + + @SerializedName(ApiConstants.DESCRIPTION) @Param(description = "the description of the Load Balancer") + private String description; + + @SerializedName(ApiConstants.ALGORITHM) @Param(description = "the load balancer algorithm (source, roundrobin, leastconn)") + private String algorithm; + + @SerializedName(ApiConstants.NETWORK_ID) @Param(description="Load Balancer network id") + private String networkId; + + @SerializedName(ApiConstants.SOURCE_IP) @Param(description="Load Balancer source ip") + private String sourceIp; + + @SerializedName(ApiConstants.SOURCE_IP_NETWORK_ID) @Param(description="Load Balancer source ip network id") + private String sourceIpNetworkId; + + @SerializedName(ApiConstants.ACCOUNT) + @Param(description = "the account of the Load Balancer") + private String accountName; + + @SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id of the Load Balancer") + private String projectId; + + @SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the Load Balancer") + private String projectName; + + @SerializedName(ApiConstants.DOMAIN_ID) + @Param(description = "the domain ID of the Load Balancer") + private String domainId; + + @SerializedName(ApiConstants.DOMAIN) + @Param(description = "the domain of the Load Balancer") + private String domainName; + + @SerializedName("loadbalancerrule") @Param(description="the list of rules associated with the Load Balancer", responseObject = ApplicationLoadBalancerRuleResponse.class) + private List lbRules; + + @SerializedName("loadbalancerinstance") @Param(description="the list of instances associated with the Load Balancer", responseObject = ApplicationLoadBalancerInstanceResponse.class) + private List lbInstances; + + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with the Load Balancer", responseObject = ResourceTagResponse.class) + private List tags; + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + @Override + public void setDomainId(String domainId) { + this.domainId = domainId; + } + + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + @Override + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + @Override + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public void setId(String id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + public void setNetworkId(String networkId) { + this.networkId = networkId; + } + + public void setSourceIp(String sourceIp) { + this.sourceIp = sourceIp; + } + + public void setSourceIpNetworkId(String sourceIpNetworkId) { + this.sourceIpNetworkId = sourceIpNetworkId; + } + + public void setLbRules(List lbRules) { + this.lbRules = lbRules; + } + + public void setLbInstances(List lbInstances) { + this.lbInstances = lbInstances; + } +} diff --git a/api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerRuleResponse.java b/api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerRuleResponse.java new file mode 100644 index 00000000000..ffc64d5ca46 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerRuleResponse.java @@ -0,0 +1,51 @@ +// 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.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +/** + * Subobject of the load balancer container response + */ +@SuppressWarnings("unused") +public class ApplicationLoadBalancerRuleResponse extends BaseResponse{ + @SerializedName(ApiConstants.SOURCE_PORT) @Param(description = "source port of the load balancer rule") + private Integer sourcePort; + + @SerializedName(ApiConstants.INSTANCE_PORT) @Param(description = "instance port of the load balancer rule") + private Integer instancePort; + + @SerializedName(ApiConstants.STATE) @Param(description = "the state of the load balancer rule") + private String state; + + public void setSourcePort(Integer sourcePort) { + this.sourcePort = sourcePort; + } + + public void setInstancePort(Integer instancePort) { + this.instancePort = instancePort; + } + + public void setState(String state) { + this.state = state; + } +} diff --git a/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java b/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java index 79c8596a8d1..852d98815a3 100644 --- a/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java +++ b/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java @@ -153,8 +153,11 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView @SerializedName("scriptsversion") @Param(description="the version of scripts") private String scriptsVersion; - @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the network belongs to") + @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the router belongs to") private String vpcId; + + @SerializedName(ApiConstants.ROLE) @Param(description="role of the domain router") + private String role; @SerializedName("nic") @Param(description="the list of nics associated with the router", responseObject = NicResponse.class, since="4.0") @@ -164,15 +167,11 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView nics = new LinkedHashSet(); } - - @Override public String getObjectId() { return this.getId(); } - - public String getId() { return id; } @@ -372,4 +371,8 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView public void setIp6Dns2(String ip6Dns2) { this.ip6Dns2 = ip6Dns2; } + + public void setRole(String role) { + this.role = role; + } } diff --git a/api/src/org/apache/cloudstack/api/response/InternalLoadBalancerElementResponse.java b/api/src/org/apache/cloudstack/api/response/InternalLoadBalancerElementResponse.java new file mode 100644 index 00000000000..b7e8634ee8f --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/InternalLoadBalancerElementResponse.java @@ -0,0 +1,51 @@ +// 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.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; + +import com.cloud.network.VirtualRouterProvider; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +@EntityReference(value=VirtualRouterProvider.class) +@SuppressWarnings("unused") +public class InternalLoadBalancerElementResponse extends BaseResponse { + @SerializedName(ApiConstants.ID) @Param(description="the id of the internal load balancer element") + private String id; + + @SerializedName(ApiConstants.NSP_ID) @Param(description="the physical network service provider id of the element") + private String nspId; + + @SerializedName(ApiConstants.ENABLED) @Param(description="Enabled/Disabled the element") + private Boolean enabled; + + + public void setId(String id) { + this.id = id; + } + + public void setNspId(String nspId) { + this.nspId = nspId; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } +} diff --git a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java index b1dcd423117..7a7e371e180 100644 --- a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java @@ -18,6 +18,7 @@ package org.apache.cloudstack.api.response; import java.util.Date; import java.util.List; +import java.util.Map; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; @@ -83,6 +84,10 @@ public class NetworkOfferingResponse extends BaseResponse { @SerializedName(ApiConstants.IS_PERSISTENT) @Param(description="true if network offering supports persistent networks, false otherwise") private Boolean isPersistent; + + @SerializedName(ApiConstants.DETAILS) @Param(description="additional key/value details tied with network offering", since="4.2.0") + private Map details; + public void setId(String id) { this.id = id; @@ -156,5 +161,9 @@ public class NetworkOfferingResponse extends BaseResponse { public void setIsPersistent(Boolean isPersistent) { this.isPersistent = isPersistent; } + + public void setDetails(Map details) { + this.details = details; + } } diff --git a/api/src/org/apache/cloudstack/api/response/VirtualRouterProviderResponse.java b/api/src/org/apache/cloudstack/api/response/VirtualRouterProviderResponse.java index 92d9a1d0cc1..de355bd0c25 100644 --- a/api/src/org/apache/cloudstack/api/response/VirtualRouterProviderResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VirtualRouterProviderResponse.java @@ -25,6 +25,7 @@ import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; @EntityReference(value=VirtualRouterProvider.class) +@SuppressWarnings("unused") public class VirtualRouterProviderResponse extends BaseResponse implements ControlledEntityResponse { @SerializedName(ApiConstants.ID) @Param(description="the id of the router") private String id; diff --git a/api/src/org/apache/cloudstack/network/element/InternalLoadBalancerElementService.java b/api/src/org/apache/cloudstack/network/element/InternalLoadBalancerElementService.java new file mode 100644 index 00000000000..33a0c64058e --- /dev/null +++ b/api/src/org/apache/cloudstack/network/element/InternalLoadBalancerElementService.java @@ -0,0 +1,56 @@ +// 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.network.element; + +import java.util.List; + + +import com.cloud.network.VirtualRouterProvider; +import com.cloud.utils.component.PluggableService; + +public interface InternalLoadBalancerElementService extends PluggableService{ + /** + * Configures existing Internal Load Balancer Element (enables or disables it) + * @param id + * @param enable + * @return + */ + VirtualRouterProvider configureInternalLoadBalancerElement(long id, boolean enable); + + /** + * Adds Internal Load Balancer element to the Network Service Provider + * @param ntwkSvcProviderId + * @return + */ + VirtualRouterProvider addInternalLoadBalancerElement(long ntwkSvcProviderId); + + /** + * Retrieves existing Internal Load Balancer element + * @param id + * @return + */ + VirtualRouterProvider getInternalLoadBalancerElement(long id); + + /** + * Searches for existing Internal Load Balancer elements based on parameters passed to the call + * @param id + * @param ntwkSvsProviderId + * @param enabled + * @return + */ + List searchForInternalLoadBalancerElements(Long id, Long ntwkSvsProviderId, Boolean enabled); +} diff --git a/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerContainer.java b/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerContainer.java new file mode 100644 index 00000000000..df94d3d4338 --- /dev/null +++ b/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerContainer.java @@ -0,0 +1,28 @@ +// 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.network.lb; + +import com.cloud.network.rules.LoadBalancerContainer; +import com.cloud.utils.net.Ip; + +public interface ApplicationLoadBalancerContainer extends LoadBalancerContainer{ + + public Long getSourceIpNetworkId(); + + public Ip getSourceIp(); + +} diff --git a/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerRule.java b/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerRule.java new file mode 100644 index 00000000000..f4acb734c8b --- /dev/null +++ b/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerRule.java @@ -0,0 +1,24 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.cloudstack.network.lb; + +import com.cloud.network.rules.LoadBalancer; + +public interface ApplicationLoadBalancerRule extends ApplicationLoadBalancerContainer, LoadBalancer{ + int getInstancePort(); +} diff --git a/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerService.java b/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerService.java new file mode 100644 index 00000000000..b2ac358555b --- /dev/null +++ b/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerService.java @@ -0,0 +1,42 @@ +// 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.network.lb; + +import java.util.List; + +import org.apache.cloudstack.api.command.user.loadbalancer.ListApplicationLoadBalancersCmd; + +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; +import com.cloud.utils.Pair; + +public interface ApplicationLoadBalancerService { + + ApplicationLoadBalancerRule createApplicationLoadBalancer(String name, String description, Scheme scheme, long sourceIpNetworkId, String sourceIp, + int sourcePort, int instancePort, String algorithm, long networkId, long lbOwnerId) throws InsufficientAddressCapacityException, + NetworkRuleConflictException, InsufficientVirtualNetworkCapcityException; + + boolean deleteApplicationLoadBalancer(long id); + + Pair, Integer> listApplicationLoadBalancers(ListApplicationLoadBalancersCmd cmd); + + ApplicationLoadBalancerRule getApplicationLoadBalancer(long ruleId); + +} diff --git a/api/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMService.java b/api/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMService.java new file mode 100644 index 00000000000..91cd88d91c1 --- /dev/null +++ b/api/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMService.java @@ -0,0 +1,34 @@ +// 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.network.lb; + +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.StorageUnavailableException; +import com.cloud.network.router.VirtualRouter; +import com.cloud.user.Account; + +public interface InternalLoadBalancerVMService { + + VirtualRouter startInternalLbVm(long internalLbVmId, Account caller, long callerUserId) + throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException; + + VirtualRouter stopInternalLbVm(long vmId, boolean forced, Account caller, long callerUserId) + throws ConcurrentOperationException, ResourceUnavailableException; + +} diff --git a/api/src/org/apache/cloudstack/query/QueryService.java b/api/src/org/apache/cloudstack/query/QueryService.java index 443c5df65b5..2f50d63828c 100644 --- a/api/src/org/apache/cloudstack/query/QueryService.java +++ b/api/src/org/apache/cloudstack/query/QueryService.java @@ -18,6 +18,7 @@ package org.apache.cloudstack.query; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; +import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd; import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd; import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd; import org.apache.cloudstack.api.command.admin.user.ListUsersCmd; @@ -101,4 +102,6 @@ public interface QueryService { public ListResponse listAffinityGroups(Long affinityGroupId, String affinityGroupName, String affinityGroupType, Long vmId, Long startIndex, Long pageSize); + + ListResponse searchForInternalLbVms(ListInternalLBVMsCmd cmd); } diff --git a/client/pom.xml b/client/pom.xml index 147959bd7f0..197ba27975c 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -85,6 +85,11 @@ cloud-plugin-network-midonet ${project.version} + + org.apache.cloudstack + cloud-plugin-network-internallb + ${project.version} + org.apache.cloudstack cloud-plugin-hypervisor-xen diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 36f232c737c..67c8ccf9355 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -363,6 +363,9 @@ + + + diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 687c3c16c75..cdc19929c19 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -577,6 +577,17 @@ revertToVMSnapshot=15 #### Baremetal commands addBaremetalHost=1 +#### New Load Balancer commands +createLoadBalancer=15 +listLoadBalancers=15 +deleteLoadBalancer=15 + +#Internal Load Balancer Element commands +configureInternalLoadBalancerElement=1 +createInternalLoadBalancerElement=1 +listInternalLoadBalancerElements=1 + + #### Affinity group commands createAffinityGroup=15 deleteAffinityGroup=15 @@ -594,5 +605,10 @@ addCiscoAsa1000vResource=1 deleteCiscoAsa1000vResource=1 listCiscoAsa1000vResources=1 +#### Internal LB VM commands +stopInternalLoadBalancerVM=1 +startInternalLoadBalancerVM=1 +listInternalLoadBalancerVMs=1 + ### Network Isolation methods listing listNetworkIsolationMethods=1 diff --git a/client/tomcatconf/componentContext.xml.in b/client/tomcatconf/componentContext.xml.in index 7a469816f82..8a45e5fea85 100644 --- a/client/tomcatconf/componentContext.xml.in +++ b/client/tomcatconf/componentContext.xml.in @@ -198,6 +198,7 @@ + @@ -241,6 +242,7 @@ + + + 4.0.0 + cloud-plugin-network-internallb + Apache CloudStack Plugin - Network Internal Load Balancer + + org.apache.cloudstack + cloudstack-plugins + 4.2.0-SNAPSHOT + ../../pom.xml + + + install + src + test + + + resources + + **/*.xml + + + + + + test/resources + + %regex[.*[0-9]*To[0-9]*.*Test.*] + + + + + diff --git a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java new file mode 100644 index 00000000000..4b9308b6606 --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java @@ -0,0 +1,548 @@ +// 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.network.element; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.cloudstack.api.command.admin.internallb.ConfigureInternalLoadBalancerElementCmd; +import org.apache.cloudstack.api.command.admin.internallb.CreateInternalLoadBalancerElementCmd; +import org.apache.cloudstack.api.command.admin.internallb.ListInternalLoadBalancerElementsCmd; +import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; +import org.apache.cloudstack.network.lb.InternalLoadBalancerVMManager; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.configuration.ConfigurationManager; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PublicIpAddress; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; +import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.VirtualRouterProviderDao; +import com.cloud.network.element.IpDeployer; +import com.cloud.network.element.LoadBalancingServiceProvider; +import com.cloud.network.element.NetworkElement; +import com.cloud.network.element.VirtualRouterElement; +import com.cloud.network.element.VirtualRouterProviderVO; +import com.cloud.network.lb.LoadBalancingRule; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.LoadBalancerContainer; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; +import com.cloud.offering.NetworkOffering; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.User; +import com.cloud.utils.component.AdapterBase; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.SearchCriteria2; +import com.cloud.utils.db.SearchCriteriaService; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.Ip; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.dao.DomainRouterDao; + +@Local(value = {NetworkElement.class}) +public class InternalLoadBalancerElement extends AdapterBase implements LoadBalancingServiceProvider, InternalLoadBalancerElementService, IpDeployer{ + private static final Logger s_logger = Logger.getLogger(InternalLoadBalancerElement.class); + protected static final Map> capabilities = setCapabilities(); + private static InternalLoadBalancerElement internalLbElement = null; + + @Inject NetworkModel _ntwkModel; + @Inject NetworkServiceMapDao _ntwkSrvcDao; + @Inject DomainRouterDao _routerDao; + @Inject VirtualRouterProviderDao _vrProviderDao; + @Inject PhysicalNetworkServiceProviderDao _pNtwkSvcProviderDao; + @Inject InternalLoadBalancerVMManager _internalLbMgr; + @Inject ConfigurationManager _configMgr; + @Inject AccountManager _accountMgr; + @Inject ApplicationLoadBalancerRuleDao _appLbDao; + + protected InternalLoadBalancerElement() { + } + + + public static InternalLoadBalancerElement getInstance() { + if ( internalLbElement == null) { + internalLbElement = new InternalLoadBalancerElement(); + } + return internalLbElement; + } + + + private boolean canHandle(Network config, Scheme lbScheme) { + //works in Advance zone only + DataCenter dc = _configMgr.getZone(config.getDataCenterId()); + if (dc.getNetworkType() != NetworkType.Advanced) { + s_logger.trace("Not hanling zone of network type " + dc.getNetworkType()); + return false; + } + if (config.getGuestType() != Network.GuestType.Isolated || config.getTrafficType() != TrafficType.Guest) { + s_logger.trace("Not handling network with Type " + config.getGuestType() + " and traffic type " + config.getTrafficType()); + return false; + } + + Map lbCaps = this.getCapabilities().get(Service.Lb); + if (!lbCaps.isEmpty()) { + String schemeCaps = lbCaps.get(Capability.LbSchemes); + if (schemeCaps != null && lbScheme != null) { + if (!schemeCaps.contains(lbScheme.toString())) { + s_logger.debug("Scheme " + lbScheme.toString() + " is not supported by the provider " + this.getName()); + return false; + } + } + } + + if (!_ntwkModel.isProviderSupportServiceInNetwork(config.getId(), Service.Lb, getProvider())) { + s_logger.trace("Element " + getProvider().getName() + " doesn't support service " + Service.Lb + + " in the network " + config); + return false; + } + return true; + } + + + @Override + public Map> getCapabilities() { + return capabilities; + } + + + @Override + public Provider getProvider() { + return Provider.InternalLbVm; + } + + + @Override + public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + + if (!canHandle(network, null)) { + s_logger.trace("No need to implement " + this.getName()); + return true; + } + + //1) Get all the Ips from the network having LB rules assigned + List ips = _appLbDao.listLbIpsBySourceIpNetworkIdAndScheme(network.getId(), Scheme.Internal); + + //2) Start those vms + for (String ip : ips) { + Ip sourceIp = new Ip(ip); + List internalLbVms; + try { + internalLbVms = _internalLbMgr.deployInternalLbVm(network, sourceIp, dest, _accountMgr.getAccount(network.getAccountId()), null); + } catch (InsufficientCapacityException e) { + s_logger.warn("Failed to deploy element " + this.getName() + " for ip " + sourceIp + " due to:", e); + return false; + } catch (ConcurrentOperationException e) { + s_logger.warn("Failed to deploy element " + this.getName() + " for ip " + sourceIp + " due to:", e); + return false; + } + + if (internalLbVms == null || internalLbVms.isEmpty()) { + throw new ResourceUnavailableException("Can't deploy " + this.getName() + " to handle LB rules", + DataCenter.class, network.getDataCenterId()); + } + } + + return true; + } + + + @Override + public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + + if (!canHandle(network, null)) { + s_logger.trace("No need to prepare " + this.getName()); + return true; + } + + if (vm.getType() == VirtualMachine.Type.User) { + //1) Get all the Ips from the network having LB rules assigned + List ips = _appLbDao.listLbIpsBySourceIpNetworkIdAndScheme(network.getId(), Scheme.Internal); + + //2) Start those vms + for (String ip : ips) { + Ip sourceIp = new Ip(ip); + List internalLbVms; + try { + internalLbVms = _internalLbMgr.deployInternalLbVm(network, sourceIp, dest, _accountMgr.getAccount(network.getAccountId()), null); + } catch (InsufficientCapacityException e) { + s_logger.warn("Failed to deploy element " + this.getName() + " for ip " + sourceIp + " due to:", e); + return false; + } catch (ConcurrentOperationException e) { + s_logger.warn("Failed to deploy element " + this.getName() + " for ip " + sourceIp + " due to:", e); + return false; + } + + if (internalLbVms == null || internalLbVms.isEmpty()) { + throw new ResourceUnavailableException("Can't deploy " + this.getName() + " to handle LB rules", + DataCenter.class, network.getDataCenterId()); + } + } + } + + return true; + } + + @Override + public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + return true; + } + + + @Override + public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException { + List internalLbVms = _routerDao.listByNetworkAndRole(network.getId(), Role.INTERNAL_LB_VM); + if (internalLbVms == null || internalLbVms.isEmpty()) { + return true; + } + boolean result = true; + for (VirtualRouter internalLbVm : internalLbVms) { + result = result && _internalLbMgr.destroyInternalLbVm(internalLbVm.getId(), + context.getAccount(), context.getCaller().getId()); + if (cleanup) { + if (!result) { + s_logger.warn("Failed to stop internal lb element " + internalLbVm + ", but would try to process clean up anyway."); + } + result = (_internalLbMgr.destroyInternalLbVm(internalLbVm.getId(), + context.getAccount(), context.getCaller().getId())); + if (!result) { + s_logger.warn("Failed to clean up internal lb element " + internalLbVm); + } + } + } + return result; + } + + + @Override + public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + List internalLbVms = _routerDao.listByNetworkAndRole(network.getId(), Role.INTERNAL_LB_VM); + if (internalLbVms == null || internalLbVms.isEmpty()) { + return true; + } + boolean result = true; + for (VirtualRouter internalLbVm : internalLbVms) { + result = result && (_internalLbMgr.destroyInternalLbVm(internalLbVm.getId(), + context.getAccount(), context.getCaller().getId())); + } + return result; + } + + + @Override + public boolean isReady(PhysicalNetworkServiceProvider provider) { + VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(provider.getId(), + VirtualRouterProviderType.InternalLbVm); + if (element == null) { + return false; + } + return element.isEnabled(); + } + + + @Override + public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException { + VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(provider.getId(), + VirtualRouterProviderType.InternalLbVm); + if (element == null) { + return true; + } + long elementId = element.getId(); + List internalLbVms = _routerDao.listByElementId(elementId); + boolean result = true; + for (DomainRouterVO internalLbVm : internalLbVms) { + result = result && (_internalLbMgr.destroyInternalLbVm(internalLbVm.getId(), + context.getAccount(), context.getCaller().getId())); + } + _vrProviderDao.remove(elementId); + + return result; + } + + + @Override + public boolean canEnableIndividualServices() { + return true; + } + + + @Override + public boolean verifyServicesCombination(Set services) { + return true; + } + + + @Override + public IpDeployer getIpDeployer(Network network) { + return this; + } + + + @Override + public boolean applyLBRules(Network network, List rules) throws ResourceUnavailableException { + //1) Get Internal LB VMs to destroy + Set vmsToDestroy = getVmsToDestroy(rules); + + //2) Get rules to apply + Map> rulesToApply = getLbRulesToApply(rules); + s_logger.debug("Applying " + rulesToApply.size() + " on element " + this.getName()); + + + for (Ip sourceIp : rulesToApply.keySet()) { + if (vmsToDestroy.contains(sourceIp)) { + //2.1 Destroy internal lb vm + List vms = _internalLbMgr.findInternalLbVms(network.getId(), sourceIp); + if (vms.size() > 0) { + //only one internal lb per IP exists + try { + s_logger.debug("Destroying internal lb vm for ip " + sourceIp.addr() + " as all the rules for this vm are in Revoke state"); + return _internalLbMgr.destroyInternalLbVm(vms.get(0).getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), + _accountMgr.getUserIncludingRemoved(User.UID_SYSTEM).getId()); + } catch (ConcurrentOperationException e) { + s_logger.warn("Failed to apply lb rule(s) for ip " + sourceIp.addr() + " on the element " + this.getName() + " due to:", e); + return false; + } + } + } else { + //2.2 Start Internal LB vm per IP address + List internalLbVms; + try { + DeployDestination dest = new DeployDestination(_configMgr.getZone(network.getDataCenterId()), null, null, null); + internalLbVms = _internalLbMgr.deployInternalLbVm(network, sourceIp, dest, _accountMgr.getAccount(network.getAccountId()), null); + } catch (InsufficientCapacityException e) { + s_logger.warn("Failed to apply lb rule(s) for ip " + sourceIp.addr() + "on the element " + this.getName() + " due to:", e); + return false; + } catch (ConcurrentOperationException e) { + s_logger.warn("Failed to apply lb rule(s) for ip " + sourceIp.addr() + "on the element " + this.getName() + " due to:", e); + return false; + } + + if (internalLbVms == null || internalLbVms.isEmpty()) { + throw new ResourceUnavailableException("Can't find/deploy internal lb vm to handle LB rules", + DataCenter.class, network.getDataCenterId()); + } + + //2.3 Apply Internal LB rules on the VM + if (!_internalLbMgr.applyLoadBalancingRules(network, rulesToApply.get(sourceIp), internalLbVms)) { + throw new CloudRuntimeException("Failed to apply load balancing rules for ip " + sourceIp.addr() + + " in network " + network.getId() + " on element " + this.getName()); + } + } + } + + return true; + } + + + protected Map> getLbRulesToApply(List rules) { + //Group rules by the source ip address as NetworkManager always passes the entire network lb config to the element + Map> rulesToApply = groupBySourceIp(rules); + + return rulesToApply; + } + + + protected Set getVmsToDestroy(List rules) { + //1) Group rules by the source ip address as NetworkManager always passes the entire network lb config to the element + Map> groupedRules = groupBySourceIp(rules); + + //2) Count rules in revoke state + Set vmsToDestroy = new HashSet(); + + for (Ip sourceIp : groupedRules.keySet()) { + List rulesToCheck = groupedRules.get(sourceIp); + int revoke = 0; + for (LoadBalancingRule ruleToCheck : rulesToCheck) { + if (ruleToCheck.getState() == FirewallRule.State.Revoke){ + revoke++; + } + } + + if (revoke == rulesToCheck.size()) { + s_logger.debug("Have to destroy internal lb vm for source ip " + sourceIp); + vmsToDestroy.add(sourceIp); + } + } + return vmsToDestroy; + } + + + protected Map> groupBySourceIp(List rules) { + Map> groupedRules = new HashMap>(); + for (LoadBalancingRule rule : rules) { + Ip sourceIp = rule.getSourceIp(); + if (!groupedRules.containsKey(sourceIp)) { + groupedRules.put(sourceIp, null); + } + + List rulesToApply = groupedRules.get(sourceIp); + if (rulesToApply == null) { + rulesToApply = new ArrayList(); + } + rulesToApply.add(rule); + groupedRules.put(sourceIp, rulesToApply); + } + return groupedRules; + } + + @Override + public boolean validateLBRule(Network network, LoadBalancingRule rule) { + List rules = new ArrayList(); + rules.add(rule); + if (canHandle(network, rule.getScheme())) { + List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.INTERNAL_LB_VM); + if (routers == null || routers.isEmpty()) { + return true; + } + return VirtualRouterElement.validateHAProxyLBRule(rule); + } + return true; + } + + @Override + public List updateHealthChecks(Network network, List lbrules) { + return null; + } + + private static Map> setCapabilities() { + Map> capabilities = new HashMap>(); + + // Set capabilities for LB service + Map lbCapabilities = new HashMap(); + lbCapabilities.put(Capability.SupportedLBAlgorithms, "roundrobin,leastconn,source"); + lbCapabilities.put(Capability.SupportedLBIsolation, "dedicated"); + lbCapabilities.put(Capability.SupportedProtocols, "tcp, udp"); + lbCapabilities.put(Capability.SupportedStickinessMethods, VirtualRouterElement.getHAProxyStickinessCapability()); + lbCapabilities.put(Capability.LbSchemes, LoadBalancerContainer.Scheme.Internal.toString()); + + capabilities.put(Service.Lb, lbCapabilities); + return capabilities; + } + + @Override + public List> getCommands() { + List> cmdList = new ArrayList>(); + cmdList.add(CreateInternalLoadBalancerElementCmd.class); + cmdList.add(ConfigureInternalLoadBalancerElementCmd.class); + cmdList.add(ListInternalLoadBalancerElementsCmd.class); + return cmdList; + } + + @Override + public VirtualRouterProvider configureInternalLoadBalancerElement(long id, boolean enable) { + VirtualRouterProviderVO element = _vrProviderDao.findById(id); + if (element == null || element.getType() != VirtualRouterProviderType.InternalLbVm) { + throw new InvalidParameterValueException("Can't find " + this.getName() + " element with network service provider id " + id + + " to be used as a provider for " + this.getName()); + } + + element.setEnabled(enable); + element = _vrProviderDao.persist(element); + + return element; + } + + @Override + public VirtualRouterProvider addInternalLoadBalancerElement(long ntwkSvcProviderId) { + VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(ntwkSvcProviderId, VirtualRouterProviderType.InternalLbVm); + if (element != null) { + s_logger.debug("There is already an " + this.getName() + " with service provider id " + ntwkSvcProviderId); + return null; + } + + PhysicalNetworkServiceProvider provider = _pNtwkSvcProviderDao.findById(ntwkSvcProviderId); + if (provider == null || !provider.getProviderName().equalsIgnoreCase(this.getName())) { + throw new InvalidParameterValueException("Invalid network service provider is specified"); + } + + element = new VirtualRouterProviderVO(ntwkSvcProviderId, VirtualRouterProviderType.InternalLbVm); + element = _vrProviderDao.persist(element); + return element; + } + + + @Override + public VirtualRouterProvider getInternalLoadBalancerElement(long id) { + VirtualRouterProvider provider = _vrProviderDao.findById(id); + if (provider == null || provider.getType() != VirtualRouterProviderType.InternalLbVm) { + throw new InvalidParameterValueException("Unable to find " + this.getName() + " by id"); + } + return provider; + } + + @Override + public List searchForInternalLoadBalancerElements(Long id, Long ntwkSvsProviderId, Boolean enabled) { + + SearchCriteriaService sc = SearchCriteria2.create(VirtualRouterProviderVO.class); + if (id != null) { + sc.addAnd(sc.getEntity().getId(), Op.EQ, id); + } + if (ntwkSvsProviderId != null) { + sc.addAnd(sc.getEntity().getNspId(), Op.EQ, ntwkSvsProviderId); + } + if (enabled != null) { + sc.addAnd(sc.getEntity().isEnabled(), Op.EQ, enabled); + } + + //return only Internal LB elements + sc.addAnd(sc.getEntity().getType(), Op.EQ, VirtualRouterProvider.VirtualRouterProviderType.InternalLbVm); + + return sc.list(); + } + + @Override + public boolean applyIps(Network network, List ipAddress, Set services) throws ResourceUnavailableException { + //do nothing here; this element just has to extend the ip deployer + //as the LB service implements IPDeployerRequester + return true; + } + +} diff --git a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManager.java b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManager.java new file mode 100644 index 00000000000..9faca562bfb --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManager.java @@ -0,0 +1,90 @@ +// 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.network.lb; + +import java.util.List; +import java.util.Map; + +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.lb.LoadBalancingRule; +import com.cloud.network.router.VirtualRouter; +import com.cloud.user.Account; +import com.cloud.utils.component.Manager; +import com.cloud.utils.net.Ip; +import com.cloud.vm.VirtualMachineProfile.Param; + +public interface InternalLoadBalancerVMManager extends Manager, InternalLoadBalancerVMService{ + //RAM/CPU for the system offering used by Internal LB VMs + public static final int DEFAULT_INTERNALLB_VM_RAMSIZE = 128; // 128 MB + public static final int DEFAULT_INTERNALLB_VM_CPU_MHZ = 256; // 256 MHz + + /** + * Destroys Internal LB vm instance + * @param vmId + * @param caller + * @param callerUserId + * @return + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + boolean destroyInternalLbVm(long vmId, Account caller, Long callerUserId) + throws ResourceUnavailableException, ConcurrentOperationException; + + + /** + * Deploys internal lb vm + * @param guestNetwork + * @param requestedGuestIp + * @param dest + * @param owner + * @param params + * @return + * @throws InsufficientCapacityException + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + List deployInternalLbVm(Network guestNetwork, Ip requestedGuestIp, DeployDestination dest, Account owner, + Map params) throws InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException; + + + + /** + * + * @param network + * @param rules + * @param internalLbVms + * @return + * @throws ResourceUnavailableException + */ + boolean applyLoadBalancingRules(Network network, List rules, List internalLbVms) + throws ResourceUnavailableException; + + + /** + * Returns existing Internal Load Balancer elements based on guestNetworkId (required) and requestedIp (optional) + * @param guestNetworkId + * @param requestedGuestIp + * @return + */ + List findInternalLbVms(long guestNetworkId, Ip requestedGuestIp); + +} diff --git a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java new file mode 100644 index 00000000000..fe32a7ba26f --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java @@ -0,0 +1,951 @@ +// 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.network.lb; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO; +import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.AgentManager.OnError; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.GetDomRVersionAnswer; +import com.cloud.agent.api.GetDomRVersionCmd; +import com.cloud.agent.api.StopAnswer; +import com.cloud.agent.api.check.CheckSshAnswer; +import com.cloud.agent.api.check.CheckSshCommand; +import com.cloud.agent.api.routing.LoadBalancerConfigCommand; +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.agent.manager.Commands; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.deploy.DataCenterDeployment; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.exception.AgentUnavailableException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientServerCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.OperationTimedoutException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.StorageUnavailableException; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.Network; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.VirtualRouterProviderDao; +import com.cloud.network.lb.LoadBalancingRule; +import com.cloud.network.lb.LoadBalancingRule.LbDestination; +import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy; +import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; +import com.cloud.network.lb.LoadBalancingRulesManager; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VirtualRouter.RedundantState; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.network.rules.FirewallRule; +import com.cloud.offering.NetworkOffering; +import com.cloud.offering.ServiceOffering; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.resource.ResourceManager; +import com.cloud.server.ConfigurationServer; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.User; +import com.cloud.utils.Pair; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.db.DB; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.Ip; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.Nic; +import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.VirtualMachineGuru; +import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.VirtualMachineName; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.VirtualMachineProfile.Param; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; + +@Component +@Local(value = { InternalLoadBalancerVMManager.class, InternalLoadBalancerVMService.class}) +public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements + InternalLoadBalancerVMManager, VirtualMachineGuru { + private static final Logger s_logger = Logger + .getLogger(InternalLoadBalancerVMManagerImpl.class); + static final private String _internalLbVmNamePrefix = "b"; + + private String _instance; + private String _mgmtHost; + private String _mgmtCidr; + private long _internalLbVmOfferingId; + + @Inject VirtualMachineManager _itMgr; + @Inject DomainRouterDao _internalLbVmDao; + @Inject ConfigurationDao _configDao; + @Inject AgentManager _agentMgr; + @Inject DataCenterDao _dcDao; + @Inject VirtualRouterProviderDao _vrProviderDao; + @Inject ApplicationLoadBalancerRuleDao _lbDao; + @Inject NetworkModel _ntwkModel; + @Inject LoadBalancingRulesManager _lbMgr; + @Inject NicDao _nicDao; + @Inject AccountManager _accountMgr; + @Inject NetworkDao _networkDao; + @Inject NetworkManager _ntwkMgr; + @Inject ServiceOfferingDao _serviceOfferingDao; + @Inject PhysicalNetworkServiceProviderDao _physicalProviderDao; + @Inject NetworkOfferingDao _networkOfferingDao; + @Inject VMTemplateDao _templateDao; + @Inject ResourceManager _resourceMgr; + @Inject ConfigurationServer _configServer; + + @Override + public DomainRouterVO findByName(String name) { + if (!VirtualMachineName.isValidSystemVmName(name, _instance, _internalLbVmNamePrefix)) { + return null; + } + + return _internalLbVmDao.findById(VirtualMachineName.getRouterId(name)); + } + + @Override + public DomainRouterVO findById(long id) { + return _internalLbVmDao.findById(id); + } + + @Override + public DomainRouterVO persist(DomainRouterVO vm) { + DomainRouterVO virtualRouter = _internalLbVmDao.persist(vm); + return virtualRouter; + } + + @Override + public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, + DeployDestination dest, ReservationContext context) { + + //Internal LB vm starts up with 2 Nics + //Nic #1 - Guest Nic with IP address that would act as the LB entry point + //Nic #2 - Control/Management Nic + + StringBuilder buf = profile.getBootArgsBuilder(); + buf.append(" template=domP"); + buf.append(" name=").append(profile.getHostName()); + + if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) { + buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password")); + } + + NicProfile controlNic = null; + Network guestNetwork = null; + + for (NicProfile nic : profile.getNics()) { + int deviceId = nic.getDeviceId(); + buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address()); + buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); + + if (nic.isDefaultNic()) { + buf.append(" gateway=").append(nic.getGateway()); + buf.append(" dns1=").append(nic.getGateway()); + } + + if (nic.getTrafficType() == TrafficType.Guest) { + guestNetwork = _ntwkModel.getNetwork(nic.getNetworkId()); + } else if (nic.getTrafficType() == TrafficType.Management) { + buf.append(" localgw=").append(dest.getPod().getGateway()); + } else if (nic.getTrafficType() == TrafficType.Control) { + controlNic = nic; + // Internal LB control command is sent over management server in VMware + if (dest.getHost().getHypervisorType() == HypervisorType.VMware) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Check if we need to add management server explicit route to Internal LB. pod cidr: " + + dest.getPod().getCidrAddress() + "/" + dest.getPod().getCidrSize() + + ", pod gateway: " + dest.getPod().getGateway() + ", management host: " + _mgmtHost); + } + + if (s_logger.isInfoEnabled()) { + s_logger.info("Add management server explicit route to Internal LB."); + } + + + buf.append(" mgmtcidr=").append(_mgmtCidr); + buf.append(" localgw=").append(dest.getPod().getGateway()); + } + } + } + + if (controlNic == null) { + throw new CloudRuntimeException("Didn't start a control port"); + } + + if (guestNetwork != null) { + String domain = guestNetwork.getNetworkDomain(); + if (domain != null) { + buf.append(" domain=" + domain); + } + } + + String type = "ilbvm"; + buf.append(" type=" + type); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Boot Args for " + profile + ": " + buf.toString()); + } + + return true; + } + + @Override + public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException { + DomainRouterVO internalLbVm = profile.getVirtualMachine(); + + List nics = profile.getNics(); + for (NicProfile nic : nics) { + if (nic.getTrafficType() == TrafficType.Control) { + internalLbVm.setPrivateIpAddress(nic.getIp4Address()); + internalLbVm.setPrivateMacAddress(nic.getMacAddress()); + } + } + _internalLbVmDao.update(internalLbVm.getId(), internalLbVm); + + finalizeCommandsOnStart(cmds, profile); + return true; + } + + @Override + public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) { + DomainRouterVO internalLbVm = profile.getVirtualMachine(); + + boolean result = true; + + Answer answer = cmds.getAnswer("checkSsh"); + if (answer != null && answer instanceof CheckSshAnswer) { + CheckSshAnswer sshAnswer = (CheckSshAnswer) answer; + if (sshAnswer == null || !sshAnswer.getResult()) { + s_logger.warn("Unable to ssh to the internal LB VM: " + sshAnswer.getDetails()); + result = false; + } + } else { + result = false; + } + if (result == false) { + return result; + } + + //Get guest network info + List guestNetworks = new ArrayList(); + List internalLbVmNics = _nicDao.listByVmId(profile.getId()); + for (Nic internalLbVmNic : internalLbVmNics) { + Network network = _ntwkModel.getNetwork(internalLbVmNic.getNetworkId()); + if (network.getTrafficType() == TrafficType.Guest) { + guestNetworks.add(network); + } + } + + answer = cmds.getAnswer("getDomRVersion"); + if (answer != null && answer instanceof GetDomRVersionAnswer) { + GetDomRVersionAnswer versionAnswer = (GetDomRVersionAnswer)answer; + if (answer == null || !answer.getResult()) { + s_logger.warn("Unable to get the template/scripts version of internal LB VM " + internalLbVm.getInstanceName() + + " due to: " + versionAnswer.getDetails()); + result = false; + } else { + internalLbVm.setTemplateVersion(versionAnswer.getTemplateVersion()); + internalLbVm.setScriptsVersion(versionAnswer.getScriptsVersion()); + internalLbVm = _internalLbVmDao.persist(internalLbVm, guestNetworks); + } + } else { + result = false; + } + + return result; + } + + @Override + public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) { + DomainRouterVO internalLbVm = profile.getVirtualMachine(); + NicProfile controlNic = getNicProfileByTrafficType(profile, TrafficType.Control); + + if (controlNic == null) { + s_logger.error("Control network doesn't exist for the internal LB vm " + internalLbVm); + return false; + } + + finalizeSshAndVersionOnStart(cmds, profile, internalLbVm, controlNic); + + // restart network if restartNetwork = false is not specified in profile parameters + boolean reprogramGuestNtwk = true; + if (profile.getParameter(Param.ReProgramGuestNetworks) != null + && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) { + reprogramGuestNtwk = false; + } + + VirtualRouterProvider lbProvider = _vrProviderDao.findById(internalLbVm.getElementId()); + if (lbProvider == null) { + throw new CloudRuntimeException("Cannot find related element " + VirtualRouterProviderType.InternalLbVm + " of vm: " + internalLbVm.getHostName()); + } + + Provider provider = Network.Provider.getProvider(lbProvider.getType().toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find related provider of provider: " + lbProvider.getType().toString()); + } + + if (reprogramGuestNtwk) { + NicProfile guestNic = getNicProfileByTrafficType(profile, TrafficType.Guest); + finalizeLbRulesForIp(cmds, internalLbVm, provider, new Ip(guestNic.getIp4Address()), guestNic.getNetworkId()); + } + + return true; + } + + @Override + public void finalizeStop(VirtualMachineProfile profile, StopAnswer answer) { + } + + @Override + public void finalizeExpunge(DomainRouterVO vm) { + } + + @Override + public Long convertToId(String vmName) { + if (!VirtualMachineName.isValidSystemVmName(vmName, _instance, _internalLbVmNamePrefix)) { + return null; + } + + return VirtualMachineName.getRouterId(vmName); + } + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } + + @Override + public void prepareStop(VirtualMachineProfile profile) { + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + final Map configs = _configDao.getConfiguration("AgentManager", params); + _instance = configs.get("instance.name"); + if (_instance == null) { + _instance = "DEFAULT"; + } + + _mgmtHost = configs.get("host"); + _mgmtCidr = _configDao.getValue(Config.ManagementNetwork.key()); + + String offIdStr = configs.get(Config.InternalLbVmServiceOfferingId.key()); + if (offIdStr != null && !offIdStr.isEmpty()) { + _internalLbVmOfferingId = Long.parseLong(offIdStr); + } else { + boolean useLocalStorage = Boolean.parseBoolean(configs.get(Config.SystemVMUseLocalStorage.key())); + ServiceOfferingVO newOff = new ServiceOfferingVO("System Offering For Internal LB VM", 1, InternalLoadBalancerVMManager.DEFAULT_INTERNALLB_VM_RAMSIZE, InternalLoadBalancerVMManager.DEFAULT_INTERNALLB_VM_CPU_MHZ, null, + null, true, null, useLocalStorage, true, null, true, VirtualMachine.Type.InternalLoadBalancerVm, true); + newOff.setUniqueName(ServiceOffering.internalLbVmDefaultOffUniqueName); + newOff = _serviceOfferingDao.persistSystemServiceOffering(newOff); + _internalLbVmOfferingId = newOff.getId(); + } + + _itMgr.registerGuru(VirtualMachine.Type.InternalLoadBalancerVm, this); + + if (s_logger.isInfoEnabled()) { + s_logger.info(getName() + " has been configured"); + } + + return true; + } + + @Override + public String getName() { + return _name; + } + + protected NicProfile getNicProfileByTrafficType(VirtualMachineProfile profile, TrafficType trafficType) { + for (NicProfile nic : profile.getNics()) { + if (nic.getTrafficType() == trafficType && nic.getIp4Address() != null) { + return nic; + } + } + return null; + } + + protected void finalizeSshAndVersionOnStart(Commands cmds, VirtualMachineProfile profile, DomainRouterVO router, NicProfile controlNic) { + cmds.addCommand("checkSsh", new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922)); + + // Update internal lb vm template/scripts version + final GetDomRVersionCmd command = new GetDomRVersionCmd(); + command.setAccessDetail(NetworkElementCommand.ROUTER_IP, controlNic.getIp4Address()); + command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + cmds.addCommand("getDomRVersion", command); + } + + + protected void finalizeLbRulesForIp(Commands cmds, DomainRouterVO internalLbVm, Provider provider, Ip sourceIp, long guestNtwkId) { + s_logger.debug("Resending load balancing rules as a part of start for " + internalLbVm); + List lbs = _lbDao.listBySrcIpSrcNtwkId(sourceIp, guestNtwkId); + List lbRules = new ArrayList(); + if (_ntwkModel.isProviderSupportServiceInNetwork(guestNtwkId, Service.Lb, provider)) { + // Re-apply load balancing rules + for (ApplicationLoadBalancerRuleVO lb : lbs) { + List dstList = _lbMgr.getExistingDestinations(lb.getId()); + List policyList = _lbMgr.getStickinessPolicies(lb.getId()); + List hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId()); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp); + lbRules.add(loadBalancing); + } + } + + s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of Intenrnal LB vm" + internalLbVm + " start."); + if (!lbRules.isEmpty()) { + createApplyLoadBalancingRulesCommands(lbRules, internalLbVm, cmds, guestNtwkId); + } + } + + private void createApplyLoadBalancingRulesCommands(List rules, VirtualRouter internalLbVm, Commands cmds, long guestNetworkId) { + + LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()]; + int i = 0; + boolean inline = false; + for (LoadBalancingRule rule : rules) { + boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke)); + String protocol = rule.getProtocol(); + String algorithm = rule.getAlgorithm(); + String uuid = rule.getUuid(); + + String srcIp = rule.getSourceIp().addr(); + int srcPort = rule.getSourcePortStart(); + List destinations = rule.getDestinations(); + List stickinessPolicies = rule.getStickinessPolicies(); + LoadBalancerTO lb = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, stickinessPolicies); + lbs[i++] = lb; + } + + Network guestNetwork = _ntwkModel.getNetwork(guestNetworkId); + Nic guestNic = _nicDao.findByNtwkIdAndInstanceId(guestNetwork.getId(), internalLbVm.getId()); + NicProfile guestNicProfile = new NicProfile(guestNic, guestNetwork, guestNic.getBroadcastUri(), guestNic.getIsolationUri(), + _ntwkModel.getNetworkRate(guestNetwork.getId(), internalLbVm.getId()), + _ntwkModel.isSecurityGroupSupportedInNetwork(guestNetwork), + _ntwkModel.getNetworkTag(internalLbVm.getHypervisorType(), guestNetwork)); + + LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs, guestNic.getIp4Address(), + guestNic.getIp4Address(), internalLbVm.getPrivateIpAddress(), + _itMgr.toNicTO(guestNicProfile, internalLbVm.getHypervisorType()), internalLbVm.getVpcId()); + + cmd.lbStatsVisibility = _configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key()); + cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key()); + cmd.lbStatsAuth = _configDao.getValue(Config.NetworkLBHaproxyStatsAuth.key()); + cmd.lbStatsPort = _configDao.getValue(Config.NetworkLBHaproxyStatsPort.key()); + + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getInternalLbControlIp(internalLbVm.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, guestNic.getIp4Address()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, internalLbVm.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(internalLbVm.getDataCenterId()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand(cmd); + } + + + protected String getInternalLbControlIp(long internalLbVmId) { + String controlIpAddress = null; + List nics = _nicDao.listByVmId(internalLbVmId); + for (NicVO nic : nics) { + Network ntwk = _ntwkModel.getNetwork(nic.getNetworkId()); + if (ntwk.getTrafficType() == TrafficType.Control) { + controlIpAddress = nic.getIp4Address(); + } + } + + if(controlIpAddress == null) { + s_logger.warn("Unable to find Internal LB control ip in its attached NICs!. Internal LB vm: " + internalLbVmId); + DomainRouterVO internalLbVm = _internalLbVmDao.findById(internalLbVmId); + return internalLbVm.getPrivateIpAddress(); + } + + return controlIpAddress; + } + + @Override + public boolean destroyInternalLbVm(long vmId, Account caller, Long callerUserId) + throws ResourceUnavailableException, ConcurrentOperationException { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Attempting to destroy Internal LB vm " + vmId); + } + + DomainRouterVO internalLbVm = _internalLbVmDao.findById(vmId); + if (internalLbVm == null) { + return true; + } + + _accountMgr.checkAccess(caller, null, true, internalLbVm); + + return _itMgr.expunge(internalLbVm, _accountMgr.getActiveUser(callerUserId), caller); + } + + + @Override + public VirtualRouter stopInternalLbVm(long vmId, boolean forced, Account caller, long callerUserId) throws ConcurrentOperationException, + ResourceUnavailableException { + DomainRouterVO internalLbVm = _internalLbVmDao.findById(vmId); + if (internalLbVm == null || internalLbVm.getRole() != Role.INTERNAL_LB_VM) { + throw new InvalidParameterValueException("Can't find internal lb vm by id specified"); + } + + return stopInternalLbVm(internalLbVm, forced, caller, callerUserId); + } + + protected VirtualRouter stopInternalLbVm(DomainRouterVO internalLbVm, boolean forced, Account caller, long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException { + s_logger.debug("Stopping internal lb vm " + internalLbVm); + try { + if (_itMgr.advanceStop((DomainRouterVO) internalLbVm, forced, _accountMgr.getActiveUser(callerUserId), caller)) { + return _internalLbVmDao.findById(internalLbVm.getId()); + } else { + return null; + } + } catch (OperationTimedoutException e) { + throw new CloudRuntimeException("Unable to stop " + internalLbVm, e); + } + } + + + @Override + public List deployInternalLbVm(Network guestNetwork, Ip requestedGuestIp, DeployDestination dest, + Account owner, Map params) throws InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { + + List internalLbVms = findOrDeployInternalLbVm(guestNetwork, requestedGuestIp, dest, owner, params); + + return startInternalLbVms(params, internalLbVms); + } + + protected List startInternalLbVms(Map params, List internalLbVms) + throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { + List runningInternalLbVms = null; + + if (internalLbVms != null) { + runningInternalLbVms = new ArrayList(); + } else { + s_logger.debug("Have no internal lb vms to start"); + return null; + } + + for (DomainRouterVO internalLbVm : internalLbVms) { + if (internalLbVm.getState() != VirtualMachine.State.Running) { + internalLbVm = startInternalLbVm(internalLbVm, _accountMgr.getSystemAccount(), User.UID_SYSTEM, params); + } + + if (internalLbVm != null) { + runningInternalLbVms.add(internalLbVm); + } + } + return runningInternalLbVms; + } + + + + @DB + protected List findOrDeployInternalLbVm(Network guestNetwork, Ip requestedGuestIp, DeployDestination dest, + Account owner, Map params) throws ConcurrentOperationException, + InsufficientCapacityException, ResourceUnavailableException { + + List internalLbVms = new ArrayList(); + Network lock = _networkDao.acquireInLockTable(guestNetwork.getId(), _ntwkMgr.getNetworkLockTimeout()); + if (lock == null) { + throw new ConcurrentOperationException("Unable to lock network " + guestNetwork.getId()); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Lock is acquired for network id " + lock.getId() + " as a part of internal lb startup in " + dest); + } + + long internalLbProviderId = getInternalLbProviderId(guestNetwork); + + try { + assert guestNetwork.getState() == Network.State.Implemented || guestNetwork.getState() == Network.State.Setup || + guestNetwork.getState() == Network.State.Implementing : "Network is not yet fully implemented: " + + guestNetwork; + assert guestNetwork.getTrafficType() == TrafficType.Guest; + + //deploy internal lb vm + Pair> planAndInternalLbVms = getDeploymentPlanAndInternalLbVms(dest, guestNetwork.getId(), requestedGuestIp); + internalLbVms = planAndInternalLbVms.second(); + DeploymentPlan plan = planAndInternalLbVms.first(); + + if (internalLbVms.size() > 0) { + s_logger.debug("Found " + internalLbVms.size() + " internal lb vms for the requested IP " + requestedGuestIp.addr()); + return internalLbVms; + } + + List> networks = createInternalLbVmNetworks(guestNetwork, plan, requestedGuestIp); + //Pass startVm=false as we are holding the network lock that needs to be released at the end of vm allocation + DomainRouterVO internalLbVm = deployInternalLbVm(owner, dest, plan, params, internalLbProviderId, _internalLbVmOfferingId, guestNetwork.getVpcId(), + networks, false); + if (internalLbVm != null) { + _internalLbVmDao.addRouterToGuestNetwork(internalLbVm, guestNetwork); + internalLbVms.add(internalLbVm); + } + } finally { + if (lock != null) { + _networkDao.releaseFromLockTable(lock.getId()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Lock is released for network id " + lock.getId() + " as a part of internal lb vm startup in " + dest); + } + } + } + return internalLbVms; + } + + protected long getInternalLbProviderId(Network guestNetwork) { + VirtualRouterProviderType type = VirtualRouterProviderType.InternalLbVm; + long physicalNetworkId = _ntwkModel.getPhysicalNetworkId(guestNetwork); + + PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId); + } + + VirtualRouterProvider internalLbProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), type); + if (internalLbProvider == null) { + throw new CloudRuntimeException("Cannot find provider " + type.toString() + " as service provider " + provider.getId()); + } + + return internalLbProvider.getId(); + } + + protected List> createInternalLbVmNetworks(Network guestNetwork, DeploymentPlan plan, Ip guestIp) throws ConcurrentOperationException, + InsufficientAddressCapacityException { + + //Form networks + List> networks = new ArrayList>(3); + + //1) Guest network - default + if (guestNetwork != null) { + s_logger.debug("Adding nic for Internal LB in Guest network " + guestNetwork); + NicProfile guestNic = new NicProfile(); + if (guestIp != null) { + guestNic.setIp4Address(guestIp.addr()); + } else { + guestNic.setIp4Address(_ntwkMgr.acquireGuestIpAddress(guestNetwork, null)); + } + guestNic.setGateway(guestNetwork.getGateway()); + guestNic.setBroadcastUri(guestNetwork.getBroadcastUri()); + guestNic.setBroadcastType(guestNetwork.getBroadcastDomainType()); + guestNic.setIsolationUri(guestNetwork.getBroadcastUri()); + guestNic.setMode(guestNetwork.getMode()); + String gatewayCidr = guestNetwork.getCidr(); + guestNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); + guestNic.setDefaultNic(true); + networks.add(new Pair((NetworkVO) guestNetwork, guestNic)); + } + + //2) Control network + s_logger.debug("Adding nic for Internal LB vm in Control network "); + List offerings = _ntwkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork); + NetworkOffering controlOffering = offerings.get(0); + NetworkVO controlConfig = _ntwkMgr.setupNetwork(_accountMgr.getSystemAccount(), controlOffering, plan, null, null, false).get(0); + networks.add(new Pair(controlConfig, null)); + + return networks; + } + + + protected Pair> getDeploymentPlanAndInternalLbVms(DeployDestination dest, long guestNetworkId, Ip requestedGuestIp) { + long dcId = dest.getDataCenter().getId(); + DeploymentPlan plan = new DataCenterDeployment(dcId); + List internalLbVms = findInternalLbVms(guestNetworkId, requestedGuestIp); + + return new Pair>(plan, internalLbVms); + + } + + @Override + public List findInternalLbVms(long guestNetworkId, Ip requestedGuestIp) { + List internalLbVms = _internalLbVmDao.listByNetworkAndRole(guestNetworkId, Role.INTERNAL_LB_VM); + if (requestedGuestIp != null && !internalLbVms.isEmpty()) { + Iterator it = internalLbVms.iterator(); + while (it.hasNext()) { + DomainRouterVO vm = it.next(); + Nic nic = _nicDao.findByNtwkIdAndInstanceId(guestNetworkId, vm.getId()); + if (!nic.getIp4Address().equalsIgnoreCase(requestedGuestIp.addr())) { + it.remove(); + } + } + } + return internalLbVms; + } + + + protected DomainRouterVO deployInternalLbVm(Account owner, DeployDestination dest, DeploymentPlan plan, Map params, + long internalLbProviderId, long svcOffId, Long vpcId, + List> networks, boolean startVm) throws ConcurrentOperationException, + InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, + StorageUnavailableException, ResourceUnavailableException { + + long id = _internalLbVmDao.getNextInSequence(Long.class, "id"); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating the internal lb vm " + id + " in datacenter " + dest.getDataCenter()); + } + + ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(svcOffId); + + // Internal lb is the network element, we don't know the hypervisor type yet. + // Try to allocate the internal lb twice using diff hypervisors, and when failed both times, throw the exception up + List hypervisors = getHypervisors(dest, plan, null); + + int allocateRetry = 0; + int startRetry = 0; + DomainRouterVO internalLbVm = null; + for (Iterator iter = hypervisors.iterator(); iter.hasNext();) { + HypervisorType hType = iter.next(); + try { + s_logger.debug("Allocating the Internal lb with the hypervisor type " + hType); + String templateName = null; + switch (hType) { + case XenServer: + templateName = _configServer.getConfigValue(Config.RouterTemplateXen.key(), Config.ConfigurationParameterScope.zone.toString(), dest.getDataCenter().getId()); + break; + case KVM: + templateName = _configServer.getConfigValue(Config.RouterTemplateKVM.key(), Config.ConfigurationParameterScope.zone.toString(), dest.getDataCenter().getId()); + break; + case VMware: + templateName = _configServer.getConfigValue(Config.RouterTemplateVmware.key(), Config.ConfigurationParameterScope.zone.toString(), dest.getDataCenter().getId()); + break; + case Hyperv: + templateName = _configServer.getConfigValue(Config.RouterTemplateHyperv.key(), Config.ConfigurationParameterScope.zone.toString(), dest.getDataCenter().getId()); + break; + case LXC: + templateName = _configServer.getConfigValue(Config.RouterTemplateLXC.key(), Config.ConfigurationParameterScope.zone.toString(), dest.getDataCenter().getId()); + break; + default: break; + } + VMTemplateVO template = _templateDao.findRoutingTemplate(hType, templateName); + + if (template == null) { + s_logger.debug(hType + " won't support system vm, skip it"); + continue; + } + + internalLbVm = new DomainRouterVO(id, routerOffering.getId(), internalLbProviderId, + VirtualMachineName.getSystemVmName(id, _instance, _internalLbVmNamePrefix), template.getId(), template.getHypervisorType(), + template.getGuestOSId(), owner.getDomainId(), owner.getId(), false, 0, false, + RedundantState.UNKNOWN, false, false, VirtualMachine.Type.InternalLoadBalancerVm, vpcId); + internalLbVm.setRole(Role.INTERNAL_LB_VM); + internalLbVm = _itMgr.allocate(internalLbVm, template, routerOffering, networks, plan, null, owner); + } catch (InsufficientCapacityException ex) { + if (allocateRetry < 2 && iter.hasNext()) { + s_logger.debug("Failed to allocate the Internal lb vm with hypervisor type " + hType + ", retrying one more time"); + continue; + } else { + throw ex; + } + } finally { + allocateRetry++; + } + + if (startVm) { + try { + internalLbVm = startInternalLbVm(internalLbVm, _accountMgr.getSystemAccount(), User.UID_SYSTEM, params); + break; + } catch (InsufficientCapacityException ex) { + if (startRetry < 2 && iter.hasNext()) { + s_logger.debug("Failed to start the Internal lb vm " + internalLbVm + " with hypervisor type " + hType + ", " + + "destroying it and recreating one more time"); + // destroy the internal lb vm + destroyInternalLbVm(internalLbVm.getId(), _accountMgr.getSystemAccount(), User.UID_SYSTEM); + continue; + } else { + throw ex; + } + } finally { + startRetry++; + } + } else { + //return stopped internal lb vm + return internalLbVm; + } + } + return internalLbVm; + } + + + + protected DomainRouterVO startInternalLbVm(DomainRouterVO internalLbVm, Account caller, long callerUserId, Map params) + throws StorageUnavailableException, InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { + s_logger.debug("Starting Internal LB VM " + internalLbVm); + if (_itMgr.start(internalLbVm, params, _accountMgr.getUserIncludingRemoved(callerUserId), caller, null) != null) { + if (internalLbVm.isStopPending()) { + s_logger.info("Clear the stop pending flag of Internal LB VM " + internalLbVm.getHostName() + " after start router successfully!"); + internalLbVm.setStopPending(false); + internalLbVm = _internalLbVmDao.persist(internalLbVm); + } + return _internalLbVmDao.findById(internalLbVm.getId()); + } else { + return null; + } + } + + + protected List getHypervisors(DeployDestination dest, DeploymentPlan plan, + List supportedHypervisors) throws InsufficientServerCapacityException { + List hypervisors = new ArrayList(); + + HypervisorType defaults = _resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId()); + if (defaults != HypervisorType.None) { + hypervisors.add(defaults); + } else { + //if there is no default hypervisor, get it from the cluster + hypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, + plan.getPodId()); + } + + //keep only elements defined in supported hypervisors + StringBuilder hTypesStr = new StringBuilder(); + if (supportedHypervisors != null && !supportedHypervisors.isEmpty()) { + hypervisors.retainAll(supportedHypervisors); + for (HypervisorType hType : supportedHypervisors) { + hTypesStr.append(hType).append(" "); + } + } + + if (hypervisors.isEmpty()) { + throw new InsufficientServerCapacityException("Unable to create internal lb vm, " + + "there are no clusters in the zone ", DataCenter.class, dest.getDataCenter().getId()); + } + return hypervisors; + } + + @Override + public boolean applyLoadBalancingRules(Network network, final List rules, List internalLbVms) + throws ResourceUnavailableException { + if (rules == null || rules.isEmpty()) { + s_logger.debug("No lb rules to be applied for network " + network); + return true; + } + + //only one internal lb vm is supported per ip address at this time + if (internalLbVms == null || internalLbVms.isEmpty()) { + throw new CloudRuntimeException("Can't apply the lb rules on network " + network + " as the list of internal lb vms is empty"); + } + + VirtualRouter lbVm = internalLbVms.get(0); + if (lbVm.getState() == State.Running) { + return sendLBRules(lbVm, rules, network.getId()); + } else if (lbVm.getState() == State.Stopped || lbVm.getState() == State.Stopping) { + s_logger.debug("Internal LB VM " + lbVm.getInstanceName() + " is in " + lbVm.getState() + + ", so not sending apply lb rules commands to the backend"); + return true; + } else { + s_logger.warn("Unable to apply lb rules, Internal LB VM is not in the right state " + lbVm.getState()); + throw new ResourceUnavailableException("Unable to apply lb rules; Internal LB VM is not in the right state", DataCenter.class, lbVm.getDataCenterId()); + } + } + + protected boolean sendLBRules(VirtualRouter internalLbVm, List rules, long guestNetworkId) throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createApplyLoadBalancingRulesCommands(rules, internalLbVm, cmds, guestNetworkId); + return sendCommandsToInternalLbVm(internalLbVm, cmds); + } + + + protected boolean sendCommandsToInternalLbVm(final VirtualRouter internalLbVm, Commands cmds) throws AgentUnavailableException { + Answer[] answers = null; + try { + answers = _agentMgr.send(internalLbVm.getHostId(), cmds); + } catch (OperationTimedoutException e) { + s_logger.warn("Timed Out", e); + throw new AgentUnavailableException("Unable to send commands to virtual router ", internalLbVm.getHostId(), e); + } + + if (answers == null) { + return false; + } + + if (answers.length != cmds.size()) { + return false; + } + + boolean result = true; + if (answers.length > 0) { + for (Answer answer : answers) { + if (!answer.getResult()) { + result = false; + break; + } + } + } + return result; + } + + + @Override + public VirtualRouter startInternalLbVm(long internalLbVmId, Account caller, long callerUserId) + throws StorageUnavailableException, InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { + + DomainRouterVO internalLbVm = _internalLbVmDao.findById(internalLbVmId); + if (internalLbVm == null || internalLbVm.getRole() != Role.INTERNAL_LB_VM) { + throw new InvalidParameterValueException("Can't find internal lb vm by id specified"); + } + + return startInternalLbVm(internalLbVm, caller, callerUserId, null); + } +} diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/ElementChildTestConfiguration.java b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/ElementChildTestConfiguration.java new file mode 100644 index 00000000000..6959b951fc3 --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/ElementChildTestConfiguration.java @@ -0,0 +1,124 @@ +// 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.internallbelement; + +import java.io.IOException; + +import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; +import org.apache.cloudstack.network.lb.InternalLoadBalancerVMManager; +import org.apache.cloudstack.test.utils.SpringUtils; +import org.mockito.Mockito; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.ComponentScan.Filter; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.classreading.MetadataReaderFactory; +import org.springframework.core.type.filter.TypeFilter; + +import com.cloud.configuration.ConfigurationManager; +import com.cloud.dc.dao.AccountVlanMapDaoImpl; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkModel; +import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.VirtualRouterProviderDao; +import com.cloud.user.AccountManager; +import com.cloud.vm.dao.DomainRouterDao; + +@Configuration +@ComponentScan( + basePackageClasses={ + AccountVlanMapDaoImpl.class + }, + includeFilters={@Filter(value=ElementChildTestConfiguration.Library.class, type=FilterType.CUSTOM)}, + useDefaultFilters=false + ) + +public class ElementChildTestConfiguration { + public static class Library implements TypeFilter { + @Bean + public AccountManager accountManager() { + return Mockito.mock(AccountManager.class); + } + + + @Bean + public DomainRouterDao domainRouterDao() { + return Mockito.mock(DomainRouterDao.class); + } + + @Bean + public VirtualRouterProviderDao virtualRouterProviderDao() { + return Mockito.mock(VirtualRouterProviderDao.class); + } + + @Bean + public NetworkModel networkModel() { + return Mockito.mock(NetworkModel.class); + } + + + @Bean + public NetworkManager networkManager() { + return Mockito.mock(NetworkManager.class); + } + + + @Bean + public PhysicalNetworkServiceProviderDao physicalNetworkServiceProviderDao() { + return Mockito.mock(PhysicalNetworkServiceProviderDao.class); + } + + @Bean + public NetworkServiceMapDao networkServiceMapDao() { + return Mockito.mock(NetworkServiceMapDao.class); + } + + @Bean + public InternalLoadBalancerVMManager internalLoadBalancerVMManager() { + return Mockito.mock(InternalLoadBalancerVMManager.class); + } + + @Bean + public ConfigurationManager confugurationManager() { + return Mockito.mock(ConfigurationManager.class); + } + + + @Bean + public ApplicationLoadBalancerRuleDao applicationLoadBalancerRuleDao() { + return Mockito.mock(ApplicationLoadBalancerRuleDao.class); + } + + @Bean + public DataCenterDao dataCenterDao() { + return Mockito.mock(DataCenterDao.class); + } + + + + @Override + public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { + mdr.getClassMetadata().getClassName(); + ComponentScan cs = ElementChildTestConfiguration.class.getAnnotation(ComponentScan.class); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + } + } +} diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementServiceTest.java b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementServiceTest.java new file mode 100644 index 00000000000..f0e951cdc7a --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementServiceTest.java @@ -0,0 +1,190 @@ +// 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.internallbelement; + +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 javax.inject.Inject; + +import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; +import com.cloud.network.dao.VirtualRouterProviderDao; +import com.cloud.network.element.VirtualRouterProviderVO; +import com.cloud.user.AccountManager; +import com.cloud.utils.component.ComponentContext; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations="classpath:/lb_element.xml") +public class InternalLbElementServiceTest { + //The interface to test + @Inject InternalLoadBalancerElementService _lbElSvc; + + //Mocked interfaces + @Inject AccountManager _accountMgr; + @Inject VirtualRouterProviderDao _vrProviderDao; + @Inject PhysicalNetworkServiceProviderDao _pNtwkProviderDao; + + long validElId = 1L; + long nonExistingElId = 2L; + long invalidElId = 3L; //not of VirtualRouterProviderType + + long validProviderId = 1L; + long nonExistingProviderId = 2L; + long invalidProviderId = 3L; + + + @Before + public void setUp() { + + ComponentContext.initComponentsLifeCycle(); + VirtualRouterProviderVO validElement = new VirtualRouterProviderVO(1, VirtualRouterProviderType.InternalLbVm); + VirtualRouterProviderVO invalidElement = new VirtualRouterProviderVO(1, VirtualRouterProviderType.VirtualRouter); + + Mockito.when(_vrProviderDao.findById(validElId)).thenReturn(validElement); + Mockito.when(_vrProviderDao.findById(invalidElId)).thenReturn(invalidElement); + + Mockito.when(_vrProviderDao.persist(validElement)).thenReturn(validElement); + + Mockito.when(_vrProviderDao.findByNspIdAndType(validProviderId, VirtualRouterProviderType.InternalLbVm)).thenReturn(validElement); + + PhysicalNetworkServiceProviderVO validProvider = new PhysicalNetworkServiceProviderVO(1, "InternalLoadBalancerElement"); + PhysicalNetworkServiceProviderVO invalidProvider = new PhysicalNetworkServiceProviderVO(1, "Invalid name!"); + + Mockito.when(_pNtwkProviderDao.findById(validProviderId)).thenReturn(validProvider); + Mockito.when(_pNtwkProviderDao.findById(invalidProviderId)).thenReturn(invalidProvider); + + Mockito.when(_vrProviderDao.persist(Mockito.any(VirtualRouterProviderVO.class))).thenReturn(validElement); + } + + //TESTS FOR getInternalLoadBalancerElement METHOD + + + @Test (expected = InvalidParameterValueException.class) + public void findNonExistingVm() { + String expectedExcText = null; + try { + _lbElSvc.getInternalLoadBalancerElement(nonExistingElId); + } catch (InvalidParameterValueException e) { + expectedExcText = e.getMessage(); + throw e; + } finally { + assertEquals("Test failed. The non-existing intenral lb provider was found" + + expectedExcText, expectedExcText, "Unable to find InternalLoadBalancerElementService by id"); + } + } + + + @Test (expected = InvalidParameterValueException.class) + public void findInvalidVm() { + String expectedExcText = null; + try { + _lbElSvc.getInternalLoadBalancerElement(invalidElId); + } catch (InvalidParameterValueException e) { + expectedExcText = e.getMessage(); + throw e; + } finally { + assertEquals("Test failed. The non-existing intenral lb provider was found" + + expectedExcText, expectedExcText, "Unable to find InternalLoadBalancerElementService by id"); + } + } + + + @Test + public void findValidVm() { + VirtualRouterProvider provider = null; + try { + provider = _lbElSvc.getInternalLoadBalancerElement(validElId); + } finally { + assertNotNull("Test failed. Couldn't find the VR provider by the valid id",provider); + } + } + + + //TESTS FOR configureInternalLoadBalancerElement METHOD + + @Test (expected = InvalidParameterValueException.class) + public void configureNonExistingVm() { + + _lbElSvc.configureInternalLoadBalancerElement(nonExistingElId, true); + + } + + + @Test (expected = InvalidParameterValueException.class) + public void ConfigureInvalidVm() { + _lbElSvc.configureInternalLoadBalancerElement(invalidElId, true); + } + + + @Test + public void enableProvider() { + VirtualRouterProvider provider = null; + try { + provider = _lbElSvc.configureInternalLoadBalancerElement(validElId, true); + } finally { + assertNotNull("Test failed. Couldn't find the VR provider by the valid id ",provider); + assertTrue("Test failed. The provider wasn't eanbled ", provider.isEnabled()); + } + } + + @Test + public void disableProvider() { + VirtualRouterProvider provider = null; + try { + provider = _lbElSvc.configureInternalLoadBalancerElement(validElId, false); + } finally { + assertNotNull("Test failed. Couldn't find the VR provider by the valid id ",provider); + assertFalse("Test failed. The provider wasn't disabled ", provider.isEnabled()); + } + } + + //TESTS FOR addInternalLoadBalancerElement METHOD + + @Test (expected = InvalidParameterValueException.class) + public void addToNonExistingProvider() { + + _lbElSvc.addInternalLoadBalancerElement(nonExistingProviderId); + + } + + @Test (expected = InvalidParameterValueException.class) + public void addToInvalidProvider() { + _lbElSvc.addInternalLoadBalancerElement(invalidProviderId); + } + + @Test + public void addToExistingProvider() { + _lbElSvc.addInternalLoadBalancerElement(validProviderId); + } + +} + + diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementTest.java b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementTest.java new file mode 100644 index 00000000000..f19612f6b0f --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementTest.java @@ -0,0 +1,226 @@ +// 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.internallbelement; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO; +import org.apache.cloudstack.network.element.InternalLoadBalancerElement; +import org.apache.cloudstack.network.lb.InternalLoadBalancerVMManager; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.configuration.ConfigurationManager; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.DataCenterVO; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; +import com.cloud.network.addr.PublicIp; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; +import com.cloud.network.dao.VirtualRouterProviderDao; +import com.cloud.network.element.VirtualRouterProviderVO; +import com.cloud.network.lb.LoadBalancingRule; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; +import com.cloud.user.AccountManager; +import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.net.Ip; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations="classpath:/lb_element.xml") +public class InternalLbElementTest { + //The class to test + @Inject InternalLoadBalancerElement _lbEl; + + //Mocked interfaces + @Inject AccountManager _accountMgr; + @Inject VirtualRouterProviderDao _vrProviderDao; + @Inject PhysicalNetworkServiceProviderDao _pNtwkProviderDao; + @Inject InternalLoadBalancerVMManager _internalLbMgr; + @Inject ConfigurationManager _configMgr; + + long validElId = 1L; + long nonExistingElId = 2L; + long invalidElId = 3L; //not of VirtualRouterProviderType + long notEnabledElId = 4L; + + long validProviderId = 1L; + long nonExistingProviderId = 2L; + long invalidProviderId = 3L; + + + @Before + public void setUp() { + + ComponentContext.initComponentsLifeCycle(); + VirtualRouterProviderVO validElement = new VirtualRouterProviderVO(1, VirtualRouterProviderType.InternalLbVm); + validElement.setEnabled(true); + VirtualRouterProviderVO invalidElement = new VirtualRouterProviderVO(1, VirtualRouterProviderType.VirtualRouter); + VirtualRouterProviderVO notEnabledElement = new VirtualRouterProviderVO(1, VirtualRouterProviderType.InternalLbVm); + + Mockito.when(_vrProviderDao.findByNspIdAndType(validElId, VirtualRouterProviderType.InternalLbVm)).thenReturn(validElement); + Mockito.when(_vrProviderDao.findByNspIdAndType(invalidElId, VirtualRouterProviderType.InternalLbVm)).thenReturn(invalidElement); + Mockito.when(_vrProviderDao.findByNspIdAndType(notEnabledElId, VirtualRouterProviderType.InternalLbVm)).thenReturn(notEnabledElement); + + Mockito.when(_vrProviderDao.persist(validElement)).thenReturn(validElement); + + Mockito.when(_vrProviderDao.findByNspIdAndType(validProviderId, VirtualRouterProviderType.InternalLbVm)).thenReturn(validElement); + + PhysicalNetworkServiceProviderVO validProvider = new PhysicalNetworkServiceProviderVO(1, "InternalLoadBalancerElement"); + PhysicalNetworkServiceProviderVO invalidProvider = new PhysicalNetworkServiceProviderVO(1, "Invalid name!"); + + Mockito.when(_pNtwkProviderDao.findById(validProviderId)).thenReturn(validProvider); + Mockito.when(_pNtwkProviderDao.findById(invalidProviderId)).thenReturn(invalidProvider); + + Mockito.when(_vrProviderDao.persist(Mockito.any(VirtualRouterProviderVO.class))).thenReturn(validElement); + + DataCenterVO dc = new DataCenterVO + (1L, null, null, null, null, null, null, null, null, null, NetworkType.Advanced, null, null); + Mockito.when(_configMgr.getZone(Mockito.anyLong())).thenReturn(dc); + } + + //TEST FOR getProvider() method + + @Test + public void verifyProviderName() { + Provider pr = _lbEl.getProvider(); + assertEquals("Wrong provider is returned", pr.getName(), Provider.InternalLbVm.getName()); + } + + //TEST FOR isReady() METHOD + + @Test + public void verifyValidProviderState() { + PhysicalNetworkServiceProviderVO provider = new PhysicalNetworkServiceProviderVO(); + provider = setId(provider, validElId); + boolean isReady = _lbEl.isReady(provider); + assertTrue("Valid provider is returned as not ready", isReady); + } + + + @Test + public void verifyNonExistingProviderState() { + PhysicalNetworkServiceProviderVO provider = new PhysicalNetworkServiceProviderVO(); + provider = setId(provider, nonExistingElId); + boolean isReady = _lbEl.isReady(provider); + assertFalse("Non existing provider is returned as ready", isReady); + } + + + @Test + public void verifyInvalidProviderState() { + PhysicalNetworkServiceProviderVO provider = new PhysicalNetworkServiceProviderVO(); + provider = setId(provider, invalidElId); + boolean isReady = _lbEl.isReady(provider); + assertFalse("Not valid provider is returned as ready", isReady); + } + + @Test + public void verifyNotEnabledProviderState() { + PhysicalNetworkServiceProviderVO provider = new PhysicalNetworkServiceProviderVO(); + provider = setId(provider, notEnabledElId); + boolean isReady = _lbEl.isReady(provider); + assertFalse("Not enabled provider is returned as ready", isReady); + } + + //TEST FOR canEnableIndividualServices METHOD + @Test + public void verifyCanEnableIndividualSvc() { + boolean result = _lbEl.canEnableIndividualServices(); + assertTrue("Wrong value is returned by canEnableIndividualSvc", result); + } + + //TEST FOR verifyServicesCombination METHOD + @Test + public void verifyServicesCombination() { + boolean result = _lbEl.verifyServicesCombination(new HashSet()); + assertTrue("Wrong value is returned by verifyServicesCombination", result); + } + + + //TEST FOR applyIps METHOD + @Test + public void verifyApplyIps() throws ResourceUnavailableException { + List ips = new ArrayList(); + boolean result = _lbEl.applyIps(new NetworkVO(), ips, new HashSet()); + assertTrue("Wrong value is returned by applyIps method", result); + } + + + //TEST FOR updateHealthChecks METHOD + @Test + public void verifyUpdateHealthChecks() throws ResourceUnavailableException { + List check = _lbEl.updateHealthChecks(new NetworkVO(), new ArrayList()); + assertNull("Wrong value is returned by updateHealthChecks method", check); + } + + //TEST FOR validateLBRule METHOD + @Test + public void verifyValidateLBRule() throws ResourceUnavailableException { + ApplicationLoadBalancerRuleVO lb = new ApplicationLoadBalancerRuleVO(null, null, 22, 22, "roundrobin", + 1L, 1L, 1L, new Ip("10.10.10.1"), 1L, Scheme.Internal); + lb.setState(FirewallRule.State.Add); + + LoadBalancingRule rule = new LoadBalancingRule(lb, null, + null, null, new Ip("10.10.10.1")); + + + boolean result = _lbEl.validateLBRule(new NetworkVO(), rule); + assertTrue("Wrong value is returned by validateLBRule method", result); + } + + + private static PhysicalNetworkServiceProviderVO setId(PhysicalNetworkServiceProviderVO vo, long id) { + PhysicalNetworkServiceProviderVO voToReturn = vo; + Class c = voToReturn.getClass(); + try { + Field f = c.getDeclaredField("id"); + f.setAccessible(true); + f.setLong(voToReturn, id); + } catch (NoSuchFieldException ex) { + return null; + } catch (IllegalAccessException ex) { + return null; + } + + return voToReturn; + } + + + +} + + diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/InternalLBVMManagerTest.java b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/InternalLBVMManagerTest.java new file mode 100644 index 00000000000..a19a82e30c1 --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/InternalLBVMManagerTest.java @@ -0,0 +1,388 @@ +// 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.internallbvmmgr; + +import java.lang.reflect.Field; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import junit.framework.TestCase; + +import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO; +import org.apache.cloudstack.network.lb.InternalLoadBalancerVMManager; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Answer; +import com.cloud.agent.manager.Commands; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.exception.AgentUnavailableException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.OperationTimedoutException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.NetworkModel; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.lb.LoadBalancingRule; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; +import com.cloud.user.User; +import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.Ip; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; + +/** + * Set of unittests for InternalLoadBalancerVMManager + * + */ + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations="classpath:/lb_mgr.xml") +public class InternalLBVMManagerTest extends TestCase { + //The interface to test + @Inject InternalLoadBalancerVMManager _lbVmMgr; + + //Mocked interfaces + @Inject AccountManager _accountMgr; + @Inject ServiceOfferingDao _svcOffDao; + @Inject DomainRouterDao _domainRouterDao; + @Inject NicDao _nicDao; + @Inject AgentManager _agentMgr; + @Inject NetworkModel _ntwkModel; + @Inject VirtualMachineManager _itMgr; + @Inject DataCenterDao _dcDao; + + long validNtwkId = 1L; + long invalidNtwkId = 2L; + String requestedIp = "10.1.1.1"; + DomainRouterVO vm = null; + NetworkVO ntwk = createNetwork(); + long validVmId = 1L; + long invalidVmId = 2L; + + @Before + public void setUp() { + //mock system offering creation as it's used by configure() method called by initComponentsLifeCycle + Mockito.when(_accountMgr.getAccount(1L)).thenReturn(new AccountVO()); + ServiceOfferingVO off = new ServiceOfferingVO("alena", 1, 1, + 1, 1, 1, false, "alena", false, false, null, false, VirtualMachine.Type.InternalLoadBalancerVm, false); + off = setId(off, 1); + Mockito.when(_svcOffDao.persistSystemServiceOffering(Mockito.any(ServiceOfferingVO.class))).thenReturn(off); + + ComponentContext.initComponentsLifeCycle(); + + vm = new DomainRouterVO(1L,off.getId(),1,"alena",1,HypervisorType.XenServer,1,1,1, + false, 0,false,null,false,false, + VirtualMachine.Type.InternalLoadBalancerVm, null); + vm.setRole(Role.INTERNAL_LB_VM); + vm = setId(vm, 1); + vm.setPrivateIpAddress("10.2.2.2"); + NicVO nic = new NicVO("somereserver", 1L, 1L, VirtualMachine.Type.InternalLoadBalancerVm); + nic.setIp4Address(requestedIp); + + List emptyList = new ArrayList(); + List nonEmptyList = new ArrayList(); + nonEmptyList.add(vm); + + Mockito.when(_domainRouterDao.listByNetworkAndRole(invalidNtwkId, Role.INTERNAL_LB_VM)).thenReturn(emptyList); + Mockito.when(_domainRouterDao.listByNetworkAndRole(validNtwkId, Role.INTERNAL_LB_VM)).thenReturn(nonEmptyList); + + Mockito.when(_nicDao.findByNtwkIdAndInstanceId(validNtwkId, 1)).thenReturn(nic); + Mockito.when(_nicDao.findByNtwkIdAndInstanceId(invalidNtwkId, 1)).thenReturn(nic); + + Answer answer= new Answer(null, true, null); + Answer[] answers = new Answer[1]; + answers[0] = answer; + + try { + Mockito.when(_agentMgr.send(Mockito.anyLong(), Mockito.any(Commands.class))).thenReturn(answers); + } catch (AgentUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (OperationTimedoutException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + createNetwork(); + Mockito.when(_ntwkModel.getNetwork(Mockito.anyLong())).thenReturn(ntwk); + + + Mockito.when(_itMgr.toNicTO(Mockito.any(NicProfile.class), Mockito.any(HypervisorType.class))).thenReturn(null); + Mockito.when(_domainRouterDao.findById(Mockito.anyLong())).thenReturn(vm); + DataCenterVO dc = new DataCenterVO + (1L, null, null, null, null, null, null, null, null, null, NetworkType.Advanced, null, null); + Mockito.when(_dcDao.findById(Mockito.anyLong())).thenReturn(dc); + + + try { + Mockito.when(_itMgr.expunge(Mockito.any(DomainRouterVO.class), Mockito.any(User.class), Mockito.any(Account.class))).thenReturn(true); + } catch (ResourceUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + Mockito.when(_domainRouterDao.findById(validVmId)).thenReturn(vm); + Mockito.when(_domainRouterDao.findById(invalidVmId)).thenReturn(null); + + } + + protected NetworkVO createNetwork() { + ntwk = new NetworkVO(); + try { + ntwk.setBroadcastUri(new URI("somevlan")); + } catch (URISyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + ntwk = setId(ntwk, 1L); + return ntwk; + } + + //TESTS FOR findInternalLbVms METHOD + + @Test + public void findInternalLbVmsForInvalidNetwork() { + List vms = _lbVmMgr.findInternalLbVms(invalidNtwkId, new Ip(requestedIp)); + assertTrue("Non empty vm list was returned for invalid network id", vms.isEmpty()); + } + + @Test + public void findInternalLbVmsForValidNetwork() { + List vms = _lbVmMgr.findInternalLbVms(validNtwkId, new Ip(requestedIp)); + assertTrue("Empty vm list was returned for valid network id", !vms.isEmpty()); + } + + + //TESTS FOR applyLoadBalancingRules METHOD + @Test + public void applyEmptyRulesSet() { + boolean result = false; + List vms = new ArrayList(); + try { + result = _lbVmMgr.applyLoadBalancingRules(new NetworkVO(), new ArrayList(), vms); + } catch (ResourceUnavailableException e) { + + } finally { + assertTrue("Got failure when tried to apply empty list of rules", result); + } + } + + @Test (expected = CloudRuntimeException.class) + public void applyWithEmptyVmsSet() { + boolean result = false; + List vms = new ArrayList(); + List rules = new ArrayList(); + LoadBalancingRule rule = new LoadBalancingRule(null, null, + null, null, null); + + rules.add(rule); + try { + result = _lbVmMgr.applyLoadBalancingRules(new NetworkVO(), rules, vms); + } catch (ResourceUnavailableException e) { + } finally { + assertFalse("Got success when tried to apply with the empty internal lb vm list", result); + } + } + + @Test (expected = ResourceUnavailableException.class) + public void applyToVmInStartingState() throws ResourceUnavailableException { + boolean result = false; + List vms = new ArrayList(); + vm.setState(State.Starting); + vms.add(vm); + + List rules = new ArrayList(); + LoadBalancingRule rule = new LoadBalancingRule(null, null, + null, null, null); + + rules.add(rule); + try { + result = _lbVmMgr.applyLoadBalancingRules(new NetworkVO(), rules, vms); + } finally { + assertFalse("Rules were applied to vm in Starting state", result); + } + } + + + @Test + public void applyToVmInStoppedState() throws ResourceUnavailableException { + boolean result = false; + List vms = new ArrayList(); + vm.setState(State.Stopped); + vms.add(vm); + + List rules = new ArrayList(); + LoadBalancingRule rule = new LoadBalancingRule(null, null, + null, null, null); + + rules.add(rule); + try { + result = _lbVmMgr.applyLoadBalancingRules(new NetworkVO(), rules, vms); + } finally { + assertTrue("Rules failed to apply to vm in Stopped state", result); + } + } + + + @Test + public void applyToVmInStoppingState() throws ResourceUnavailableException { + boolean result = false; + List vms = new ArrayList(); + vm.setState(State.Stopping); + vms.add(vm); + + List rules = new ArrayList(); + LoadBalancingRule rule = new LoadBalancingRule(null, null, + null, null, null); + + rules.add(rule); + try { + result = _lbVmMgr.applyLoadBalancingRules(new NetworkVO(), rules, vms); + } finally { + assertTrue("Rules failed to apply to vm in Stopping state", result); + } + } + + + @Test + public void applyToVmInRunningState() throws ResourceUnavailableException { + boolean result = false; + List vms = new ArrayList(); + vm.setState(State.Running); + vms.add(vm); + + List rules = new ArrayList(); + ApplicationLoadBalancerRuleVO lb = new ApplicationLoadBalancerRuleVO(null, null, 22, 22, "roundrobin", + 1L, 1L, 1L, new Ip(requestedIp), 1L, Scheme.Internal); + lb.setState(FirewallRule.State.Add); + + LoadBalancingRule rule = new LoadBalancingRule(lb, null, + null, null, new Ip(requestedIp)); + + rules.add(rule); + + ntwk.getId(); + + try { + result = _lbVmMgr.applyLoadBalancingRules(ntwk, rules, vms); + } finally { + assertTrue("Rules failed to apply to vm in Running state", result); + } + } + + + //TESTS FOR destroyInternalLbVm METHOD + @Test + public void destroyNonExistingVM() throws ResourceUnavailableException, ConcurrentOperationException { + boolean result = false; + + try { + result = _lbVmMgr.destroyInternalLbVm(invalidVmId, new AccountVO(), 1L); + } finally { + assertTrue("Failed to destroy non-existing vm", result); + } + } + + @Test + public void destroyExistingVM() throws ResourceUnavailableException, ConcurrentOperationException { + boolean result = false; + + try { + result = _lbVmMgr.destroyInternalLbVm(validVmId, new AccountVO(), 1L); + } finally { + assertTrue("Failed to destroy valid vm", result); + } + } + + + private static ServiceOfferingVO setId(ServiceOfferingVO vo, long id) { + ServiceOfferingVO voToReturn = vo; + Class c = voToReturn.getClass(); + try { + Field f = c.getSuperclass().getDeclaredField("id"); + f.setAccessible(true); + f.setLong(voToReturn, id); + } catch (NoSuchFieldException ex) { + return null; + } catch (IllegalAccessException ex) { + return null; + } + + return voToReturn; + } + + + private static NetworkVO setId(NetworkVO vo, long id) { + NetworkVO voToReturn = vo; + Class c = voToReturn.getClass(); + try { + Field f = c.getDeclaredField("id"); + f.setAccessible(true); + f.setLong(voToReturn, id); + } catch (NoSuchFieldException ex) { + return null; + } catch (IllegalAccessException ex) { + return null; + } + + return voToReturn; + } + + private static DomainRouterVO setId(DomainRouterVO vo, long id) { + DomainRouterVO voToReturn = vo; + Class c = voToReturn.getClass(); + try { + Field f = c.getSuperclass().getDeclaredField("id"); + f.setAccessible(true); + f.setLong(voToReturn, id); + } catch (NoSuchFieldException ex) { + return null; + } catch (IllegalAccessException ex) { + return null; + } + + return voToReturn; + } + +} diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/InternalLBVMServiceTest.java b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/InternalLBVMServiceTest.java new file mode 100644 index 00000000000..75f54faf8f0 --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/InternalLBVMServiceTest.java @@ -0,0 +1,291 @@ +// 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.internallbvmmgr; + +import java.lang.reflect.Field; +import java.util.Map; + +import javax.inject.Inject; + +import junit.framework.TestCase; + +import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.cloud.deploy.DeploymentPlan; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.OperationTimedoutException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.StorageUnavailableException; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; +import com.cloud.user.User; +import com.cloud.utils.component.ComponentContext; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.dao.DomainRouterDao; + +/** + * Set of unittests for InternalLoadBalancerVMService + * + */ + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations="classpath:/lb_svc.xml") +@SuppressWarnings("unchecked") +public class InternalLBVMServiceTest extends TestCase { + //The interface to test + @Inject InternalLoadBalancerVMService _lbVmSvc; + + //Mocked interfaces + @Inject AccountManager _accountMgr; + @Inject ServiceOfferingDao _svcOffDao; + @Inject DomainRouterDao _domainRouterDao; + @Inject VirtualMachineManager _itMgr; + + long validVmId = 1L; + long nonExistingVmId = 2L; + long nonInternalLbVmId = 3L; + + @Before + public void setUp() { + //mock system offering creation as it's used by configure() method called by initComponentsLifeCycle + Mockito.when(_accountMgr.getAccount(1L)).thenReturn(new AccountVO()); + ServiceOfferingVO off = new ServiceOfferingVO("alena", 1, 1, + 1, 1, 1, false, "alena", false, false, null, false, VirtualMachine.Type.InternalLoadBalancerVm, false); + off = setId(off, 1); + Mockito.when(_svcOffDao.persistSystemServiceOffering(Mockito.any(ServiceOfferingVO.class))).thenReturn(off); + + ComponentContext.initComponentsLifeCycle(); + + DomainRouterVO validVm = new DomainRouterVO(validVmId,off.getId(),1,"alena",1,HypervisorType.XenServer,1,1,1, + false, 0,false,null,false,false, + VirtualMachine.Type.InternalLoadBalancerVm, null); + validVm.setRole(Role.INTERNAL_LB_VM); + DomainRouterVO nonInternalLbVm = new DomainRouterVO(validVmId,off.getId(),1,"alena",1,HypervisorType.XenServer,1,1,1, + false, 0,false,null,false,false, + VirtualMachine.Type.DomainRouter, null); + nonInternalLbVm.setRole(Role.VIRTUAL_ROUTER); + + Mockito.when(_domainRouterDao.findById(validVmId)).thenReturn(validVm); + Mockito.when(_domainRouterDao.findById(nonExistingVmId)).thenReturn(null); + Mockito.when(_domainRouterDao.findById(nonInternalLbVmId)).thenReturn(nonInternalLbVm); + + try { + Mockito.when(_itMgr.start(Mockito.any(DomainRouterVO.class), + Mockito.any(Map.class), Mockito.any(User.class), Mockito.any(Account.class), Mockito.any(DeploymentPlan.class))).thenReturn(validVm); + } catch (InsufficientCapacityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ResourceUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + try { + Mockito.when(_itMgr.advanceStop(Mockito.any(DomainRouterVO.class), Mockito.any(Boolean.class), Mockito.any(User.class), Mockito.any(Account.class))).thenReturn(true); + } catch (ResourceUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (OperationTimedoutException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ConcurrentOperationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + //TESTS FOR START COMMAND + + + @Test (expected = InvalidParameterValueException.class) + public void startNonExistingVm() { + String expectedExcText = null; + try { + _lbVmSvc.startInternalLbVm(nonExistingVmId, _accountMgr.getAccount(1L), 1L); + } catch (StorageUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InsufficientCapacityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ConcurrentOperationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ResourceUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvalidParameterValueException e) { + expectedExcText = e.getMessage(); + throw e; + } finally { + assertEquals("Test failed. The non-existing internal lb vm was attempted to start" + + expectedExcText, expectedExcText, "Can't find internal lb vm by id specified"); + } + } + + @Test (expected = InvalidParameterValueException.class) + public void startNonInternalLbVmVm() { + String expectedExcText = null; + try { + _lbVmSvc.startInternalLbVm(nonInternalLbVmId, _accountMgr.getAccount(1L), 1L); + } catch (StorageUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InsufficientCapacityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ConcurrentOperationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ResourceUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }catch (InvalidParameterValueException e) { + expectedExcText = e.getMessage(); + throw e; + } finally { + assertEquals("Test failed. The existing vm of not Internal lb vm type was attempted to start" + + expectedExcText, expectedExcText, "Can't find internal lb vm by id specified"); + } + } + + @Test + public void startValidLbVmVm() { + VirtualRouter vr = null; + try { + vr = _lbVmSvc.startInternalLbVm(validVmId, _accountMgr.getAccount(1L), 1L); + } catch (StorageUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InsufficientCapacityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ConcurrentOperationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ResourceUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + assertNotNull("Internal LB vm is null which means it failed to start " + vr, vr); + } + } + + + //TEST FOR STOP COMMAND + @Test (expected = InvalidParameterValueException.class) + public void stopNonExistingVm() { + String expectedExcText = null; + try { + _lbVmSvc.stopInternalLbVm(nonExistingVmId, false,_accountMgr.getAccount(1L), 1L); + } catch (StorageUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ConcurrentOperationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ResourceUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvalidParameterValueException e) { + expectedExcText = e.getMessage(); + throw e; + } finally { + assertEquals("Test failed. The non-existing internal lb vm was attempted to stop" + + expectedExcText, expectedExcText, "Can't find internal lb vm by id specified"); + } + } + + + @Test (expected = InvalidParameterValueException.class) + public void stopNonInternalLbVmVm() { + String expectedExcText = null; + try { + _lbVmSvc.stopInternalLbVm(nonInternalLbVmId, false, _accountMgr.getAccount(1L), 1L); + } catch (StorageUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ConcurrentOperationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ResourceUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }catch (InvalidParameterValueException e) { + expectedExcText = e.getMessage(); + throw e; + } finally { + assertEquals("Test failed. The existing vm of not Internal lb vm type was attempted to stop" + + expectedExcText, expectedExcText, "Can't find internal lb vm by id specified"); + } + } + + + @Test + public void stopValidLbVmVm() { + VirtualRouter vr = null; + try { + vr = _lbVmSvc.stopInternalLbVm(validVmId, false, _accountMgr.getAccount(1L), 1L); + } catch (StorageUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ConcurrentOperationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ResourceUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + assertNotNull("Internal LB vm is null which means it failed to stop " + vr, vr); + } + } + + + + private static ServiceOfferingVO setId(ServiceOfferingVO vo, long id) { + ServiceOfferingVO voToReturn = vo; + Class c = voToReturn.getClass(); + try { + Field f = c.getSuperclass().getDeclaredField("id"); + f.setAccessible(true); + f.setLong(voToReturn, id); + } catch (NoSuchFieldException ex) { + return null; + } catch (IllegalAccessException ex) { + return null; + } + + return voToReturn; + } +} diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/LbChildTestConfiguration.java b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/LbChildTestConfiguration.java new file mode 100644 index 00000000000..0f24f963ae6 --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/LbChildTestConfiguration.java @@ -0,0 +1,170 @@ +// 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.internallbvmmgr; + +import java.io.IOException; + +import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; +import org.apache.cloudstack.test.utils.SpringUtils; +import org.mockito.Mockito; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.ComponentScan.Filter; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.classreading.MetadataReaderFactory; +import org.springframework.core.type.filter.TypeFilter; + +import com.cloud.agent.AgentManager; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.dao.AccountVlanMapDaoImpl; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkModel; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.VirtualRouterProviderDao; +import com.cloud.network.lb.LoadBalancingRulesManager; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.resource.ResourceManager; +import com.cloud.server.ConfigurationServer; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.user.AccountManager; +import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; + +@Configuration +@ComponentScan( + basePackageClasses={ + AccountVlanMapDaoImpl.class + }, + includeFilters={@Filter(value=LbChildTestConfiguration.Library.class, type=FilterType.CUSTOM)}, + useDefaultFilters=false + ) + + public class LbChildTestConfiguration { + + public static class Library implements TypeFilter { + + + @Bean + public AccountManager accountManager() { + return Mockito.mock(AccountManager.class); + } + + @Bean + public VirtualMachineManager virtualMachineManager() { + return Mockito.mock(VirtualMachineManager.class); + } + + @Bean + public DomainRouterDao domainRouterDao() { + return Mockito.mock(DomainRouterDao.class); + } + + @Bean + public ConfigurationDao configurationDao() { + return Mockito.mock(ConfigurationDao.class); + } + + @Bean + public VirtualRouterProviderDao virtualRouterProviderDao() { + return Mockito.mock(VirtualRouterProviderDao.class); + } + + @Bean + public ApplicationLoadBalancerRuleDao applicationLoadBalancerRuleDao() { + return Mockito.mock(ApplicationLoadBalancerRuleDao.class); + } + + @Bean + public NetworkModel networkModel() { + return Mockito.mock(NetworkModel.class); + } + + @Bean + public LoadBalancingRulesManager loadBalancingRulesManager() { + return Mockito.mock(LoadBalancingRulesManager.class); + } + + @Bean + public NicDao nicDao() { + return Mockito.mock(NicDao.class); + } + + @Bean + public NetworkDao networkDao() { + return Mockito.mock(NetworkDao.class); + } + + @Bean + public NetworkManager networkManager() { + return Mockito.mock(NetworkManager.class); + } + + @Bean + public ServiceOfferingDao serviceOfferingDao() { + return Mockito.mock(ServiceOfferingDao.class); + } + + @Bean + public PhysicalNetworkServiceProviderDao physicalNetworkServiceProviderDao() { + return Mockito.mock(PhysicalNetworkServiceProviderDao.class); + } + + @Bean + public NetworkOfferingDao networkOfferingDao() { + return Mockito.mock(NetworkOfferingDao.class); + } + + @Bean + public VMTemplateDao vmTemplateDao() { + return Mockito.mock(VMTemplateDao.class); + } + + @Bean + public ResourceManager resourceManager() { + return Mockito.mock(ResourceManager.class); + } + + @Bean + public AgentManager agentManager() { + return Mockito.mock(AgentManager.class); + } + + @Bean + public DataCenterDao dataCenterDao() { + return Mockito.mock(DataCenterDao.class); + } + + @Bean + public ConfigurationServer configurationServer() { + return Mockito.mock(ConfigurationServer.class); + } + + @Override + public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { + mdr.getClassMetadata().getClassName(); + ComponentScan cs = LbChildTestConfiguration.class.getAnnotation(ComponentScan.class); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + } + + } +} diff --git a/plugins/network-elements/internal-loadbalancer/test/resources/lb_element.xml b/plugins/network-elements/internal-loadbalancer/test/resources/lb_element.xml new file mode 100644 index 00000000000..5dec9c314f6 --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/test/resources/lb_element.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/network-elements/internal-loadbalancer/test/resources/lb_mgr.xml b/plugins/network-elements/internal-loadbalancer/test/resources/lb_mgr.xml new file mode 100644 index 00000000000..1ad6403861c --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/test/resources/lb_mgr.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/network-elements/internal-loadbalancer/test/resources/lb_svc.xml b/plugins/network-elements/internal-loadbalancer/test/resources/lb_svc.xml new file mode 100644 index 00000000000..fa822f35302 --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/test/resources/lb_svc.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java index b8144301810..4f2a0a1da42 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java @@ -16,6 +16,22 @@ // under the License. package com.cloud.network.element; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice; +import org.apache.cloudstack.region.gslb.GslbServiceProvider; +import org.apache.log4j.Logger; + import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.routing.GlobalLoadBalancerConfigCommand; @@ -27,7 +43,11 @@ import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.to.LoadBalancerTO; import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.api.ApiDBUtils; -import com.cloud.api.commands.*; +import com.cloud.api.commands.AddNetscalerLoadBalancerCmd; +import com.cloud.api.commands.ConfigureNetscalerLoadBalancerCmd; +import com.cloud.api.commands.DeleteNetscalerLoadBalancerCmd; +import com.cloud.api.commands.ListNetscalerLoadBalancerNetworksCmd; +import com.cloud.api.commands.ListNetscalerLoadBalancersCmd; import com.cloud.api.response.NetscalerLoadBalancerResponse; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; @@ -39,27 +59,48 @@ import com.cloud.dc.HostPodVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterIpAddressDao; import com.cloud.deploy.DeployDestination; -import com.cloud.exception.*; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientNetworkCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDetailsDao; -import com.cloud.network.*; +import com.cloud.network.ExternalLoadBalancerDeviceManager; +import com.cloud.network.ExternalLoadBalancerDeviceManagerImpl; +import com.cloud.network.IpAddress; +import com.cloud.network.NetScalerPodVO; +import com.cloud.network.Network; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; +import com.cloud.network.NetworkModel; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PublicIpAddress; import com.cloud.network.as.AutoScaleCounter; import com.cloud.network.as.AutoScaleCounter.AutoScaleCounterType; -import com.cloud.network.dao.*; +import com.cloud.network.dao.ExternalLoadBalancerDeviceDao; +import com.cloud.network.dao.ExternalLoadBalancerDeviceVO; import com.cloud.network.dao.ExternalLoadBalancerDeviceVO.LBDeviceState; +import com.cloud.network.dao.NetScalerPodDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkExternalLoadBalancerDao; +import com.cloud.network.dao.NetworkExternalLoadBalancerVO; +import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.resource.NetscalerResource; import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.LbStickinessMethod; import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; +import com.cloud.network.rules.LoadBalancerContainer; import com.cloud.network.rules.StaticNat; import com.cloud.network.vpc.PrivateGateway; import com.cloud.network.vpc.StaticRouteProfile; @@ -75,15 +116,6 @@ import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; import com.google.gson.Gson; -import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice; -import org.apache.cloudstack.region.gslb.GslbServiceProvider; -import org.apache.log4j.Logger; - -import javax.ejb.Local; -import javax.inject.Inject; -import java.net.URI; -import java.util.*; @Local(value = {NetworkElement.class, StaticNatServiceProvider.class, LoadBalancingServiceProvider.class, GslbServiceProvider.class}) public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl implements LoadBalancingServiceProvider, @@ -207,6 +239,10 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl if (!canHandle(config, Service.Lb)) { return false; } + + if (canHandleLbRules(rules)) { + return false; + } if (isBasicZoneNetwok(config)) { return applyElasticLoadBalancerRules(config, rules); @@ -237,6 +273,9 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl // Specifies that load balancing rules can only be made with public IPs that aren't source NAT IPs lbCapabilities.put(Capability.LoadBalancingSupportedIps, "additional"); + // Supports only Public load balancing + lbCapabilities.put(Capability.LbSchemes, LoadBalancerContainer.Scheme.Public.toString()); + // Specifies that load balancing rules can support autoscaling and the list of counters it supports AutoScaleCounter counter; List counterList = new ArrayList(); @@ -644,14 +683,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl return this; } - public boolean applyElasticLoadBalancerRules(Network network, List rules) throws ResourceUnavailableException { - - List loadBalancingRules = new ArrayList(); - for (FirewallRule rule : rules) { - if (rule.getPurpose().equals(Purpose.LoadBalancing)) { - loadBalancingRules.add((LoadBalancingRule) rule); - } - } + public boolean applyElasticLoadBalancerRules(Network network, List loadBalancingRules) throws ResourceUnavailableException { if (loadBalancingRules == null || loadBalancingRules.isEmpty()) { return true; @@ -682,7 +714,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl String protocol = rule.getProtocol(); String algorithm = rule.getAlgorithm(); String lbUuid = rule.getUuid(); - String srcIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress().addr(); + String srcIp = rule.getSourceIp().addr(); int srcPort = rule.getSourcePortStart(); List destinations = rule.getDestinations(); @@ -813,16 +845,10 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl return null; } - public List getElasticLBRulesHealthCheck(Network network, List rules) + public List getElasticLBRulesHealthCheck(Network network, List loadBalancingRules) throws ResourceUnavailableException { HealthCheckLBConfigAnswer answer = null; - List loadBalancingRules = new ArrayList(); - for (FirewallRule rule : rules) { - if (rule.getPurpose().equals(Purpose.LoadBalancing)) { - loadBalancingRules.add((LoadBalancingRule) rule); - } - } if (loadBalancingRules == null || loadBalancingRules.isEmpty()) { return null; @@ -849,7 +875,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl String protocol = rule.getProtocol(); String algorithm = rule.getAlgorithm(); String lbUuid = rule.getUuid(); - String srcIp = _networkMgr.getIp(rule.getSourceIpAddressId()).getAddress().addr(); + String srcIp = rule.getSourceIp().addr(); int srcPort = rule.getSourcePortStart(); List destinations = rule.getDestinations(); @@ -874,7 +900,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl public List updateHealthChecks(Network network, List lbrules) { - if (canHandle(network, Service.Lb)) { + if (canHandle(network, Service.Lb) && canHandleLbRules(lbrules)) { try { if (isBasicZoneNetwok(network)) { @@ -891,7 +917,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl return null; } - public List getLBHealthChecks(Network network, List rules) + public List getLBHealthChecks(Network network, List rules) throws ResourceUnavailableException { return super.getLBHealthChecks(network, rules); } @@ -960,6 +986,22 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } return null; } + + private boolean canHandleLbRules(List rules) { + Map lbCaps = this.getCapabilities().get(Service.Lb); + if (!lbCaps.isEmpty()) { + String schemeCaps = lbCaps.get(Capability.LbSchemes); + if (schemeCaps != null) { + for (LoadBalancingRule rule : rules) { + if (!schemeCaps.contains(rule.getScheme().toString())) { + s_logger.debug("Scheme " + rules.get(0).getScheme() + " is not supported by the provider " + this.getName()); + return false; + } + } + } + } + return true; + } @Override public boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext context) diff --git a/plugins/pom.xml b/plugins/pom.xml index b9402718b89..e49fac9533a 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -62,6 +62,7 @@ storage/volume/default alert-handlers/snmp-alerts alert-handlers/syslog-alerts + network-elements/internal-loadbalancer diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index b8eea12b4cf..fce1f719086 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -25,8 +25,6 @@ import java.util.Set; import javax.annotation.PostConstruct; import javax.inject.Inject; -import com.cloud.network.rules.LoadBalancer; -import com.cloud.region.ha.GlobalLoadBalancingRulesService; import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.affinity.dao.AffinityGroupDao; @@ -37,8 +35,8 @@ import org.apache.cloudstack.api.response.AsyncJobResponse; import org.apache.cloudstack.api.response.DiskOfferingResponse; import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.EventResponse; -import org.apache.cloudstack.api.response.HostResponse; import org.apache.cloudstack.api.response.HostForMigrationResponse; +import org.apache.cloudstack.api.response.HostResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; import org.apache.cloudstack.api.response.ProjectAccountResponse; import org.apache.cloudstack.api.response.ProjectInvitationResponse; @@ -52,6 +50,7 @@ import org.apache.cloudstack.api.response.UserResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.api.response.VolumeResponse; import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.springframework.stereotype.Component; @@ -157,6 +156,8 @@ import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao; import com.cloud.network.as.dao.AutoScaleVmProfileDao; import com.cloud.network.as.dao.ConditionDao; import com.cloud.network.as.dao.CounterDao; +import com.cloud.network.dao.AccountGuestVlanMapDao; +import com.cloud.network.dao.AccountGuestVlanMapVO; import com.cloud.network.dao.FirewallRulesCidrsDao; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; @@ -181,6 +182,7 @@ import com.cloud.network.dao.Site2SiteVpnGatewayDao; import com.cloud.network.dao.Site2SiteVpnGatewayVO; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRuleVO; +import com.cloud.network.rules.LoadBalancer; import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.SecurityGroupVO; @@ -204,6 +206,7 @@ import com.cloud.projects.Project; import com.cloud.projects.ProjectAccount; import com.cloud.projects.ProjectInvitation; import com.cloud.projects.ProjectService; +import com.cloud.region.ha.GlobalLoadBalancingRulesService; import com.cloud.resource.ResourceManager; import com.cloud.server.Criteria; import com.cloud.server.ManagementServer; @@ -499,6 +502,7 @@ public class ApiDBUtils { @Inject private VMSnapshotDao vmSnapshotDao; @Inject private NicSecondaryIpDao nicSecondaryIpDao; @Inject private VpcProvisioningService vpcProvSvc; + @Inject private ApplicationLoadBalancerRuleDao _appLbDao; @Inject private AffinityGroupDao affinityGroupDao; @Inject private AffinityGroupJoinDao affinityGroupJoinDao; @Inject private GlobalLoadBalancingRulesService gslbService; diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index d7eaa2604b1..d5960abba8b 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -44,6 +44,9 @@ import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.ResponseGenerator; import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd; import org.apache.cloudstack.api.response.AccountResponse; +import org.apache.cloudstack.api.response.ApplicationLoadBalancerInstanceResponse; +import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse; +import org.apache.cloudstack.api.response.ApplicationLoadBalancerRuleResponse; import org.apache.cloudstack.api.response.AsyncJobResponse; import org.apache.cloudstack.api.response.AutoScalePolicyResponse; import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse; @@ -72,6 +75,7 @@ import org.apache.cloudstack.api.response.HostResponse; import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse; import org.apache.cloudstack.api.response.IPAddressResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; +import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse; import org.apache.cloudstack.api.response.IpForwardingRuleResponse; import org.apache.cloudstack.api.response.IsolationMethodResponse; import org.apache.cloudstack.api.response.LBHealthCheckPolicyResponse; @@ -130,6 +134,7 @@ import org.apache.cloudstack.api.response.VpcOfferingResponse; import org.apache.cloudstack.api.response.VpcResponse; import org.apache.cloudstack.api.response.VpnUsersResponse; import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule; import org.apache.cloudstack.region.Region; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.usage.Usage; @@ -189,6 +194,7 @@ import com.cloud.network.Network; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; +import com.cloud.network.NetworkModel; import com.cloud.network.NetworkProfile; import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.TrafficType; @@ -216,6 +222,7 @@ import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.HealthCheckPolicy; import com.cloud.network.rules.LoadBalancer; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.StaticNatRule; import com.cloud.network.rules.StickinessPolicy; @@ -229,6 +236,7 @@ import com.cloud.network.vpc.Vpc; import com.cloud.network.vpc.VpcOffering; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; +import com.cloud.offering.NetworkOffering.Detail; import com.cloud.offering.ServiceOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.org.Cluster; @@ -269,6 +277,7 @@ import com.cloud.user.UserContext; import com.cloud.uservm.UserVm; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; +import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; import com.cloud.vm.ConsoleProxyVO; import com.cloud.vm.InstanceGroup; @@ -289,6 +298,7 @@ public class ApiResponseHelper implements ResponseGenerator { private static final DecimalFormat s_percentFormat = new DecimalFormat("##.##"); @Inject private EntityManager _entityMgr = null; @Inject private UsageService _usageSvc = null; + @Inject NetworkModel _ntwkModel; @Override public UserResponse createUserResponse(User user) { @@ -750,7 +760,7 @@ public class ApiResponseHelper implements ResponseGenerator { } //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, loadBalancer.getId()); + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.LoadBalancer, loadBalancer.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); @@ -2263,6 +2273,13 @@ public class ApiResponseHelper implements ResponseGenerator { response.setForVpc(ApiDBUtils.isOfferingForVpc(offering)); response.setServices(serviceResponses); + + //set network offering details + Map details = _ntwkModel.getNtwkOffDetails(offering.getId()); + if (details != null && !details.isEmpty()) { + response.setDetails(details); + } + response.setObjectName("networkoffering"); return response; } @@ -2826,6 +2843,11 @@ public class ApiResponseHelper implements ResponseGenerator { @Override public VirtualRouterProviderResponse createVirtualRouterProviderResponse(VirtualRouterProvider result) { + //generate only response of the VR/VPCVR provider type + if (!(result.getType() == VirtualRouterProvider.VirtualRouterProviderType.VirtualRouter + || result.getType() == VirtualRouterProvider.VirtualRouterProviderType.VPCVirtualRouter)) { + return null; + } VirtualRouterProviderResponse response = new VirtualRouterProviderResponse(); response.setId(result.getUuid()); PhysicalNetworkServiceProvider nsp = ApiDBUtils.findPhysicalNetworkServiceProviderById(result.getNspId()); @@ -3689,6 +3711,73 @@ public class ApiResponseHelper implements ResponseGenerator { return response; } + + @Override + public ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb, Map lbInstances) { + + ApplicationLoadBalancerResponse lbResponse = new ApplicationLoadBalancerResponse(); + lbResponse.setId(lb.getUuid()); + lbResponse.setName(lb.getName()); + lbResponse.setDescription(lb.getDescription()); + lbResponse.setAlgorithm(lb.getAlgorithm()); + Network nw = ApiDBUtils.findNetworkById(lb.getNetworkId()); + lbResponse.setNetworkId(nw.getUuid()); + populateOwner(lbResponse, lb); + + if (lb.getScheme() == Scheme.Internal) { + lbResponse.setSourceIp(lb.getSourceIp().addr()); + //TODO - create the view for the load balancer rule to reflect the network uuid + Network network = ApiDBUtils.findNetworkById(lb.getNetworkId()); + lbResponse.setSourceIpNetworkId(network.getUuid()); + } else { + //for public, populate the ip information from the ip address + IpAddress publicIp = ApiDBUtils.findIpAddressById(lb.getSourceIpAddressId()); + lbResponse.setSourceIp(publicIp.getAddress().addr()); + Network ntwk = ApiDBUtils.findNetworkById(publicIp.getNetworkId()); + lbResponse.setSourceIpNetworkId(ntwk.getUuid()); + } + + //set load balancer rules information (only one rule per load balancer in this release) + List ruleResponses = new ArrayList(); + ApplicationLoadBalancerRuleResponse ruleResponse = new ApplicationLoadBalancerRuleResponse(); + ruleResponse.setInstancePort(lb.getDefaultPortStart()); + ruleResponse.setSourcePort(lb.getSourcePortStart()); + String stateToSet = lb.getState().toString(); + if (stateToSet.equals(FirewallRule.State.Revoke)) { + stateToSet = "Deleting"; + } + ruleResponse.setState(stateToSet); + ruleResponse.setObjectName("loadbalancerrule"); + ruleResponses.add(ruleResponse); + lbResponse.setLbRules(ruleResponses); + + //set Lb instances information + List instanceResponses = new ArrayList(); + for (Ip ip : lbInstances.keySet()) { + ApplicationLoadBalancerInstanceResponse instanceResponse = new ApplicationLoadBalancerInstanceResponse(); + instanceResponse.setIpAddress(ip.addr()); + UserVm vm = lbInstances.get(ip); + instanceResponse.setId(vm.getUuid()); + instanceResponse.setName(vm.getInstanceName()); + instanceResponse.setObjectName("loadbalancerinstance"); + instanceResponses.add(instanceResponse); + } + + lbResponse.setLbInstances(instanceResponses); + + //set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.LoadBalancer, lb.getId()); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); + tagResponses.add(tagResponse); + } + lbResponse.setTags(tagResponses); + + lbResponse.setObjectName("loadbalancer"); + return lbResponse; + } + @Override public AffinityGroupResponse createAffinityGroupResponse(AffinityGroup group) { @@ -3719,8 +3808,25 @@ public class ApiResponseHelper implements ResponseGenerator { } } + + @Override + public InternalLoadBalancerElementResponse createInternalLbElementResponse(VirtualRouterProvider result) { + if (result.getType() != VirtualRouterProvider.VirtualRouterProviderType.InternalLbVm) { + return null; + } + InternalLoadBalancerElementResponse response = new InternalLoadBalancerElementResponse(); + response.setId(result.getUuid()); + PhysicalNetworkServiceProvider nsp = ApiDBUtils.findPhysicalNetworkServiceProviderById(result.getNspId()); + if (nsp != null) { + response.setNspId(nsp.getUuid()); + } + response.setEnabled(result.isEnabled()); + response.setObjectName("internalloadbalancerelement"); + return response; + } + @Override public IsolationMethodResponse createIsolationMethodResponse(IsolationType method) { IsolationMethodResponse response = new IsolationMethodResponse(); diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 50018e53efb..808b1efceb1 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -29,7 +29,9 @@ import javax.inject.Inject; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.affinity.AffinityGroupVMMapVO; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; +import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; +import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd; import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd; import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd; import org.apache.cloudstack.api.command.admin.user.ListUsersCmd; @@ -981,7 +983,21 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { @Override public ListResponse searchForRouters(ListRoutersCmd cmd) { - Pair, Integer> result = searchForRoutersInternal(cmd); + Pair, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), + cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), + cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), cmd.getZoneType()); + ListResponse response = new ListResponse(); + + List routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()])); + response.setResponses(routerResponses, result.second()); + return response; + } + + @Override + public ListResponse searchForInternalLbVms(ListInternalLBVMsCmd cmd) { + Pair, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), + cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), + cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), cmd.getZoneType()); ListResponse response = new ListResponse(); List routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()])); @@ -990,18 +1006,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } - private Pair, Integer> searchForRoutersInternal(ListRoutersCmd cmd) { - Long id = cmd.getId(); - String name = cmd.getRouterName(); - String state = cmd.getState(); - Long zoneId = cmd.getZoneId(); - String zoneType = cmd.getZoneType(); - Long pod = cmd.getPodId(); - Long hostId = cmd.getHostId(); - String keyword = cmd.getKeyword(); - Long networkId = cmd.getNetworkId(); - Long vpcId = cmd.getVpcId(); - Boolean forVpc = cmd.getForVpc(); + private Pair, Integer> searchForRoutersInternal(BaseListProjectAndAccountResourcesCmd cmd, Long id, + String name, String state, Long zoneId, Long podId, Long hostId, String keyword, Long networkId, Long vpcId, Boolean forVpc, String role, String zoneType) { + Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -1032,6 +1039,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); sb.and("hostId", sb.entity().getHostId(), SearchCriteria.Op.EQ); sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); + sb.and("role", sb.entity().getRole(), SearchCriteria.Op.EQ); if (forVpc != null) { if (forVpc) { @@ -1073,13 +1081,14 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sc.setParameters("dataCenterId", zoneId); } + if (podId != null) { + sc.setParameters("podId", podId); + } + if (zoneType != null) { sc.setParameters("dataCenterType", zoneType); } - if (pod != null) { - sc.setParameters("podId", pod); - } if (hostId != null) { sc.setParameters("hostId", hostId); @@ -1092,6 +1101,10 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { if (vpcId != null) { sc.setParameters("vpcId", vpcId); } + + if (role != null) { + sc.setParameters("role", role); + } // search VR details by ids Pair, Integer> uniqueVrPair = _routerJoinDao.searchAndCount(sc, searchFilter); diff --git a/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java index 125db17c760..a7a83de14a1 100644 --- a/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java @@ -32,6 +32,7 @@ import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.network.Networks.TrafficType; import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VirtualRouter.Role; import com.cloud.user.Account; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; @@ -156,6 +157,8 @@ public class DomainRouterJoinDaoImpl extends GenericDaoBase> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, Map> serviceCapabilityMap, - boolean specifyIpRanges, boolean isPersistent); + boolean specifyIpRanges, boolean isPersistent, Map details); Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, String vlanId, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException; diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 37ca793c556..fdc0ffbabe1 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -39,6 +39,7 @@ import javax.naming.NamingException; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; + import com.cloud.dc.*; import com.cloud.dc.dao.*; import com.cloud.user.*; @@ -81,6 +82,17 @@ import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.Vlan.VlanType; +import com.cloud.dc.VlanVO; +import com.cloud.dc.dao.AccountVlanMapDao; +import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.DataCenterIpAddressDao; +import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDao; +import com.cloud.dc.dao.DcDetailsDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.dc.dao.PodVlanMapDao; +import com.cloud.dc.dao.VlanDao; + import com.cloud.deploy.DataCenterDeployment; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; @@ -115,10 +127,12 @@ import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao; import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO; import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.vpc.VpcManager; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; +import com.cloud.offering.NetworkOffering.Detail; import com.cloud.offering.ServiceOffering; import com.cloud.offerings.NetworkOfferingServiceMapVO; import com.cloud.offerings.NetworkOfferingVO; @@ -1919,6 +1933,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati vmType = VirtualMachine.Type.ConsoleProxy; } else if (VirtualMachine.Type.SecondaryStorageVm.toString().toLowerCase().equals(vmTypeString)) { vmType = VirtualMachine.Type.SecondaryStorageVm; + } else if (VirtualMachine.Type.InternalLoadBalancerVm.toString().toLowerCase().equals(vmTypeString)) { + vmType = VirtualMachine.Type.InternalLoadBalancerVm; } else { throw new InvalidParameterValueException("Invalid systemVmType. Supported types are: " + VirtualMachine.Type.DomainRouter + ", " + VirtualMachine.Type.ConsoleProxy + ", " + VirtualMachine.Type.SecondaryStorageVm); @@ -3340,6 +3356,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati Network.GuestType guestType = null; boolean specifyIpRanges = cmd.getSpecifyIpRanges(); boolean isPersistent = cmd.getIsPersistent(); + Map detailsStr = cmd.getDetails(); // Verify traffic type for (TrafficType tType : TrafficType.values()) { @@ -3432,10 +3449,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati Network.Service service = Network.Service.getService(serviceStr); if (serviceProviderMap.containsKey(service)) { Set providers = new HashSet(); - // in Acton, don't allow to specify more than 1 provider per service - if (svcPrv.get(serviceStr) != null && svcPrv.get(serviceStr).size() > 1) { + // Allow to specify more than 1 provider per service only if the service is LB + if (!serviceStr.equalsIgnoreCase(Service.Lb.getName()) && svcPrv.get(serviceStr) != null && svcPrv.get(serviceStr).size() > 1) { throw new InvalidParameterValueException("In the current release only one provider can be " + - "specified for the service"); + "specified for the service if the service is not LB"); } for (String prvNameStr : svcPrv.get(serviceStr)) { // check if provider is supported @@ -3508,9 +3525,26 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati firewallProviderSet.add(firewallProvider); serviceProviderMap.put(Service.Firewall, firewallProviderSet); } + + Map details = new HashMap(); + if (detailsStr != null) { + for (String detailStr : detailsStr.keySet()) { + NetworkOffering.Detail offDetail = null; + for (NetworkOffering.Detail supportedDetail: NetworkOffering.Detail.values()) { + if (detailStr.equalsIgnoreCase(supportedDetail.toString())) { + offDetail = supportedDetail; + break; + } + } + if (offDetail == null) { + throw new InvalidParameterValueException("Unsupported detail " + detailStr); + } + details.put(offDetail, detailsStr.get(detailStr)); + } + } return createNetworkOffering(name, displayText, trafficType, tags, specifyVlan, availability, networkRate, serviceProviderMap, false, guestType, false, - serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges, isPersistent); + serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges, isPersistent, details); } void validateLoadBalancerServiceCapabilities(Map lbServiceCapabilityMap) { @@ -3539,8 +3573,16 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (!enabled && !disabled) { throw new InvalidParameterValueException("Unknown specified value for " + Capability.InlineMode.getName()); } + } else if (cap == Capability.LbSchemes) { + boolean internalLb = value.contains("internal"); + boolean publicLb = value.contains("public"); + if (!internalLb && !publicLb) { + throw new InvalidParameterValueException("Unknown specified value for " + Capability.LbSchemes.getName()); + } } else { - throw new InvalidParameterValueException("Only " + Capability.SupportedLBIsolation.getName() + ", " + Capability.ElasticLb.getName() + ", " + Capability.InlineMode.getName() + " capabilities can be sepcified for LB service"); + throw new InvalidParameterValueException("Only " + Capability.SupportedLBIsolation.getName() + + ", " + Capability.ElasticLb.getName() + ", " + Capability.InlineMode.getName() + + ", " + Capability.LbSchemes.getName() + " capabilities can be sepcified for LB service"); } } } @@ -3612,7 +3654,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @DB public NetworkOfferingVO createNetworkOffering(String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, Integer networkRate, Map> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId, - boolean conserveMode, Map> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent) { + boolean conserveMode, Map> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent, Map details) { String multicastRateStr = _configDao.getValue("multicast.throttling.rate"); int multicastRate = ((multicastRateStr == null) ? 10 : Integer.parseInt(multicastRateStr)); @@ -3666,6 +3708,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati boolean elasticIp = false; boolean associatePublicIp = false; boolean inline = false; + boolean publicLb = false; + boolean internalLb = false; if (serviceCapabilityMap != null && !serviceCapabilityMap.isEmpty()) { Map lbServiceCapabilityMap = serviceCapabilityMap.get(Service.Lb); @@ -3690,6 +3734,23 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } else { inline = false; } + + String publicLbStr = lbServiceCapabilityMap.get(Capability.LbSchemes); + if (serviceProviderMap.containsKey(Service.Lb)) { + if (publicLbStr != null) { + _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.Lb), Service.Lb, Capability.LbSchemes, publicLbStr); + internalLb = publicLbStr.contains("internal"); + publicLb = publicLbStr.contains("public"); + } else { + //if not specified, default public lb to true + publicLb = true; + } + } + } + + //in the current version of the code, publicLb and specificLb can't both be set to true for the same network offering + if (publicLb && internalLb) { + throw new InvalidParameterValueException("Public lb and internal lb can't be enabled at the same time on the offering"); } Map sourceNatServiceCapabilityMap = serviceCapabilityMap.get(Service.SourceNat); @@ -3724,18 +3785,23 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability, tags, type, conserveMode, dedicatedLb, - sharedSourceNat, redundantRouter, elasticIp, elasticLb, specifyIpRanges, inline, isPersistent, associatePublicIp); + sharedSourceNat, redundantRouter, elasticIp, elasticLb, specifyIpRanges, inline, isPersistent, associatePublicIp, publicLb, internalLb); if (serviceOfferingId != null) { offering.setServiceOfferingId(serviceOfferingId); } + + //validate the details + if (details != null) { + validateNtwkOffDetails(details, serviceProviderMap); + } Transaction txn = Transaction.currentTxn(); txn.start(); - // create network offering object + //1) create network offering object s_logger.debug("Adding network offering " + offering); - offering = _networkOfferingDao.persist(offering); - // populate services and providers + offering = _networkOfferingDao.persist(offering, details); + //2) populate services and providers if (serviceProviderMap != null) { for (Network.Service service : serviceProviderMap.keySet()) { Set providers = serviceProviderMap.get(service); @@ -3769,6 +3835,42 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati return offering; } + protected void validateNtwkOffDetails(Map details, Map> serviceProviderMap) { + for (Detail detail : details.keySet()) { + + Provider lbProvider = null; + if (detail == NetworkOffering.Detail.InternalLbProvider || detail == NetworkOffering.Detail.PublicLbProvider) { + //1) Vaidate the detail values - have to match the lb provider name + String providerStr = details.get(detail); + if (Network.Provider.getProvider(providerStr) == null) { + throw new InvalidParameterValueException("Invalid value " + providerStr + " for the detail " + detail); + } + if (serviceProviderMap.get(Service.Lb) != null) { + for (Provider provider : serviceProviderMap.get(Service.Lb)) { + if (provider.getName().equalsIgnoreCase(providerStr)) { + lbProvider = provider; + break; + } + } + } + + if (lbProvider == null) { + throw new InvalidParameterValueException("Invalid value " + details.get(detail) + + " for the detail " + detail + ". The provider is not supported by the network offering"); + } + + //2) validate if the provider supports the scheme + Set lbProviders = new HashSet(); + lbProviders.add(lbProvider); + if (detail == NetworkOffering.Detail.InternalLbProvider) { + _networkModel.checkCapabilityForProvider(lbProviders, Service.Lb, Capability.LbSchemes, Scheme.Internal.toString()); + } else if (detail == NetworkOffering.Detail.PublicLbProvider){ + _networkModel.checkCapabilityForProvider(lbProviders, Service.Lb, Capability.LbSchemes, Scheme.Public.toString()); + } + } + } + } + @Override public List searchForNetworkOfferings(ListNetworkOfferingsCmd cmd) { @@ -3994,6 +4096,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati public boolean isOfferingForVpc(NetworkOffering offering) { boolean vpcProvider = _ntwkOffServiceMapDao.isProviderForNetworkOffering(offering.getId(), Provider.VPCVirtualRouter); + boolean internalLb = offering.getInternalLb(); return vpcProvider; } diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManager.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManager.java index 9f11b850180..cb00614b086 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManager.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManager.java @@ -23,7 +23,7 @@ import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.Host; import com.cloud.network.dao.ExternalLoadBalancerDeviceVO; -import com.cloud.network.rules.FirewallRule; +import com.cloud.network.lb.LoadBalancingRule; import com.cloud.resource.ServerResource; import com.cloud.utils.component.Manager; @@ -89,7 +89,7 @@ public interface ExternalLoadBalancerDeviceManager extends Manager{ * @return true if successfully applied rules * @throws ResourceUnavailableException */ - public boolean applyLoadBalancerRules(Network network, List rules) throws ResourceUnavailableException; + public boolean applyLoadBalancerRules(Network network, List rules) throws ResourceUnavailableException; /** * implements or shutdowns guest network on the load balancer device assigned to the guest network @@ -102,6 +102,6 @@ public interface ExternalLoadBalancerDeviceManager extends Manager{ public boolean manageGuestNetworkWithExternalLoadBalancer(boolean add, Network guestConfig) throws ResourceUnavailableException, InsufficientCapacityException; - public List getLBHealthChecks(Network network, List rules) + public List getLBHealthChecks(Network network, List rules) throws ResourceUnavailableException; } diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java index 686f5bc2a05..f93bf7ae9b5 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java @@ -829,19 +829,11 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase } @Override - public boolean applyLoadBalancerRules(Network network, List rules) throws ResourceUnavailableException { + public boolean applyLoadBalancerRules(Network network, List loadBalancingRules) throws ResourceUnavailableException { // Find the external load balancer in this zone long zoneId = network.getDataCenterId(); DataCenterVO zone = _dcDao.findById(zoneId); - List loadBalancingRules = new ArrayList(); - - for (FirewallRule rule : rules) { - if (rule.getPurpose().equals(Purpose.LoadBalancing)) { - loadBalancingRules.add((LoadBalancingRule) rule); - } - } - if (loadBalancingRules == null || loadBalancingRules.isEmpty()) { return true; } @@ -870,12 +862,13 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase String protocol = rule.getProtocol(); String algorithm = rule.getAlgorithm(); String uuid = rule.getUuid(); - String srcIp = _networkModel.getIp(rule.getSourceIpAddressId()).getAddress().addr(); + String srcIp = rule.getSourceIp().addr(); int srcPort = rule.getSourcePortStart(); List destinations = rule.getDestinations(); if (externalLoadBalancerIsInline) { - MappingNic nic = getLoadBalancingIpNic(zone, network, rule.getSourceIpAddressId(), revoked, null); + long ipId = _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getId(); + MappingNic nic = getLoadBalancingIpNic(zone, network, ipId, revoked, null); mappingStates.add(nic.getState()); NicVO loadBalancingIpNic = nic.getNic(); if (loadBalancingIpNic == null) { @@ -927,7 +920,8 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase } else { continue; } - getLoadBalancingIpNic(zone, network, rule.getSourceIpAddressId(), revoke, existedGuestIp); + long sourceIpId = _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getId(); + getLoadBalancingIpNic(zone, network, sourceIpId, revoke, existedGuestIp); } } throw new ResourceUnavailableException(ex.getMessage(), DataCenter.class, network.getDataCenterId()); @@ -1113,7 +1107,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase } @Override - public List getLBHealthChecks(Network network, List rules) + public List getLBHealthChecks(Network network, List loadBalancingRules) throws ResourceUnavailableException { // Find the external load balancer in this zone @@ -1121,14 +1115,6 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase DataCenterVO zone = _dcDao.findById(zoneId); HealthCheckLBConfigAnswer answer = null; - List loadBalancingRules = new ArrayList(); - - for (FirewallRule rule : rules) { - if (rule.getPurpose().equals(Purpose.LoadBalancing)) { - loadBalancingRules.add((LoadBalancingRule) rule); - } - } - if (loadBalancingRules == null || loadBalancingRules.isEmpty()) { return null; } @@ -1158,12 +1144,13 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase String protocol = rule.getProtocol(); String algorithm = rule.getAlgorithm(); String uuid = rule.getUuid(); - String srcIp = _networkModel.getIp(rule.getSourceIpAddressId()).getAddress().addr(); + String srcIp = rule.getSourceIp().addr(); int srcPort = rule.getSourcePortStart(); List destinations = rule.getDestinations(); if (externalLoadBalancerIsInline) { - MappingNic nic = getLoadBalancingIpNic(zone, network, rule.getSourceIpAddressId(), revoked, null); + long sourceIpId = _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getId(); + MappingNic nic = getLoadBalancingIpNic(zone, network, sourceIpId, revoked, null); mappingStates.add(nic.getState()); NicVO loadBalancingIpNic = nic.getNic(); if (loadBalancingIpNic == null) { diff --git a/server/src/com/cloud/network/ExternalLoadBalancerUsageManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerUsageManagerImpl.java index d405382f89c..2c8031c64f0 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerUsageManagerImpl.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerUsageManagerImpl.java @@ -16,6 +16,22 @@ // under the License. package com.cloud.network; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + import com.cloud.agent.AgentManager; import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer; import com.cloud.agent.api.ExternalNetworkResourceUsageCommand; @@ -48,6 +64,7 @@ import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.rules.PortForwardingRuleVO; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.offerings.dao.NetworkOfferingDao; @@ -68,20 +85,6 @@ import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicVO; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import javax.ejb.Local; -import javax.inject.Inject; -import javax.naming.ConfigurationException; -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; @Component @Local(value = { ExternalLoadBalancerUsageManager.class }) @@ -647,9 +650,10 @@ public class ExternalLoadBalancerUsageManagerImpl extends ManagerBase implements // If an external load balancer is added, manage one entry for each load balancing rule in this network if (externalLoadBalancer != null && lbAnswer != null) { boolean inline = _networkMgr.isNetworkInlineMode(network); - List loadBalancers = _loadBalancerDao.listByNetworkId(network.getId()); + List loadBalancers = _loadBalancerDao.listByNetworkIdAndScheme(network.getId(), Scheme.Public); for (LoadBalancerVO loadBalancer : loadBalancers) { String publicIp = _networkMgr.getIp(loadBalancer.getSourceIpAddressId()).getAddress().addr(); + if (!createOrUpdateStatsEntry(create, accountId, zoneId, network.getId(), publicIp, externalLoadBalancer.getId(), lbAnswer, inline)) { throw new ExecutionException(networkErrorMsg + ", load balancing rule public IP = " + publicIp); } diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 4af716ca12a..34a092a465a 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -43,6 +43,7 @@ import com.cloud.network.element.StaticNatServiceProvider; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.rules.StaticNat; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; @@ -333,7 +334,7 @@ public interface NetworkManager { int getRuleCountForIp(Long addressId, FirewallRule.Purpose purpose, FirewallRule.State state); - LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network); + LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network, Scheme lbScheme); boolean isSecondaryIpSetForNic(long nicId); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 4fffbc11072..c91243095da 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -62,6 +62,13 @@ import com.cloud.network.guru.NetworkGuru; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.rules.*; import com.cloud.network.rules.FirewallRule.Purpose; +import com.cloud.network.rules.FirewallRuleVO; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; +import com.cloud.network.rules.PortForwardingRuleVO; +import com.cloud.network.rules.RulesManager; +import com.cloud.network.rules.StaticNat; +import com.cloud.network.rules.StaticNatRule; +import com.cloud.network.rules.StaticNatRuleImpl; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.vpc.NetworkACLManager; import com.cloud.network.vpc.VpcManager; @@ -72,6 +79,7 @@ import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offerings.NetworkOfferingServiceMapVO; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.offerings.dao.NetworkOfferingDetailsDao; import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; import com.cloud.org.Grouping; import com.cloud.user.*; @@ -156,6 +164,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L @Inject PodVlanMapDao _podVlanMapDao; @Inject + NetworkOfferingDetailsDao _ntwkOffDetailsDao; + @Inject ConfigurationServer _configServer; @Inject AccountGuestVlanMapDao _accountGuestVlanMapDao; @@ -948,7 +958,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices, "Offering for QuickCloud with no services", TrafficType.Guest, null, true, Availability.Optional, null, new HashMap>(), true, - Network.GuestType.Shared, false, null, true, null, true, false); + Network.GuestType.Shared, false, null, true, null, true, false, null); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } @@ -957,14 +967,14 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks", TrafficType.Guest, null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, - Network.GuestType.Shared, false, null, true, null, true, false); + Network.GuestType.Shared, false, null, true, null, true, false, null); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true, Availability.Optional, null, - defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false); + defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false, null); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } @@ -987,7 +997,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Required, null, defaultINetworkOfferingProvidersForVpcNetwork, - true, Network.GuestType.Isolated, false, null, true, null, false, false); + true, Network.GuestType.Isolated, false, null, true, null, false, false, null); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } @@ -996,7 +1006,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, "Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Optional, null, defaultVPCOffProviders, - true, Network.GuestType.Isolated, false, null, false, null, false, false); + true, Network.GuestType.Isolated, false, null, false, null, false, false, null); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } @@ -1007,7 +1017,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB, "Offering for Isolated VPC networks with Source Nat service enabled and LB service disabled", TrafficType.Guest, null, false, Availability.Optional, null, defaultVPCOffProviders, - true, Network.GuestType.Isolated, false, null, false, null, false, false); + true, Network.GuestType.Isolated, false, null, false, null, false, false, null); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } @@ -1016,7 +1026,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service", TrafficType.Guest, null, true, Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated, - false, null, true, null, true, false); + false, null, true, null, true, false, null); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } @@ -1045,7 +1055,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedEIPandELBNetworkOffering) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedEIPandELBNetworkOffering, "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, true, - Availability.Optional, null, netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false); + Availability.Optional, null, netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null); offering.setState(NetworkOffering.State.Enabled); offering.setDedicatedLB(false); _networkOfferingDao.update(offering.getId(), offering); @@ -2651,9 +2661,15 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L success = false; } - // apply load balancer rules - if (!_lbMgr.applyLoadBalancersForNetwork(networkId)) { - s_logger.warn("Failed to reapply load balancer rules as a part of network id=" + networkId + " restart"); + // apply public load balancer rules + if (!_lbMgr.applyLoadBalancersForNetwork(networkId, Scheme.Public)) { + s_logger.warn("Failed to reapply Public load balancer rules as a part of network id=" + networkId + " restart"); + success = false; + } + + // apply internal load balancer rules + if (!_lbMgr.applyLoadBalancersForNetwork(networkId, Scheme.Internal)) { + s_logger.warn("Failed to reapply internal load balancer rules as a part of network id=" + networkId + " restart"); success = false; } @@ -3234,12 +3250,22 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L } try { - if (!_lbMgr.revokeLoadBalancersForNetwork(networkId)) { - s_logger.warn("Failed to cleanup lb rules as a part of shutdownNetworkRules"); + if (!_lbMgr.revokeLoadBalancersForNetwork(networkId, Scheme.Public)) { + s_logger.warn("Failed to cleanup public lb rules as a part of shutdownNetworkRules"); success = false; } } catch (ResourceUnavailableException ex) { - s_logger.warn("Failed to cleanup lb rules as a part of shutdownNetworkRules due to ", ex); + s_logger.warn("Failed to cleanup public lb rules as a part of shutdownNetworkRules due to ", ex); + success = false; + } + + try { + if (!_lbMgr.revokeLoadBalancersForNetwork(networkId, Scheme.Internal)) { + s_logger.warn("Failed to cleanup internal lb rules as a part of shutdownNetworkRules"); + success = false; + } + } catch (ResourceUnavailableException ex) { + s_logger.warn("Failed to cleanup public lb rules as a part of shutdownNetworkRules due to ", ex); success = false; } @@ -3645,7 +3671,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L } } } else { - NicVO nicVO = _nicDao.findByInstanceIdAndNetworkId(network.getId(), vm.getId()); + NicVO nicVO = _nicDao.findByNtwkIdAndInstanceId(network.getId(), vm.getId()); if (nicVO != null) { nic = _networkModel.getNicProfile(vm, network.getId(), null); } @@ -3747,35 +3773,62 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L return null; } - protected NetworkElement getElementForServiceInNetwork(Network network, Service service) { + protected List getElementForServiceInNetwork(Network network, Service service) { + List elements = new ArrayList(); List providers = getProvidersForServiceInNetwork(network, service); //Only support one provider now if (providers == null) { s_logger.error("Cannot find " + service.getName() + " provider for network " + network.getId()); return null; } - if (providers.size() != 1) { + if (providers.size() != 1 && service != Service.Lb) { + //support more than one LB providers only s_logger.error("Found " + providers.size() + " " + service.getName() + " providers for network!" + network.getId()); return null; + } + + for (Provider provider : providers) { + NetworkElement element = _networkModel.getElementImplementingProvider(provider.getName()); + s_logger.info("Let " + element.getName() + " handle " + service.getName() + " in network " + network.getId()); + elements.add(element); } - NetworkElement element = _networkModel.getElementImplementingProvider(providers.get(0).getName()); - s_logger.info("Let " + element.getName() + " handle " + service.getName() + " in network " + network.getId()); - return element; + return elements; } @Override public StaticNatServiceProvider getStaticNatProviderForNetwork(Network network) { - NetworkElement element = getElementForServiceInNetwork(network, Service.StaticNat); + //only one provider per Static nat service is supoprted + NetworkElement element = getElementForServiceInNetwork(network, Service.StaticNat).get(0); assert element instanceof StaticNatServiceProvider; return (StaticNatServiceProvider)element; } @Override - public LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network) { - NetworkElement element = getElementForServiceInNetwork(network, Service.Lb); - assert element instanceof LoadBalancingServiceProvider; - return (LoadBalancingServiceProvider)element; + public LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network, Scheme lbScheme) { + List lbElements = getElementForServiceInNetwork(network, Service.Lb); + NetworkElement lbElement = null; + if (lbElements.size() > 1) { + String providerName = null; + //get network offering details + NetworkOffering off = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); + if (lbScheme == Scheme.Public) { + providerName = _ntwkOffDetailsDao.getDetail(off.getId(), NetworkOffering.Detail.PublicLbProvider); + } else { + providerName = _ntwkOffDetailsDao.getDetail(off.getId(), NetworkOffering.Detail.InternalLbProvider); + } + if (providerName == null) { + throw new InvalidParameterValueException("Can't find Lb provider supporting scheme " + lbScheme.toString() + " in network " + network); + } + lbElement = _networkModel.getElementImplementingProvider(providerName); + } else if (lbElements.size() == 1){ + lbElement = lbElements.get(0); + } + + assert lbElement != null; + assert lbElement instanceof LoadBalancingServiceProvider; + return (LoadBalancingServiceProvider)lbElement; } + @Override public boolean isNetworkInlineMode(Network network) { NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId()); diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java index eaec6a6b42f..135fd290535 100755 --- a/server/src/com/cloud/network/NetworkModelImpl.java +++ b/server/src/com/cloud/network/NetworkModelImpl.java @@ -32,6 +32,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -52,13 +53,11 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.UnsupportedServiceException; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.server.ConfigurationServer; import com.cloud.network.IpAddress.State; import com.cloud.network.Network.Capability; import com.cloud.network.Network.GuestType; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; -import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.FirewallRulesDao; @@ -86,11 +85,14 @@ import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.vpc.dao.PrivateIpDao; import com.cloud.offering.NetworkOffering; +import com.cloud.offering.NetworkOffering.Detail; import com.cloud.offerings.NetworkOfferingServiceMapVO; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.offerings.dao.NetworkOfferingDetailsDao; import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; import com.cloud.projects.dao.ProjectAccountDao; +import com.cloud.server.ConfigurationServer; import com.cloud.user.Account; import com.cloud.user.AccountVO; import com.cloud.user.DomainManager; @@ -183,9 +185,13 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { @Inject UserIpv6AddressDao _ipv6Dao; @Inject - NicSecondaryIpDao _nicSecondaryIpDao;; + NicSecondaryIpDao _nicSecondaryIpDao; + @Inject + ApplicationLoadBalancerRuleDao _appLbRuleDao; @Inject private ProjectAccountDao _projectAccountDao; + @Inject + NetworkOfferingDetailsDao _ntwkOffDetailsDao; private final HashMap _systemNetworks = new HashMap(5); static Long _privateOfferingId = null; @@ -604,7 +610,6 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { NetworkElement element = getElementImplementingProvider(instance.getProvider()); if (element != null) { Map> elementCapabilities = element.getCapabilities(); - ; if (elementCapabilities != null) { networkCapabilities.put(service, elementCapabilities.get(service)); } @@ -917,7 +922,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { boolean isUserVmsDefaultNetwork = false; boolean isDomRGuestOrPublicNetwork = false; if (vm != null) { - Nic nic = _nicDao.findByInstanceIdAndNetworkId(networkId, vmId); + Nic nic = _nicDao.findByNtwkIdAndInstanceId(networkId, vmId); if (vm.getType() == Type.User && nic != null && nic.isDefaultNic()) { isUserVmsDefaultNetwork = true; } else if (vm.getType() == Type.DomainRouter && ntwkOff != null && (ntwkOff.getTrafficType() == TrafficType.Public || ntwkOff.getTrafficType() == TrafficType.Guest)) { @@ -1465,10 +1470,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { throw new UnsupportedServiceException("Service " + service.getName() + " doesn't have capability " + cap.getName() + " for element=" + element.getName() + " implementing Provider=" + provider.getName()); } - - capValue = capValue.toLowerCase(); - - if (!value.contains(capValue)) { + + if (!value.toLowerCase().contains(capValue.toLowerCase())) { throw new UnsupportedServiceException("Service " + service.getName() + " doesn't support value " + capValue + " for capability " + cap.getName() + " for element=" + element.getName() + " implementing Provider=" + provider.getName()); } @@ -1664,9 +1667,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { @Override public Set getAvailableIps(Network network, String requestedIp) { String[] cidr = network.getCidr().split("/"); - List ips = _nicDao.listIpAddressInNetwork(network.getId()); - List secondaryIps = _nicSecondaryIpDao.listSecondaryIpAddressInNetwork(network.getId()); - ips.addAll(secondaryIps); + List ips = getUsedIpsInNetwork(network); Set usedIps = new TreeSet(); for (String ip : ips) { @@ -1677,6 +1678,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { usedIps.add(NetUtils.ip2Long(ip)); } + Set allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]), usedIps); String gateway = network.getGateway(); @@ -1685,6 +1687,19 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { return allPossibleIps; } + + @Override + public List getUsedIpsInNetwork(Network network) { + //Get all ips used by vms nics + List ips = _nicDao.listIpAddressInNetwork(network.getId()); + //Get all secondary ips for nics + List secondaryIps = _nicSecondaryIpDao.listSecondaryIpAddressInNetwork(network.getId()); + ips.addAll(secondaryIps); + //Get ips used by load balancers + List lbIps = _appLbRuleDao.listLbIpsBySourceIpNetworkId(network.getId()); + ips.addAll(lbIps); + return ips; + } @Override public String getDomainNetworkDomain(long domainId, long zoneId) { @@ -1792,7 +1807,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { if (broadcastUri != null) { nic = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(networkId, vm.getId(), broadcastUri); } else { - nic = _nicDao.findByInstanceIdAndNetworkId(networkId, vm.getId()); + nic = _nicDao.findByNtwkIdAndInstanceId(networkId, vm.getId()); } if (nic == null) { return null; @@ -2051,6 +2066,22 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { return null; } + + @Override + public IpAddress getPublicIpAddress(String ipAddress, long zoneId) { + List networks = _networksDao.listByZoneAndTrafficType(zoneId, TrafficType.Public); + if (networks.isEmpty() || networks.size() > 1) { + throw new CloudRuntimeException("Can't find public network in the zone specified"); + } + + return _ipAddressDao.findByIpAndSourceNetworkId(networks.get(0).getId(), ipAddress); + } + + @Override + public Map getNtwkOffDetails(long offId) { + return _ntwkOffDetailsDao.getNtwkOffDetails(offId); + } + @Override public Networks.IsolationType[] listNetworkIsolationMethods() { diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index f44688c7594..88155582569 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -47,6 +47,7 @@ import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; +import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -170,6 +171,33 @@ import com.cloud.vm.dao.NicSecondaryIpDao; import com.cloud.vm.dao.NicSecondaryIpVO; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; +import com.cloud.vm.*; +import com.cloud.vm.dao.*; +import org.apache.cloudstack.acl.ControlledEntity.ACLType; +import org.apache.cloudstack.acl.SecurityChecker; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; +import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; +import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd; +import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; +import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; +import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; +import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.security.InvalidParameterException; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + /** * NetworkServiceImpl implements NetworkService. @@ -267,6 +295,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { HostDao _hostDao; @Inject HostPodDao _hostPodDao; + @Inject + InternalLoadBalancerElementService _internalLbElementSvc; @Inject DataCenterVnetDao _datacneter_vnet; @Inject @@ -1187,6 +1217,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (_configMgr.isOfferingForVpc(ntwkOff)){ throw new InvalidParameterValueException("Network offering can be used for VPC networks only"); } + if (ntwkOff.getInternalLb()) { + throw new InvalidParameterValueException("Internal Lb can be enabled on vpc networks only"); + } + network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr); } @@ -2134,8 +2168,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } - - protected Set getAvailableIps(Network network, String requestedIp) { String[] cidr = network.getCidr().split("/"); List ips = _nicDao.listIpAddressInNetwork(network.getId()); @@ -2159,7 +2191,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } - protected boolean canUpgrade(Network network, long oldNetworkOfferingId, long newNetworkOfferingId) { NetworkOffering oldNetworkOffering = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId); NetworkOffering newNetworkOffering = _networkOfferingDao.findById(newNetworkOfferingId); @@ -2225,6 +2256,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return false; } } + + //can't update from internal LB to public LB + if (areServicesSupportedByNetworkOffering(oldNetworkOfferingId, Service.Lb) && areServicesSupportedByNetworkOffering(newNetworkOfferingId, Service.Lb)) { + if (oldNetworkOffering.getPublicLb() != newNetworkOffering.getPublicLb() || oldNetworkOffering.getInternalLb() != newNetworkOffering.getInternalLb()) { + throw new InvalidParameterValueException("Original and new offerings support different types of LB - Internal vs Public," + + " can't upgrade"); + } + } return canIpsUseOffering(publicIps, newNetworkOfferingId); } @@ -2345,7 +2384,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { // add baremetal as the defualt network service provider /* addDefaultBaremetalProvidersToPhysicalNetwork(pNetwork.getId()); */ - + + //Add Internal Load Balancer element as a default network service provider + addDefaultInternalLbProviderToPhysicalNetwork(pNetwork.getId()); + txn.commit(); return pNetwork; } catch (Exception ex) { @@ -3564,6 +3606,22 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return nsp; } + + + protected PhysicalNetworkServiceProvider addDefaultInternalLbProviderToPhysicalNetwork(long physicalNetworkId) { + + PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, + Network.Provider.InternalLbVm.getName(), null, null); + + NetworkElement networkElement = _networkModel.getElementImplementingProvider(Network.Provider.InternalLbVm.getName()); + if (networkElement == null) { + throw new CloudRuntimeException("Unable to find the Network Element implementing the " + Network.Provider.InternalLbVm.getName() + " Provider"); + } + + _internalLbElementSvc.addInternalLoadBalancerElement(nsp.getId()); + + return nsp; + } protected PhysicalNetworkServiceProvider addDefaultSecurityGroupProviderToPhysicalNetwork(long physicalNetworkId) { @@ -3572,6 +3630,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return nsp; } + + private PhysicalNetworkServiceProvider addDefaultBaremetalProvidersToPhysicalNetwork(long physicalNetworkId) { PhysicalNetworkVO pvo = _physicalNetworkDao.findById(physicalNetworkId); diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index f601f4fa2e4..28473cc7bc2 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -25,7 +25,6 @@ import java.util.Set; import javax.ejb.Local; import javax.inject.Inject; -import com.cloud.utils.PropertiesUtil; import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd; import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd; import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd; @@ -66,6 +65,7 @@ import com.cloud.network.router.VpcVirtualNetworkApplianceManager; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LbStickinessMethod; import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; +import com.cloud.network.rules.LoadBalancerContainer; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.RulesManager; import com.cloud.network.rules.StaticNat; @@ -242,7 +242,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl * number like 12 2) time or tablesize like 12h, 34m, 45k, 54m , here * last character is non-digit but from known characters . */ - private boolean containsOnlyNumbers(String str, String endChar) { + private static boolean containsOnlyNumbers(String str, String endChar) { if (str == null) return false; @@ -271,7 +271,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return true; } - private boolean validateHAProxyLBRule(LoadBalancingRule rule) { + public static boolean validateHAProxyLBRule(LoadBalancingRule rule) { String timeEndChar = "dhms"; for (LbStickinessPolicy stickinessPolicy : rule.getStickinessPolicies()) { @@ -338,7 +338,9 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @Override public boolean validateLBRule(Network network, LoadBalancingRule rule) { - if (canHandle(network, Service.Lb)) { + List rules = new ArrayList(); + rules.add(rule); + if (canHandle(network, Service.Lb) && canHandleLbRules(rules)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { return true; @@ -351,6 +353,10 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @Override public boolean applyLBRules(Network network, List rules) throws ResourceUnavailableException { if (canHandle(network, Service.Lb)) { + if (!canHandleLbRules(rules)) { + return false; + } + List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + @@ -358,8 +364,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return true; } - if (!_routerMgr.applyFirewallRules(network, rules, routers)) { - throw new CloudRuntimeException("Failed to apply firewall rules in network " + network.getId()); + if (!_routerMgr.applyLoadBalancingRules(network, rules, routers)) { + throw new CloudRuntimeException("Failed to apply load balancing rules in network " + network.getId()); } else { return true; } @@ -452,7 +458,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return capabilities; } - private static String getHAProxyStickinessCapability() { + public static String getHAProxyStickinessCapability() { LbStickinessMethod method; List methodList = new ArrayList(1); @@ -557,8 +563,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl lbCapabilities.put(Capability.SupportedLBAlgorithms, "roundrobin,leastconn,source"); lbCapabilities.put(Capability.SupportedLBIsolation, "dedicated"); lbCapabilities.put(Capability.SupportedProtocols, "tcp, udp"); - lbCapabilities.put(Capability.SupportedStickinessMethods, getHAProxyStickinessCapability()); + lbCapabilities.put(Capability.LbSchemes, LoadBalancerContainer.Scheme.Public.toString()); capabilities.put(Service.Lb, lbCapabilities); @@ -715,8 +721,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @Override public VirtualRouterProvider configure(ConfigureVirtualRouterElementCmd cmd) { VirtualRouterProviderVO element = _vrProviderDao.findById(cmd.getId()); - if (element == null) { - s_logger.debug("Can't find element with network service provider id " + cmd.getId()); + if (element == null || !(element.getType() == VirtualRouterProviderType.VirtualRouter || element.getType() == VirtualRouterProviderType.VPCVirtualRouter)) { + s_logger.debug("Can't find Virtual Router element with network service provider id " + cmd.getId()); return null; } @@ -728,6 +734,10 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @Override public VirtualRouterProvider addElement(Long nspId, VirtualRouterProviderType providerType) { + if (!(providerType == VirtualRouterProviderType.VirtualRouter || providerType == VirtualRouterProviderType.VPCVirtualRouter)) { + throw new InvalidParameterValueException("Element " + this.getName() + " supports only providerTypes: " + + VirtualRouterProviderType.VirtualRouter.toString() + " and " + VirtualRouterProviderType.VPCVirtualRouter); + } VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(nspId, providerType); if (element != null) { s_logger.debug("There is already a virtual router element with service provider id " + nspId); @@ -801,7 +811,11 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @Override public VirtualRouterProvider getCreatedElement(long id) { - return _vrProviderDao.findById(id); + VirtualRouterProvider provider = _vrProviderDao.findById(id); + if (!(provider.getType() == VirtualRouterProviderType.VirtualRouter || provider.getType() == VirtualRouterProviderType.VPCVirtualRouter)) { + throw new InvalidParameterValueException("Unable to find provider by id"); + } + return provider; } @Override @@ -911,6 +925,10 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (enabled != null) { sc.addAnd(sc.getEntity().isEnabled(), Op.EQ, enabled); } + + //return only VR and VPC VR + sc.addAnd(sc.getEntity().getType(), Op.IN, VirtualRouterProvider.VirtualRouterProviderType.VPCVirtualRouter, VirtualRouterProvider.VirtualRouterProviderType.VirtualRouter); + return sc.list(); } @@ -946,4 +964,20 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl // TODO Auto-generated method stub return null; } + + private boolean canHandleLbRules(List rules) { + Map lbCaps = this.getCapabilities().get(Service.Lb); + if (!lbCaps.isEmpty()) { + String schemeCaps = lbCaps.get(Capability.LbSchemes); + if (schemeCaps != null) { + for (LoadBalancingRule rule : rules) { + if (!schemeCaps.contains(rule.getScheme().toString())) { + s_logger.debug("Scheme " + rules.get(0).getScheme() + " is not supported by the provider " + this.getName()); + return false; + } + } + } + } + return true; + } } diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index 4ad8868b86a..def4c1ed06f 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -27,17 +27,12 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.api.command.user.firewall.ListEgressFirewallRulesCmd; import com.cloud.network.dao.*; import org.apache.cloudstack.api.command.user.firewall.ListFirewallRulesCmd; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.mysql.jdbc.ConnectionPropertiesImpl; -import org.apache.log4j.Logger; - -import org.apache.cloudstack.api.BaseListCmd; -import org.apache.cloudstack.api.command.user.firewall.ListEgressFirewallRulesCmd; -import org.apache.cloudstack.api.command.user.firewall.ListFirewallRulesCmd; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.domain.dao.DomainDao; @@ -53,7 +48,6 @@ import com.cloud.network.IpAddress; import com.cloud.network.Network; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Service; -import com.cloud.network.Networks.TrafficType; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkModel; import com.cloud.network.NetworkRuleApplier; @@ -61,10 +55,15 @@ import com.cloud.network.element.FirewallServiceProvider; import com.cloud.network.element.NetworkACLServiceProvider; import com.cloud.network.element.PortForwardingServiceProvider; import com.cloud.network.element.StaticNatServiceProvider; -import com.cloud.network.rules.*; +import com.cloud.network.rules.FirewallManager; +import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule.FirewallRuleType; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRule.State; +import com.cloud.network.rules.FirewallRuleVO; +import com.cloud.network.rules.PortForwardingRule; +import com.cloud.network.rules.PortForwardingRuleVO; +import com.cloud.network.rules.StaticNat; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.vpc.VpcManager; import com.cloud.projects.Project.ListProjectResourcesCriteria; @@ -83,8 +82,8 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.*; import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.UserVmVO; @@ -438,22 +437,28 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, return; } - if (ipAddress!=null){ - if (ipAddress.getAssociatedWithNetworkId() == null) { - throw new InvalidParameterValueException("Unable to create firewall rule ; ip with specified id is not associated with any network"); - } else { - networkId = ipAddress.getAssociatedWithNetworkId(); - } - + if (ipAddress != null){ + if (ipAddress.getAssociatedWithNetworkId() == null) { + throw new InvalidParameterValueException("Unable to create firewall rule ; ip with specified id is not associated with any network"); + } else { + networkId = ipAddress.getAssociatedWithNetworkId(); + } + // Validate ip address _accountMgr.checkAccess(caller, null, true, ipAddress); - + } + + //network id either has to be passed explicitly, or implicitly as a part of ipAddress object + if (networkId == null) { + throw new InvalidParameterValueException("Unable to retrieve network id to validate the rule"); + } + Network network = _networkModel.getNetwork(networkId); - assert network != null : "Can't create port forwarding rule as network associated with public ip address is null?"; + assert network != null : "Can't create rule as network associated with public ip address is null?"; - if (trafficType == FirewallRule.TrafficType.Egress) { - _accountMgr.checkAccess(caller, null, true, network); - } + if (trafficType == FirewallRule.TrafficType.Egress) { + _accountMgr.checkAccess(caller, null, true, network); + } // Verify that the network guru supports the protocol specified Map caps = null; @@ -464,32 +469,32 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService, } } else if (purpose == Purpose.PortForwarding) { caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.PortForwarding); - }else if (purpose == Purpose.Firewall){ - caps = _networkModel.getNetworkServiceCapabilities(network.getId(),Service.Firewall); + } else if (purpose == Purpose.Firewall){ + caps = _networkModel.getNetworkServiceCapabilities(network.getId(),Service.Firewall); } if (caps != null) { - String supportedProtocols; - String supportedTrafficTypes = null; - if (purpose == FirewallRule.Purpose.Firewall) { - supportedTrafficTypes = caps.get(Capability.SupportedTrafficDirection).toLowerCase(); - } + String supportedProtocols; + String supportedTrafficTypes = null; + if (purpose == FirewallRule.Purpose.Firewall) { + supportedTrafficTypes = caps.get(Capability.SupportedTrafficDirection).toLowerCase(); + } - if (purpose == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress) { - supportedProtocols = caps.get(Capability.SupportedEgressProtocols).toLowerCase(); - } else { - supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase(); - } + if (purpose == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress) { + supportedProtocols = caps.get(Capability.SupportedEgressProtocols).toLowerCase(); + } else { + supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase(); + } if (!supportedProtocols.contains(proto.toLowerCase())) { throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId()); } else if (proto.equalsIgnoreCase(NetUtils.ICMP_PROTO) && purpose != Purpose.Firewall) { throw new InvalidParameterValueException("Protocol " + proto + " is currently supported only for rules with purpose " + Purpose.Firewall); - } else if (purpose == Purpose.Firewall && !supportedTrafficTypes.contains(trafficType.toString().toLowerCase())) { - throw new InvalidParameterValueException("Traffic Type " + trafficType + " is currently supported by Firewall in network " + networkId); - } + } else if (purpose == Purpose.Firewall && !supportedTrafficTypes.contains(trafficType.toString().toLowerCase())) { + throw new InvalidParameterValueException("Traffic Type " + trafficType + " is currently supported by Firewall in network " + networkId); } } + } @Override diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java index 291e3ccbc77..32ce744979b 100755 --- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java @@ -223,48 +223,7 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur nic.deallocate(); } } - - public Ip4Address acquireIp4Address(Network network, Ip4Address requestedIp, String reservationId) { - List ips = _nicDao.listIpAddressInNetwork(network.getId()); - String[] cidr = network.getCidr().split("/"); - SortedSet usedIps = new TreeSet(); - - if (requestedIp != null && requestedIp.equals(network.getGateway())) { - s_logger.warn("Requested ip address " + requestedIp + " is used as a gateway address in network " + network); - return null; - } - - for (String ip : ips) { - usedIps.add(NetUtils.ip2Long(ip)); - } - - if (network.getGateway() != null) { - usedIps.add(NetUtils.ip2Long(network.getGateway())); - } - - if (requestedIp != null) { - if (usedIps.contains(requestedIp.toLong())) { - s_logger.warn("Requested ip address " + requestedIp + " is already in used in " + network); - return null; - } - //check that requested ip has the same cidr - boolean isSameCidr = NetUtils.sameSubnetCIDR(requestedIp.ip4(), cidr[0], Integer.parseInt(cidr[1])); - if (!isSameCidr) { - s_logger.warn("Requested ip address " + requestedIp + " doesn't belong to the network " + network + " cidr"); - return null; - } - - return requestedIp; - } - - long ip = NetUtils.getRandomIpFromCidr(cidr[0], Integer.parseInt(cidr[1]), usedIps); - if (ip == -1) { - s_logger.warn("Unable to allocate any more ip address in " + network); - return null; - } - - return new Ip4Address(ip); - } + public int getVlanOffset(long physicalNetworkId, int vlanTag) { PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId); diff --git a/server/src/com/cloud/network/lb/LBHealthCheckManager.java b/server/src/com/cloud/network/lb/LBHealthCheckManager.java index 2e24965aa35..a9969eb7ce1 100644 --- a/server/src/com/cloud/network/lb/LBHealthCheckManager.java +++ b/server/src/com/cloud/network/lb/LBHealthCheckManager.java @@ -16,9 +16,11 @@ // under the License. package com.cloud.network.lb; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; + public interface LBHealthCheckManager { - void updateLBHealthCheck(); + void updateLBHealthCheck(Scheme scheme); } diff --git a/server/src/com/cloud/network/lb/LBHealthCheckManagerImpl.java b/server/src/com/cloud/network/lb/LBHealthCheckManagerImpl.java index 90547328714..62b738bb498 100644 --- a/server/src/com/cloud/network/lb/LBHealthCheckManagerImpl.java +++ b/server/src/com/cloud/network/lb/LBHealthCheckManagerImpl.java @@ -19,7 +19,6 @@ package com.cloud.network.lb; import static java.lang.String.format; import java.util.Map; - import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -34,6 +33,7 @@ import org.springframework.stereotype.Component; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; @@ -90,7 +90,8 @@ public class LBHealthCheckManagerImpl extends ManagerBase implements LBHealthChe @Override public void run() { try { - updateLBHealthCheck(); + updateLBHealthCheck(Scheme.Public); + updateLBHealthCheck(Scheme.Internal); } catch (Exception e) { s_logger.error("Exception in LB HealthCheck Update Checker", e); } @@ -98,9 +99,9 @@ public class LBHealthCheckManagerImpl extends ManagerBase implements LBHealthChe } @Override - public void updateLBHealthCheck() { + public void updateLBHealthCheck(Scheme scheme) { try { - _lbService.updateLBHealthChecks(); + _lbService.updateLBHealthChecks(scheme); } catch (ResourceUnavailableException e) { s_logger.debug("Error while updating the LB HealtCheck ", e); } diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java index d98872a0906..a23d96f8aea 100644 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManager.java @@ -16,23 +16,24 @@ // under the License. package com.cloud.network.lb; +import java.util.List; + import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.Network; import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; -import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LbStickinessMethod; import com.cloud.network.rules.LoadBalancer; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.user.Account; -import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerRuleCmd; - -import java.util.List; +import com.cloud.user.UserContext; public interface LoadBalancingRulesManager extends LoadBalancingRulesService { - LoadBalancer createLoadBalancer(CreateLoadBalancerRuleCmd lb, boolean openFirewall) throws NetworkRuleConflictException; + LoadBalancer createPublicLoadBalancer(String xId, String name, String description, + int srcPort, int destPort, long sourceIpId, String protocol, String algorithm, boolean openFirewall, UserContext caller) + throws NetworkRuleConflictException; boolean removeAllLoadBalanacersForIp(long ipId, Account caller, long callerUserId); boolean removeAllLoadBalanacersForNetwork(long networkId, Account caller, long callerUserId); @@ -47,9 +48,14 @@ public interface LoadBalancingRulesManager extends LoadBalancingRulesService { * @return true if removal is successful */ boolean removeVmFromLoadBalancers(long vmId); - boolean applyRules(Network network, FirewallRule.Purpose purpose, List rules) throws ResourceUnavailableException ; - boolean applyLoadBalancersForNetwork(long networkId) throws ResourceUnavailableException; + boolean applyLoadBalancersForNetwork(long networkId, Scheme scheme) throws ResourceUnavailableException; String getLBCapability(long networkid, String capabilityName); boolean configureLbAutoScaleVmGroup(long vmGroupid, String currentState) throws ResourceUnavailableException; - boolean revokeLoadBalancersForNetwork(long networkId) throws ResourceUnavailableException; + boolean revokeLoadBalancersForNetwork(long networkId, Scheme scheme) throws ResourceUnavailableException; + + boolean validateLbRule(LoadBalancingRule lbRule); + + void removeLBRule(LoadBalancer rule); + + void isLbServiceSupportedInNetwork(long networkId, Scheme scheme); } diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index 7ad1070e1c7..520dd763667 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -16,6 +16,34 @@ // under the License. package com.cloud.network.lb; +import java.security.InvalidParameterException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.ListLBHealthCheckPoliciesCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.ListLBStickinessPoliciesCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRuleInstancesCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRulesCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRuleCmd; +import org.apache.cloudstack.api.response.ServiceResponse; +import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO; +import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + import com.cloud.agent.api.to.LoadBalancerTO; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; @@ -30,21 +58,70 @@ import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; import com.cloud.event.dao.EventDao; import com.cloud.event.dao.UsageEventDao; -import com.cloud.exception.*; -import com.cloud.network.*; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.ExternalLoadBalancerUsageManager; +import com.cloud.network.IpAddress; +import com.cloud.network.LBHealthCheckPolicyVO; +import com.cloud.network.Network; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; -import com.cloud.network.as.*; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkModel; +import com.cloud.network.addr.PublicIp; +import com.cloud.network.as.AutoScalePolicy; +import com.cloud.network.as.AutoScalePolicyConditionMapVO; +import com.cloud.network.as.AutoScaleVmGroup; +import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO; +import com.cloud.network.as.AutoScaleVmGroupVO; +import com.cloud.network.as.AutoScaleVmProfile; import com.cloud.network.as.Condition; -import com.cloud.network.as.dao.*; -import com.cloud.network.dao.*; +import com.cloud.network.as.Counter; +import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao; +import com.cloud.network.as.dao.AutoScalePolicyDao; +import com.cloud.network.as.dao.AutoScaleVmGroupDao; +import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao; +import com.cloud.network.as.dao.AutoScaleVmProfileDao; +import com.cloud.network.as.dao.ConditionDao; +import com.cloud.network.as.dao.CounterDao; +import com.cloud.network.dao.FirewallRulesCidrsDao; +import com.cloud.network.dao.FirewallRulesDao; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.LBHealthCheckPolicyDao; +import com.cloud.network.dao.LBStickinessPolicyDao; +import com.cloud.network.dao.LBStickinessPolicyVO; +import com.cloud.network.dao.LoadBalancerDao; +import com.cloud.network.dao.LoadBalancerVMMapDao; +import com.cloud.network.dao.LoadBalancerVMMapVO; +import com.cloud.network.dao.LoadBalancerVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.NetworkVO; import com.cloud.network.element.LoadBalancingServiceProvider; -import com.cloud.network.lb.LoadBalancingRule.*; -import com.cloud.network.rules.*; +import com.cloud.network.lb.LoadBalancingRule.LbAutoScalePolicy; +import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmGroup; +import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmProfile; +import com.cloud.network.lb.LoadBalancingRule.LbCondition; +import com.cloud.network.lb.LoadBalancingRule.LbDestination; +import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy; +import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; +import com.cloud.network.rules.FirewallManager; +import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule.FirewallRuleType; import com.cloud.network.rules.FirewallRule.Purpose; +import com.cloud.network.rules.FirewallRuleVO; +import com.cloud.network.rules.HealthCheckPolicy; +import com.cloud.network.rules.LbStickinessMethod; import com.cloud.network.rules.LbStickinessMethod.LbStickinessMethodParam; +import com.cloud.network.rules.LoadBalancer; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; +import com.cloud.network.rules.RulesManager; +import com.cloud.network.rules.StickinessPolicy; import com.cloud.network.vpc.VpcManager; import com.cloud.offering.NetworkOffering; import com.cloud.projects.Project.ListProjectResourcesCriteria; @@ -53,15 +130,25 @@ import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; -import com.cloud.user.*; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.DomainService; +import com.cloud.user.User; +import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; import com.cloud.uservm.UserVm; import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.component.ManagerBase; -import com.cloud.utils.db.*; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; import com.cloud.vm.Nic; import com.cloud.vm.UserVmVO; @@ -70,21 +157,11 @@ import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; -import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.command.user.loadbalancer.*; -import org.apache.cloudstack.api.response.ServiceResponse; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import javax.ejb.Local; -import javax.inject.Inject; -import java.security.InvalidParameterException; -import java.util.*; @Component @Local(value = { LoadBalancingRulesManager.class, LoadBalancingRulesService.class }) public class LoadBalancingRulesManagerImpl extends ManagerBase implements LoadBalancingRulesManager, - LoadBalancingRulesService, NetworkRuleApplier { + LoadBalancingRulesService { private static final Logger s_logger = Logger.getLogger(LoadBalancingRulesManagerImpl.class); @Inject @@ -166,6 +243,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements UserDao _userDao; @Inject List _lbProviders; + @Inject ApplicationLoadBalancerRuleDao _appLbRuleDao; // Will return a string. For LB Stickiness this will be a json, for // autoscale this will be "," separated values @@ -261,8 +339,9 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements * Regular config like destinations need not be packed for applying * autoscale config as of today. */ - List policyList = getStickinessPolicies(lb.getId()); - LoadBalancingRule rule = new LoadBalancingRule(lb, null, policyList, null); + List policyList = getStickinessPolicies(lb.getId()); + Ip sourceIp = getSourceIp(lb); + LoadBalancingRule rule = new LoadBalancingRule(lb, null, policyList, null, sourceIp); rule.setAutoScaleVmGroup(lbAutoScaleVmGroup); if (!isRollBackAllowedForProvider(lb)) { @@ -273,7 +352,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements List rules = Arrays.asList(rule); - if (!_networkMgr.applyRules(rules, FirewallRule.Purpose.LoadBalancing, this, false)) { + if (!applyLbRules(rules, false)) { s_logger.debug("LB rules' autoscale config are not completely applied"); return false; } @@ -281,6 +360,17 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements return true; } + private Ip getSourceIp(LoadBalancer lb) { + Ip sourceIp = null; + if (lb.getScheme() == Scheme.Public) { + sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress(); + } else if (lb.getScheme() == Scheme.Internal) { + ApplicationLoadBalancerRuleVO appLbRule = _appLbRuleDao.findById(lb.getId()); + sourceIp = appLbRule.getSourceIp(); + } + return sourceIp; + } + @Override @DB public boolean configureLbAutoScaleVmGroup(long vmGroupid, String currentState) throws ResourceUnavailableException { @@ -454,9 +544,10 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements cmd.getStickinessMethodName(), cmd.getparamList(), cmd.getDescription()); List policyList = new ArrayList(); policyList.add(new LbStickinessPolicy(cmd.getStickinessMethodName(), lbpolicy.getParams())); + Ip sourceIp = getSourceIp(loadBalancer); LoadBalancingRule lbRule = new LoadBalancingRule(loadBalancer, getExistingDestinations(lbpolicy.getId()), - policyList, null); - if (!validateRule(lbRule)) { + policyList, null, sourceIp); + if (!validateLbRule(lbRule)) { throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation Failed " + cmd.getLbRuleId()); } @@ -539,7 +630,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements return policy; } - private boolean validateRule(LoadBalancingRule lbRule) { + @Override + public boolean validateLbRule(LoadBalancingRule lbRule) { Network network = _networkDao.findById(lbRule.getNetworkId()); Purpose purpose = lbRule.getPurpose(); if (purpose != Purpose.LoadBalancing) { @@ -748,7 +840,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements // by CloudStack and update them in lbvmmap table @DB @Override - public void updateLBHealthChecks() throws ResourceUnavailableException { + public void updateLBHealthChecks(Scheme scheme) throws ResourceUnavailableException { List rules = _lbDao.listAll(); List networks = _networkDao.listAll(); List stateRules = null; @@ -763,7 +855,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements * "HealthCheck Manager :: LB Provider in the Network has the Healthcheck policy capability :: " * + provider.get(0).getName()); */ - rules = _lbDao.listByNetworkId(network.getId()); + rules = _lbDao.listByNetworkIdAndScheme(network.getId(), scheme); if (rules != null && rules.size() > 0) { List lbrules = new ArrayList(); for (LoadBalancerVO lb : rules) { @@ -772,7 +864,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements // adding to lbrules list only if the LB rule // hashealtChecks if (hcPolicyList != null && hcPolicyList.size() > 0) { - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, null, hcPolicyList); + Ip sourceIp = getSourceIp(lb); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, null, hcPolicyList, sourceIp); lbrules.add(loadBalancing); } } @@ -1168,31 +1261,21 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements @Override @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_CREATE, eventDescription = "creating load balancer") - public LoadBalancer createLoadBalancerRule(CreateLoadBalancerRuleCmd lb, boolean openFirewall) + public LoadBalancer createPublicLoadBalancerRule(String xId, String name, String description, + int srcPortStart, int srcPortEnd, int defPortStart, int defPortEnd, Long ipAddrId, String protocol, String algorithm, long networkId, long lbOwnerId, boolean openFirewall) throws NetworkRuleConflictException, InsufficientAddressCapacityException { - Account lbOwner = _accountMgr.getAccount(lb.getEntityOwnerId()); - - int defPortStart = lb.getDefaultPortStart(); - int defPortEnd = lb.getDefaultPortEnd(); - - if (!NetUtils.isValidPort(defPortEnd)) { - throw new InvalidParameterValueException("privatePort is an invalid value: " + defPortEnd); - } - if (defPortStart > defPortEnd) { - throw new InvalidParameterValueException("private port range is invalid: " + defPortStart + "-" - + defPortEnd); - } - if ((lb.getAlgorithm() == null) || !NetUtils.isValidAlgorithm(lb.getAlgorithm())) { - throw new InvalidParameterValueException("Invalid algorithm: " + lb.getAlgorithm()); + Account lbOwner = _accountMgr.getAccount(lbOwnerId); + + if (srcPortStart != srcPortEnd) { + throw new InvalidParameterValueException("Port ranges are not supported by the load balancer"); } - Long ipAddrId = lb.getSourceIpAddressId(); IPAddressVO ipVO = null; if (ipAddrId != null) { ipVO = _ipAddressDao.findById(ipAddrId); } - Network network = _networkModel.getNetwork(lb.getNetworkId()); + Network network = _networkModel.getNetwork(networkId); // FIXME: breaking the dependency on ELB manager. This breaks // functionality of ELB using virtual router @@ -1204,8 +1287,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements IpAddress systemIp = null; NetworkOffering off = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); if (off.getElasticLb() && ipVO == null && network.getVpcId() == null) { - systemIp = _networkMgr.assignSystemIp(lb.getNetworkId(), lbOwner, true, false); - lb.setSourceIpAddressId(systemIp.getId()); + systemIp = _networkMgr.assignSystemIp(networkId, lbOwner, true, false); ipVO = _ipAddressDao.findById(systemIp.getId()); } @@ -1224,11 +1306,11 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements && ipVO.getVpcId().longValue() == network.getVpcId(); if (assignToVpcNtwk) { // set networkId just for verification purposes - _networkModel.checkIpForService(ipVO, Service.Lb, lb.getNetworkId()); + _networkModel.checkIpForService(ipVO, Service.Lb, networkId); - s_logger.debug("The ip is not associated with the VPC network id=" + lb.getNetworkId() + s_logger.debug("The ip is not associated with the VPC network id=" + networkId + " so assigning"); - ipVO = _networkMgr.associateIPToGuestNetwork(ipAddrId, lb.getNetworkId(), false); + ipVO = _networkMgr.associateIPToGuestNetwork(ipAddrId, networkId, false); performedIpAssoc = true; } } else { @@ -1240,10 +1322,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements + network); } - if (lb.getSourceIpAddressId() == null) { - throw new CloudRuntimeException("No ip address is defined to assign the LB to"); - } - result = createLoadBalancer(lb, openFirewall); + result = createPublicLoadBalancer(xId, name, description, srcPortStart, defPortStart, ipVO.getId(), protocol, algorithm, openFirewall, UserContext.current()); } catch (Exception ex) { s_logger.warn("Failed to create load balancer due to ", ex); if (ex instanceof NetworkRuleConflictException) { @@ -1258,27 +1337,31 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements // release ip address if ipassoc was perfored if (performedIpAssoc) { ipVO = _ipAddressDao.findById(ipVO.getId()); - _vpcMgr.unassignIPFromVpcNetwork(ipVO.getId(), lb.getNetworkId()); + _vpcMgr.unassignIPFromVpcNetwork(ipVO.getId(), networkId); } } } if (result == null) { - throw new CloudRuntimeException("Failed to create load balancer rule: " + lb.getName()); + throw new CloudRuntimeException("Failed to create load balancer rule: " + name); } return result; } - @Override @DB - public LoadBalancer createLoadBalancer(CreateLoadBalancerRuleCmd lb, boolean openFirewall) + @Override + public LoadBalancer createPublicLoadBalancer(String xId, String name, String description, + int srcPort, int destPort, long sourceIpId, String protocol, String algorithm, boolean openFirewall, UserContext caller) throws NetworkRuleConflictException { - UserContext caller = UserContext.current(); - int srcPortStart = lb.getSourcePortStart(); - int defPortStart = lb.getDefaultPortStart(); - int srcPortEnd = lb.getSourcePortEnd(); - long sourceIpId = lb.getSourceIpAddressId(); + + if (!NetUtils.isValidPort(destPort)) { + throw new InvalidParameterValueException("privatePort is an invalid value: " + destPort); + } + + if ((algorithm == null) || !NetUtils.isValidAlgorithm(algorithm)) { + throw new InvalidParameterValueException("Invalid algorithm: " + algorithm); + } IPAddressVO ipAddr = _ipAddressDao.findById(sourceIpId); // make sure ip address exists @@ -1293,6 +1376,9 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); throw ex; } + + _accountMgr.checkAccess(caller.getCaller(), null, true, ipAddr); + Long networkId = ipAddr.getAssociatedWithNetworkId(); if (networkId == null) { @@ -1301,39 +1387,34 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); throw ex; } - - _firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(), - Purpose.LoadBalancing, FirewallRuleType.User, networkId, null); - NetworkVO network = _networkDao.findById(networkId); - _accountMgr.checkAccess(caller.getCaller(), null, true, ipAddr); - + // verify that lb service is supported by the network - if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb)) { - InvalidParameterValueException ex = new InvalidParameterValueException( - "LB service is not supported in specified network id"); - ex.addProxyObject(network, networkId, "networkId"); - throw ex; + isLbServiceSupportedInNetwork(networkId, Scheme.Public); + + _firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPort, srcPort, protocol, + Purpose.LoadBalancing, FirewallRuleType.User, networkId, null); + + LoadBalancerVO newRule = new LoadBalancerVO(xId, name, description, + sourceIpId, srcPort, srcPort, algorithm, + networkId, ipAddr.getAllocatedToAccountId(), ipAddr.getAllocatedInDomainId()); + + // verify rule is supported by Lb provider of the network + Ip sourceIp = getSourceIp(newRule); + LoadBalancingRule loadBalancing = new LoadBalancingRule(newRule, new ArrayList(), + new ArrayList(), new ArrayList(), sourceIp); + if (!validateLbRule(loadBalancing)) { + throw new InvalidParameterValueException("LB service provider cannot support this rule"); } Transaction txn = Transaction.currentTxn(); txn.start(); - - LoadBalancerVO newRule = new LoadBalancerVO(lb.getXid(), lb.getName(), lb.getDescription(), - lb.getSourceIpAddressId(), lb.getSourcePortEnd(), lb.getDefaultPortStart(), lb.getAlgorithm(), - network.getId(), ipAddr.getAllocatedToAccountId(), ipAddr.getAllocatedInDomainId()); - - // verify rule is supported by Lb provider of the network - LoadBalancingRule loadBalancing = new LoadBalancingRule(newRule, new ArrayList(), - new ArrayList(), new ArrayList()); - if (!validateRule(loadBalancing)) { - throw new InvalidParameterValueException("LB service provider cannot support this rule"); - } - + newRule = _lbDao.persist(newRule); + //create rule for all CIDRs if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCaller(), lb.getSourcePortStart(), - lb.getSourcePortEnd(), lb.getProtocol(), null, null, newRule.getId(), networkId); + _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCaller(), srcPort, + srcPort, protocol, null, null, newRule.getId(), networkId); } boolean success = true; @@ -1344,7 +1425,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } s_logger.debug("Load balancer " + newRule.getId() + " for Ip address id=" + sourceIpId + ", public port " - + srcPortStart + ", private port " + defPortStart + " is added successfully."); + + srcPort + ", private port " + destPort + " is added successfully."); UserContext.current().setEventDetails("Load balancer Id: " + newRule.getId()); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_CREATE, ipAddr.getAllocatedToAccountId(), ipAddr.getDataCenterId(), newRule.getId(), null, LoadBalancingRule.class.getName(), @@ -1380,14 +1461,17 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements lbs = Arrays.asList(lb); } else { // get all rules in transition state - lbs = _lbDao.listInTransitionStateByNetworkId(lb.getNetworkId()); + lbs = _lbDao.listInTransitionStateByNetworkIdAndScheme(lb.getNetworkId(), lb.getScheme()); } return applyLoadBalancerRules(lbs, true); } @Override - public boolean revokeLoadBalancersForNetwork(long networkId) throws ResourceUnavailableException { - List lbs = _lbDao.listByNetworkId(networkId); + public boolean revokeLoadBalancersForNetwork(long networkId, Scheme scheme) throws ResourceUnavailableException { + List lbs = _lbDao.listByNetworkIdAndScheme(networkId, scheme); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Revoking " + lbs.size() + " " + scheme + " load balancing rules for network id=" + networkId); + } if (lbs != null) { for(LoadBalancerVO lb : lbs) { // called during restart, not persisting state in db lb.setState(FirewallRule.State.Revoke); @@ -1400,20 +1484,20 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } @Override - public boolean applyLoadBalancersForNetwork(long networkId) throws ResourceUnavailableException { - List lbs = _lbDao.listByNetworkId(networkId); + public boolean applyLoadBalancersForNetwork(long networkId, Scheme scheme) throws ResourceUnavailableException { + List lbs = _lbDao.listByNetworkIdAndScheme(networkId, scheme); if (lbs != null) { + s_logger.debug("Applying load balancer rules of scheme " + scheme + " in network id=" + networkId); return applyLoadBalancerRules(lbs, true); } else { - s_logger.info("Network id=" + networkId + " doesn't have load balancer rules, nothing to apply"); + s_logger.info("Network id=" + networkId + " doesn't have load balancer rules of scheme " + scheme + ", nothing to apply"); return true; } } - @Override - public boolean applyRules(Network network, Purpose purpose, List rules) + + protected boolean applyLbRules(Network network, List rules) throws ResourceUnavailableException { - assert (purpose == Purpose.LoadBalancing) : "LB Manager asked to handle non-LB rules"; boolean handled = false; for (LoadBalancingServiceProvider lbElement : _lbProviders) { Provider provider = lbElement.getProvider(); @@ -1422,7 +1506,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements if (!isLbProvider) { continue; } - handled = lbElement.applyLBRules(network, (List) rules); + handled = lbElement.applyLBRules(network, rules); if (handled) break; } @@ -1432,7 +1516,8 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements private LoadBalancingRule getLoadBalancerRuleToApply(LoadBalancerVO lb) { List policyList = getStickinessPolicies(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, null, policyList, null); + Ip sourceIp = getSourceIp(lb); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, null, policyList, null, sourceIp); if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(lb.getId())) { // Get the associated VmGroup @@ -1442,7 +1527,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } else { List dstList = getExistingDestinations(lb.getId()); loadBalancing.setDestinations(dstList); - List hcPolicyList = getHealthCheckPolicies(lb.getId()); + List hcPolicyList = getHealthCheckPolicies(lb.getId()); loadBalancing.setHealthCheckPolicies(hcPolicyList); } @@ -1458,7 +1543,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements rules.add(getLoadBalancerRuleToApply(lb)); } - if (!_networkMgr.applyRules(rules, FirewallRule.Purpose.LoadBalancing, this, false)) { + if (!applyLbRules(rules, false)) { s_logger.debug("LB rules are not completely applied"); return false; } @@ -1515,7 +1600,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } txn.commit(); - if (checkForReleaseElasticIp) { + if (checkForReleaseElasticIp && lb.getSourceIpAddressId() != null) { boolean success = true; long count = _firewallDao.countRulesByIpId(lb.getSourceIpAddressId()); if (count == 0) { @@ -1534,8 +1619,10 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements } // if the rule is the last one for the ip address assigned to // VPC, unassign it from the network - IpAddress ip = _ipAddressDao.findById(lb.getSourceIpAddressId()); - _vpcMgr.unassignIPFromVpcNetwork(ip.getId(), lb.getNetworkId()); + if (lb.getSourceIpAddressId() != null) { + IpAddress ip = _ipAddressDao.findById(lb.getSourceIpAddressId()); + _vpcMgr.unassignIPFromVpcNetwork(ip.getId(), lb.getNetworkId()); + } } } @@ -1902,32 +1989,115 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements count++; } } + + //list only Public load balancers using this command + sc.setParameters("scheme", Scheme.Public); Pair, Integer> result = _lbDao.searchAndCount(sc, searchFilter); return new Pair, Integer>(result.first(), result.second()); } - @Override - public List listByNetworkId(long networkId) { - List lbs = _lbDao.listByNetworkId(networkId); - List lbRules = new ArrayList(); - for (LoadBalancerVO lb : lbs) { - List dstList = getExistingDestinations(lb.getId()); - List policyList = this.getStickinessPolicies(lb.getId()); - List hcPolicyList = this.getHealthCheckPolicies(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList); - lbRules.add(loadBalancing); - } - return lbRules; - } @Override public LoadBalancerVO findById(long lbId) { return _lbDao.findById(lbId); } - protected void removeLBRule(LoadBalancerVO rule) { + @Override + public void removeLBRule(LoadBalancer rule) { // remove the rule _lbDao.remove(rule.getId()); } + + + public boolean applyLbRules(List rules, boolean continueOnError) throws ResourceUnavailableException { + if (rules == null || rules.size() == 0) { + s_logger.debug("There are no Load Balancing Rules to forward to the network elements"); + return true; + } + + boolean success = true; + Network network = _networkModel.getNetwork(rules.get(0).getNetworkId()); + List publicIps = new ArrayList(); + + + // get the list of public ip's owned by the network + List userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null); + if (userIps != null && !userIps.isEmpty()) { + for (IPAddressVO userIp : userIps) { + PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId())); + publicIps.add(publicIp); + } + } + + // rules can not programmed unless IP is associated with network + // service provider, so run IP assoication for + // the network so as to ensure IP is associated before applying + // rules (in add state) + _networkMgr.applyIpAssociations(network, false, continueOnError, publicIps); + + + try { + applyLbRules(network, rules); + } catch (ResourceUnavailableException e) { + if (!continueOnError) { + throw e; + } + s_logger.warn("Problems with applying load balancing rules but pushing on", e); + success = false; + } + + // if all the rules configured on public IP are revoked then + // dis-associate IP with network service provider + _networkMgr.applyIpAssociations(network, true, continueOnError, publicIps); + + return success; + } + + @Override + public Map getLbInstances(long lbId) { + Map dstList = new HashMap(); + List lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lbId); + LoadBalancerVO lb = _lbDao.findById(lbId); + + for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) { + UserVm vm = _vmDao.findById(lbVmMap.getInstanceId()); + Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(lb.getNetworkId(), vm.getId()); + Ip ip = new Ip(nic.getIp4Address()); + dstList.put(ip, vm); + } + return dstList; + } + + @Override + public void isLbServiceSupportedInNetwork(long networkId, Scheme scheme) { + Network network = _networkDao.findById(networkId); + + //1) Check if the LB service is supported + if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb)) { + InvalidParameterValueException ex = new InvalidParameterValueException( + "LB service is not supported in specified network id"); + ex.addProxyObject(network, network.getId(), "networkId"); + throw ex; + } + + //2) Check if the Scheme is supported\ + NetworkOffering off = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); + if (scheme == Scheme.Public) { + if (!off.getPublicLb()) { + throw new InvalidParameterValueException("Scheme " + scheme + " is not supported by the network offering " + off); + } + } else { + if (!off.getInternalLb()) { + throw new InvalidParameterValueException("Scheme " + scheme + " is not supported by the network offering " + off); + } + } + + //3) Check if the provider supports the scheme + LoadBalancingServiceProvider lbProvider = _networkMgr.getLoadBalancingProviderForNetwork(network, scheme); + if (lbProvider == null) { + throw new InvalidParameterValueException("Lb rule with scheme " + scheme.toString() + " is not supported by lb providers in network " + network); + } + } + } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java index f49ab79b500..fcf650f900c 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -28,6 +28,7 @@ import com.cloud.network.PublicIpAddress; import com.cloud.network.RemoteAccessVpn; import com.cloud.network.VirtualNetworkApplianceService; import com.cloud.network.VpnUser; +import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.StaticNat; import com.cloud.user.Account; @@ -103,4 +104,7 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA boolean applyUserData(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, List routers) throws ResourceUnavailableException; + + boolean applyLoadBalancingRules(Network network, List rules, List routers) throws ResourceUnavailableException; + } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 6620e0a6379..e3dd06ba47c 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -173,6 +173,7 @@ import com.cloud.network.router.VirtualRouter.RedundantState; import com.cloud.network.router.VirtualRouter.Role; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule.Purpose; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.RulesManager; import com.cloud.network.rules.StaticNat; @@ -218,6 +219,7 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.Ip; import com.cloud.utils.net.MacAddress; import com.cloud.utils.net.NetUtils; import com.cloud.vm.DomainRouterVO; @@ -1526,7 +1528,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V for (int i = 0; i < count; i++) { List> networks = createRouterNetworks(owner, isRedundant, plan, guestNetwork, new Pair(publicNetwork, sourceNatIp)); - //don't start the router as we are holding the network lock that needs to be released at the end of router allocation + //don't start the router as we are holding the network lock that needs to be released at the end of router allocation DomainRouterVO router = deployRouter(owner, destination, plan, params, isRedundant, vrProvider, offeringId, null, networks, false, null); @@ -2410,7 +2412,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } } - List lbs = _loadBalancerDao.listByNetworkId(guestNetworkId); + List lbs = _loadBalancerDao.listByNetworkIdAndScheme(guestNetworkId, Scheme.Public); List lbRules = new ArrayList(); if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Lb, provider)) { // Re-apply load balancing rules @@ -2418,7 +2420,8 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V List dstList = _lbMgr.getExistingDestinations(lb.getId()); List policyList = _lbMgr.getStickinessPolicies(lb.getId()); List hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList); + Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress(); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp); lbRules.add(loadBalancing); } } @@ -2509,7 +2512,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V Network network = _networkModel.getNetwork(routerNic.getNetworkId()); if (network.getTrafficType() == TrafficType.Guest) { guestNetworks.add(network); - } + } } answer = cmds.getAnswer("getDomRVersion"); @@ -3036,7 +3039,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V String algorithm = rule.getAlgorithm(); String uuid = rule.getUuid(); - String srcIp = _networkModel.getIp(rule.getSourceIpAddressId()).getAddress().addr(); + String srcIp = rule.getSourceIp().addr(); int srcPort = rule.getSourcePortStart(); List destinations = rule.getDestinations(); List stickinessPolicies = rule.getStickinessPolicies(); @@ -3051,7 +3054,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } Network guestNetwork = _networkModel.getNetwork(guestNetworkId); - Nic nic = _nicDao.findByInstanceIdAndNetworkId(guestNetwork.getId(), router.getId()); + Nic nic = _nicDao.findByNtwkIdAndInstanceId(guestNetwork.getId(), router.getId()); NicProfile nicProfile = new NicProfile(nic, guestNetwork, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(guestNetwork.getId(), router.getId()), _networkModel.isSecurityGroupSupportedInNetwork(guestNetwork), @@ -3144,7 +3147,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } if (createVmData) { - NicVO nic = _nicDao.findByInstanceIdAndNetworkId(guestNetworkId, vm.getId()); + NicVO nic = _nicDao.findByNtwkIdAndInstanceId(guestNetworkId, vm.getId()); if (nic != null) { s_logger.debug("Creating user data entry for vm " + vm + " on domR " + router); createVmDataCommand(router, vm, nic, null, cmds); @@ -3197,7 +3200,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V createDhcp = false; } if (createDhcp) { - NicVO nic = _nicDao.findByInstanceIdAndNetworkId(guestNetworkId, vm.getId()); + NicVO nic = _nicDao.findByNtwkIdAndInstanceId(guestNetworkId, vm.getId()); if (nic != null) { s_logger.debug("Creating dhcp entry for vm " + vm + " on domR " + router + "."); createDhcpEntryCommand(router, vm, nic, cmds); @@ -3315,13 +3318,14 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { if (rules.get(0).getPurpose() == Purpose.LoadBalancing) { // for load balancer we have to resend all lb rules for the network - List lbs = _loadBalancerDao.listByNetworkId(network.getId()); + List lbs = _loadBalancerDao.listByNetworkIdAndScheme(network.getId(), Scheme.Public); List lbRules = new ArrayList(); for (LoadBalancerVO lb : lbs) { List dstList = _lbMgr.getExistingDestinations(lb.getId()); List policyList = _lbMgr.getStickinessPolicies(lb.getId()); - List hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId() ); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList); + List hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId()); + Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress(); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp); lbRules.add(loadBalancing); } return sendLBRules(router, lbRules, network.getId()); @@ -3338,6 +3342,32 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } }); } + + + @Override + public boolean applyLoadBalancingRules(Network network, final List rules, List routers) throws ResourceUnavailableException { + if (rules == null || rules.isEmpty()) { + s_logger.debug("No lb rules to be applied for network " + network.getId()); + return true; + } + return applyRules(network, routers, "loadbalancing rules", false, null, false, new RuleApplier() { + @Override + public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { + // for load balancer we have to resend all lb rules for the network + List lbs = _loadBalancerDao.listByNetworkIdAndScheme(network.getId(), Scheme.Public); + List lbRules = new ArrayList(); + for (LoadBalancerVO lb : lbs) { + List dstList = _lbMgr.getExistingDestinations(lb.getId()); + List policyList = _lbMgr.getStickinessPolicies(lb.getId()); + List hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId()); + Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress(); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp); + lbRules.add(loadBalancing); + } + return sendLBRules(router, lbRules, network.getId()); + } + }); + } protected boolean sendLBRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); @@ -3734,4 +3764,11 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } } } + + + + @Override + public VirtualRouter findRouter(long routerId) { + return _routerDao.findById(routerId); + } } diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java index ebf2d4257e3..611100955e7 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -440,7 +440,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian defaultDns2 = guestNic.getDns2(); } - Nic nic = _nicDao.findByInstanceIdAndNetworkId(network.getId(), router.getId()); + Nic nic = _nicDao.findByNtwkIdAndInstanceId(network.getId(), router.getId()); String networkDomain = network.getNetworkDomain(); String dhcpRange = getGuestDhcpRange(guestNic, network, _configMgr.getZone(network.getDataCenterId())); diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 9be22084e11..55656d8b4fb 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -184,7 +184,9 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker")); private List vpcElements = null; private final List nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall); - private final List supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.Netscaler); + private final List supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler); + + int _cleanupInterval; int _maxNetworks; SearchBuilder IpAddressSearch; @@ -206,6 +208,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis if (svc == Service.Lb) { Set lbProviders = new HashSet(); lbProviders.add(Provider.VPCVirtualRouter); + lbProviders.add(Provider.InternalLbVm); svcProviderMap.put(svc, lbProviders); } else { svcProviderMap.put(svc, defaultProviders); @@ -1057,16 +1060,17 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis } } - //4) Only one network in the VPC can support LB - if (_ntwkModel.areServicesSupportedByNetworkOffering(guestNtwkOff.getId(), Service.Lb)) { + //4) Only one network in the VPC can support public LB inside the VPC. Internal LB can be supported on multiple VPC tiers + if (_ntwkModel.areServicesSupportedByNetworkOffering(guestNtwkOff.getId(), Service.Lb) && guestNtwkOff.getPublicLb()) { List networks = getVpcNetworks(vpc.getId()); for (Network network : networks) { if (networkId != null && network.getId() == networkId.longValue()) { //skip my own network continue; } else { - if (_ntwkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb)) { - throw new InvalidParameterValueException("LB service is already supported " + + NetworkOffering otherOff = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); + if (_ntwkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb) && otherOff.getPublicLb()) { + throw new InvalidParameterValueException("Public LB service is already supported " + "by network " + network + " in VPC " + vpc); } } diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index 3d97447fe40..bc52e9a881c 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -1017,7 +1017,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio "Offering for Shared Security group enabled networks", TrafficType.Guest, false, true, null, null, true, Availability.Optional, - null, Network.GuestType.Shared, true, true, false); + null, Network.GuestType.Shared, true, true, false, false, false); defaultSharedSGNetworkOffering.setState(NetworkOffering.State.Enabled); defaultSharedSGNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedSGNetworkOffering); @@ -1034,7 +1034,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio "Offering for Shared networks", TrafficType.Guest, false, true, null, null, true, Availability.Optional, - null, Network.GuestType.Shared, true, true, false); + null, Network.GuestType.Shared, true, true, false, false, false); defaultSharedNetworkOffering.setState(NetworkOffering.State.Enabled); defaultSharedNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedNetworkOffering); @@ -1051,7 +1051,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, false, false, null, null, true, Availability.Required, - null, Network.GuestType.Isolated, true, false, false); + null, Network.GuestType.Isolated, true, false, false, false, true); defaultIsolatedSourceNatEnabledNetworkOffering.setState(NetworkOffering.State.Enabled); defaultIsolatedSourceNatEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedSourceNatEnabledNetworkOffering); @@ -1069,7 +1069,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio "Offering for Isolated networks with no Source Nat service", TrafficType.Guest, false, true, null, null, true, Availability.Optional, - null, Network.GuestType.Isolated, true, true, false); + null, Network.GuestType.Isolated, true, true, false, false, false); defaultIsolatedEnabledNetworkOffering.setState(NetworkOffering.State.Enabled); defaultIsolatedEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedEnabledNetworkOffering); @@ -1086,7 +1086,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, false, true, null, null, true, Availability.Optional, - null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true); + null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true, true, false); defaultNetscalerNetworkOffering.setState(NetworkOffering.State.Enabled); defaultNetscalerNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetscalerNetworkOffering); @@ -1103,7 +1103,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio "Offering for Isolated Vpc networks with Source Nat service enabled", TrafficType.Guest, false, false, null, null, true, Availability.Optional, - null, Network.GuestType.Isolated, false, false, false); + null, Network.GuestType.Isolated, false, false, false, false, true); defaultNetworkOfferingForVpcNetworks.setState(NetworkOffering.State.Enabled); defaultNetworkOfferingForVpcNetworks = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworks); @@ -1133,7 +1133,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio "Offering for Isolated Vpc networks with Source Nat service enabled and LB service Disabled", TrafficType.Guest, false, false, null, null, true, Availability.Optional, - null, Network.GuestType.Isolated, false, false, false); + null, Network.GuestType.Isolated, false, false, false, false, false); defaultNetworkOfferingForVpcNetworksNoLB.setState(NetworkOffering.State.Enabled); defaultNetworkOfferingForVpcNetworksNoLB = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworksNoLB); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index da8f30ed759..86c1a640da9 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -34,7 +34,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; -import java.util.UUID; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -44,52 +43,371 @@ import javax.crypto.spec.SecretKeySpec; import javax.inject.Inject; import javax.naming.ConfigurationException; -import com.cloud.configuration.*; -import com.cloud.storage.dao.*; +import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker.AccessType; -import org.apache.cloudstack.api.ApiConstants; - -import com.cloud.event.ActionEventUtils; -import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd; -import org.apache.cloudstack.api.command.admin.account.*; -import org.apache.cloudstack.api.command.admin.domain.*; -import org.apache.cloudstack.api.command.admin.host.*; -import org.apache.cloudstack.api.command.admin.network.*; -import org.apache.cloudstack.api.command.admin.offering.*; -import org.apache.cloudstack.api.command.admin.resource.*; -import org.apache.cloudstack.api.command.admin.router.*; -import org.apache.cloudstack.api.command.admin.storage.*; -import org.apache.cloudstack.api.command.admin.systemvm.*; -import org.apache.cloudstack.api.command.admin.usage.*; -import org.apache.cloudstack.api.command.admin.user.*; -import org.apache.cloudstack.api.command.admin.vlan.*; -import org.apache.cloudstack.api.command.admin.vpc.*; -import org.apache.cloudstack.api.command.user.autoscale.*; -import org.apache.cloudstack.api.command.user.firewall.*; -import org.apache.cloudstack.api.command.user.iso.*; -import org.apache.cloudstack.api.command.user.loadbalancer.*; -import org.apache.cloudstack.api.command.user.nat.*; -import org.apache.cloudstack.api.command.user.network.*; -import org.apache.cloudstack.api.command.user.project.*; -import org.apache.cloudstack.api.command.user.resource.*; -import org.apache.cloudstack.api.command.user.securitygroup.*; -import org.apache.cloudstack.api.command.user.snapshot.*; -import org.apache.cloudstack.api.command.user.template.*; -import org.apache.cloudstack.api.command.user.vm.*; -import org.apache.cloudstack.api.command.user.volume.*; -import org.apache.cloudstack.api.command.user.vpc.*; -import org.apache.cloudstack.api.command.user.vpn.*; -import org.apache.cloudstack.api.response.ExtractResponse; -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; import org.apache.cloudstack.affinity.AffinityGroupProcessor; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; - +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd; +import org.apache.cloudstack.api.command.admin.account.CreateAccountCmd; +import org.apache.cloudstack.api.command.admin.account.DeleteAccountCmd; +import org.apache.cloudstack.api.command.admin.account.DisableAccountCmd; +import org.apache.cloudstack.api.command.admin.account.EnableAccountCmd; +import org.apache.cloudstack.api.command.admin.account.LockAccountCmd; +import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd; +import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd; +import org.apache.cloudstack.api.command.admin.autoscale.DeleteCounterCmd; +import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd; +import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd; +import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd; +import org.apache.cloudstack.api.command.admin.cluster.UpdateClusterCmd; +import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd; +import org.apache.cloudstack.api.command.admin.config.ListHypervisorCapabilitiesCmd; +import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd; +import org.apache.cloudstack.api.command.admin.config.UpdateHypervisorCapabilitiesCmd; +import org.apache.cloudstack.api.command.admin.domain.CreateDomainCmd; +import org.apache.cloudstack.api.command.admin.domain.DeleteDomainCmd; +import org.apache.cloudstack.api.command.admin.domain.ListDomainChildrenCmd; +import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmd; +import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd; +import org.apache.cloudstack.api.command.admin.host.AddHostCmd; +import org.apache.cloudstack.api.command.admin.host.AddSecondaryStorageCmd; +import org.apache.cloudstack.api.command.admin.host.CancelMaintenanceCmd; +import org.apache.cloudstack.api.command.admin.host.DeleteHostCmd; +import org.apache.cloudstack.api.command.admin.host.FindHostsForMigrationCmd; +import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; +import org.apache.cloudstack.api.command.admin.host.PrepareForMaintenanceCmd; +import org.apache.cloudstack.api.command.admin.host.ReconnectHostCmd; +import org.apache.cloudstack.api.command.admin.host.UpdateHostCmd; +import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd; +import org.apache.cloudstack.api.command.admin.internallb.ConfigureInternalLoadBalancerElementCmd; +import org.apache.cloudstack.api.command.admin.internallb.CreateInternalLoadBalancerElementCmd; +import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd; +import org.apache.cloudstack.api.command.admin.internallb.ListInternalLoadBalancerElementsCmd; +import org.apache.cloudstack.api.command.admin.internallb.StartInternalLBVMCmd; +import org.apache.cloudstack.api.command.admin.internallb.StopInternalLBVMCmd; +import org.apache.cloudstack.api.command.admin.ldap.LDAPConfigCmd; +import org.apache.cloudstack.api.command.admin.ldap.LDAPRemoveCmd; +import org.apache.cloudstack.api.command.admin.network.AddNetworkDeviceCmd; +import org.apache.cloudstack.api.command.admin.network.AddNetworkServiceProviderCmd; +import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd; +import org.apache.cloudstack.api.command.admin.network.CreatePhysicalNetworkCmd; +import org.apache.cloudstack.api.command.admin.network.CreateStorageNetworkIpRangeCmd; +import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; +import org.apache.cloudstack.api.command.admin.network.DeleteNetworkDeviceCmd; +import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd; +import org.apache.cloudstack.api.command.admin.network.DeleteNetworkServiceProviderCmd; +import org.apache.cloudstack.api.command.admin.network.DeletePhysicalNetworkCmd; +import org.apache.cloudstack.api.command.admin.network.DeleteStorageNetworkIpRangeCmd; +import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; +import org.apache.cloudstack.api.command.admin.network.ListNetworkDeviceCmd; +import org.apache.cloudstack.api.command.admin.network.ListNetworkIsolationMethodsCmd; +import org.apache.cloudstack.api.command.admin.network.ListNetworkServiceProvidersCmd; +import org.apache.cloudstack.api.command.admin.network.ListPhysicalNetworksCmd; +import org.apache.cloudstack.api.command.admin.network.ListStorageNetworkIpRangeCmd; +import org.apache.cloudstack.api.command.admin.network.ListSupportedNetworkServicesCmd; +import org.apache.cloudstack.api.command.admin.network.ReleaseDedicatedGuestVlanRangeCmd; +import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd; +import org.apache.cloudstack.api.command.admin.network.UpdateNetworkServiceProviderCmd; +import org.apache.cloudstack.api.command.admin.network.UpdatePhysicalNetworkCmd; +import org.apache.cloudstack.api.command.admin.network.UpdateStorageNetworkIpRangeCmd; +import org.apache.cloudstack.api.command.admin.offering.CreateDiskOfferingCmd; +import org.apache.cloudstack.api.command.admin.offering.CreateServiceOfferingCmd; +import org.apache.cloudstack.api.command.admin.offering.DeleteDiskOfferingCmd; +import org.apache.cloudstack.api.command.admin.offering.DeleteServiceOfferingCmd; +import org.apache.cloudstack.api.command.admin.offering.UpdateDiskOfferingCmd; +import org.apache.cloudstack.api.command.admin.offering.UpdateServiceOfferingCmd; +import org.apache.cloudstack.api.command.admin.pod.CreatePodCmd; +import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd; +import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd; +import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd; +import org.apache.cloudstack.api.command.admin.region.AddRegionCmd; +import org.apache.cloudstack.api.command.admin.region.RemoveRegionCmd; +import org.apache.cloudstack.api.command.admin.region.UpdateRegionCmd; +import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd; +import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd; +import org.apache.cloudstack.api.command.admin.resource.ListAlertsCmd; +import org.apache.cloudstack.api.command.admin.resource.ListCapacityCmd; +import org.apache.cloudstack.api.command.admin.resource.UploadCustomCertificateCmd; +import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd; +import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd; +import org.apache.cloudstack.api.command.admin.router.DestroyRouterCmd; +import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd; +import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd; +import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd; +import org.apache.cloudstack.api.command.admin.router.StartRouterCmd; +import org.apache.cloudstack.api.command.admin.router.StopRouterCmd; +import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd; +import org.apache.cloudstack.api.command.admin.storage.AddS3Cmd; +import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd; +import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd; +import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd; +import org.apache.cloudstack.api.command.admin.storage.FindStoragePoolsForMigrationCmd; +import org.apache.cloudstack.api.command.admin.storage.ListS3sCmd; +import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd; +import org.apache.cloudstack.api.command.admin.storage.ListStorageProvidersCmd; +import org.apache.cloudstack.api.command.admin.storage.PreparePrimaryStorageForMaintenanceCmd; +import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd; +import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd; +import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd; +import org.apache.cloudstack.api.command.admin.systemvm.DestroySystemVmCmd; +import org.apache.cloudstack.api.command.admin.systemvm.ListSystemVMsCmd; +import org.apache.cloudstack.api.command.admin.systemvm.MigrateSystemVMCmd; +import org.apache.cloudstack.api.command.admin.systemvm.RebootSystemVmCmd; +import org.apache.cloudstack.api.command.admin.systemvm.StartSystemVMCmd; +import org.apache.cloudstack.api.command.admin.systemvm.StopSystemVmCmd; +import org.apache.cloudstack.api.command.admin.systemvm.UpgradeSystemVMCmd; +import org.apache.cloudstack.api.command.admin.template.PrepareTemplateCmd; +import org.apache.cloudstack.api.command.admin.usage.AddTrafficMonitorCmd; +import org.apache.cloudstack.api.command.admin.usage.AddTrafficTypeCmd; +import org.apache.cloudstack.api.command.admin.usage.DeleteTrafficMonitorCmd; +import org.apache.cloudstack.api.command.admin.usage.DeleteTrafficTypeCmd; +import org.apache.cloudstack.api.command.admin.usage.GenerateUsageRecordsCmd; +import org.apache.cloudstack.api.command.admin.usage.GetUsageRecordsCmd; +import org.apache.cloudstack.api.command.admin.usage.ListTrafficMonitorsCmd; +import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd; +import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypesCmd; +import org.apache.cloudstack.api.command.admin.usage.ListUsageTypesCmd; +import org.apache.cloudstack.api.command.admin.usage.UpdateTrafficTypeCmd; +import org.apache.cloudstack.api.command.admin.user.CreateUserCmd; +import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd; +import org.apache.cloudstack.api.command.admin.user.DisableUserCmd; +import org.apache.cloudstack.api.command.admin.user.EnableUserCmd; +import org.apache.cloudstack.api.command.admin.user.GetUserCmd; +import org.apache.cloudstack.api.command.admin.user.ListUsersCmd; +import org.apache.cloudstack.api.command.admin.user.LockUserCmd; +import org.apache.cloudstack.api.command.admin.user.RegisterCmd; +import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; +import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd; +import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd; +import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd; +import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd; +import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd; +import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd; +import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd; +import org.apache.cloudstack.api.command.admin.vm.MigrateVirtualMachineWithVolumeCmd; +import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd; +import org.apache.cloudstack.api.command.admin.vpc.CreatePrivateGatewayCmd; +import org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd; +import org.apache.cloudstack.api.command.admin.vpc.DeletePrivateGatewayCmd; +import org.apache.cloudstack.api.command.admin.vpc.DeleteVPCOfferingCmd; +import org.apache.cloudstack.api.command.admin.vpc.UpdateVPCOfferingCmd; +import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd; +import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd; +import org.apache.cloudstack.api.command.admin.zone.MarkDefaultZoneForAccountCmd; +import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd; +import org.apache.cloudstack.api.command.user.account.AddAccountToProjectCmd; +import org.apache.cloudstack.api.command.user.account.DeleteAccountFromProjectCmd; +import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; +import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd; +import org.apache.cloudstack.api.command.user.address.AssociateIPAddrCmd; +import org.apache.cloudstack.api.command.user.address.DisassociateIPAddrCmd; +import org.apache.cloudstack.api.command.user.address.ListPublicIpAddressesCmd; import org.apache.cloudstack.api.command.user.affinitygroup.CreateAffinityGroupCmd; import org.apache.cloudstack.api.command.user.affinitygroup.DeleteAffinityGroupCmd; import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupTypesCmd; import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupsCmd; import org.apache.cloudstack.api.command.user.affinitygroup.UpdateVMAffinityGroupCmd; +import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScalePolicyCmd; +import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScaleVmGroupCmd; +import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScaleVmProfileCmd; +import org.apache.cloudstack.api.command.user.autoscale.CreateConditionCmd; +import org.apache.cloudstack.api.command.user.autoscale.DeleteAutoScalePolicyCmd; +import org.apache.cloudstack.api.command.user.autoscale.DeleteAutoScaleVmGroupCmd; +import org.apache.cloudstack.api.command.user.autoscale.DeleteAutoScaleVmProfileCmd; +import org.apache.cloudstack.api.command.user.autoscale.DeleteConditionCmd; +import org.apache.cloudstack.api.command.user.autoscale.DisableAutoScaleVmGroupCmd; +import org.apache.cloudstack.api.command.user.autoscale.EnableAutoScaleVmGroupCmd; +import org.apache.cloudstack.api.command.user.autoscale.ListAutoScalePoliciesCmd; +import org.apache.cloudstack.api.command.user.autoscale.ListAutoScaleVmGroupsCmd; +import org.apache.cloudstack.api.command.user.autoscale.ListAutoScaleVmProfilesCmd; +import org.apache.cloudstack.api.command.user.autoscale.ListConditionsCmd; +import org.apache.cloudstack.api.command.user.autoscale.ListCountersCmd; +import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScalePolicyCmd; +import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmGroupCmd; +import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmProfileCmd; +import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd; +import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd; +import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd; +import org.apache.cloudstack.api.command.user.event.ListEventTypesCmd; +import org.apache.cloudstack.api.command.user.event.ListEventsCmd; +import org.apache.cloudstack.api.command.user.firewall.CreateEgressFirewallRuleCmd; +import org.apache.cloudstack.api.command.user.firewall.CreateFirewallRuleCmd; +import org.apache.cloudstack.api.command.user.firewall.CreatePortForwardingRuleCmd; +import org.apache.cloudstack.api.command.user.firewall.DeleteEgressFirewallRuleCmd; +import org.apache.cloudstack.api.command.user.firewall.DeleteFirewallRuleCmd; +import org.apache.cloudstack.api.command.user.firewall.DeletePortForwardingRuleCmd; +import org.apache.cloudstack.api.command.user.firewall.ListEgressFirewallRulesCmd; +import org.apache.cloudstack.api.command.user.firewall.ListFirewallRulesCmd; +import org.apache.cloudstack.api.command.user.firewall.ListPortForwardingRulesCmd; +import org.apache.cloudstack.api.command.user.firewall.UpdatePortForwardingRuleCmd; +import org.apache.cloudstack.api.command.user.guest.ListGuestOsCategoriesCmd; +import org.apache.cloudstack.api.command.user.guest.ListGuestOsCmd; +import org.apache.cloudstack.api.command.user.iso.AttachIsoCmd; +import org.apache.cloudstack.api.command.user.iso.CopyIsoCmd; +import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; +import org.apache.cloudstack.api.command.user.iso.DetachIsoCmd; +import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd; +import org.apache.cloudstack.api.command.user.iso.ListIsoPermissionsCmd; +import org.apache.cloudstack.api.command.user.iso.ListIsosCmd; +import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd; +import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd; +import org.apache.cloudstack.api.command.user.iso.UpdateIsoPermissionsCmd; +import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd; +import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.AssignToLoadBalancerRuleCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.CreateApplicationLoadBalancerCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerRuleCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.DeleteApplicationLoadBalancerCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.DeleteLBHealthCheckPolicyCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.DeleteLBStickinessPolicyCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.DeleteLoadBalancerRuleCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.ListApplicationLoadBalancersCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.ListLBHealthCheckPoliciesCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.ListLBStickinessPoliciesCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRuleInstancesCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRulesCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.RemoveFromLoadBalancerRuleCmd; +import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRuleCmd; +import org.apache.cloudstack.api.command.user.nat.CreateIpForwardingRuleCmd; +import org.apache.cloudstack.api.command.user.nat.DeleteIpForwardingRuleCmd; +import org.apache.cloudstack.api.command.user.nat.DisableStaticNatCmd; +import org.apache.cloudstack.api.command.user.nat.EnableStaticNatCmd; +import org.apache.cloudstack.api.command.user.nat.ListIpForwardingRulesCmd; +import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd; +import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; +import org.apache.cloudstack.api.command.user.network.DeleteNetworkACLCmd; +import org.apache.cloudstack.api.command.user.network.DeleteNetworkCmd; +import org.apache.cloudstack.api.command.user.network.ListNetworkACLsCmd; +import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd; +import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; +import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; +import org.apache.cloudstack.api.command.user.network.UpdateNetworkCmd; +import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd; +import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd; +import org.apache.cloudstack.api.command.user.project.ActivateProjectCmd; +import org.apache.cloudstack.api.command.user.project.CreateProjectCmd; +import org.apache.cloudstack.api.command.user.project.DeleteProjectCmd; +import org.apache.cloudstack.api.command.user.project.DeleteProjectInvitationCmd; +import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd; +import org.apache.cloudstack.api.command.user.project.ListProjectsCmd; +import org.apache.cloudstack.api.command.user.project.SuspendProjectCmd; +import org.apache.cloudstack.api.command.user.project.UpdateProjectCmd; +import org.apache.cloudstack.api.command.user.project.UpdateProjectInvitationCmd; +import org.apache.cloudstack.api.command.user.region.ListRegionsCmd; +import org.apache.cloudstack.api.command.user.region.ha.gslb.AssignToGlobalLoadBalancerRuleCmd; +import org.apache.cloudstack.api.command.user.region.ha.gslb.CreateGlobalLoadBalancerRuleCmd; +import org.apache.cloudstack.api.command.user.region.ha.gslb.DeleteGlobalLoadBalancerRuleCmd; +import org.apache.cloudstack.api.command.user.region.ha.gslb.ListGlobalLoadBalancerRuleCmd; +import org.apache.cloudstack.api.command.user.region.ha.gslb.RemoveFromGlobalLoadBalancerRuleCmd; +import org.apache.cloudstack.api.command.user.resource.GetCloudIdentifierCmd; +import org.apache.cloudstack.api.command.user.resource.ListHypervisorsCmd; +import org.apache.cloudstack.api.command.user.resource.ListResourceLimitsCmd; +import org.apache.cloudstack.api.command.user.resource.UpdateResourceCountCmd; +import org.apache.cloudstack.api.command.user.resource.UpdateResourceLimitCmd; +import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupEgressCmd; +import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupIngressCmd; +import org.apache.cloudstack.api.command.user.securitygroup.CreateSecurityGroupCmd; +import org.apache.cloudstack.api.command.user.securitygroup.DeleteSecurityGroupCmd; +import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd; +import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupEgressCmd; +import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupIngressCmd; +import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotCmd; +import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd; +import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotCmd; +import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd; +import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd; +import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd; +import org.apache.cloudstack.api.command.user.ssh.CreateSSHKeyPairCmd; +import org.apache.cloudstack.api.command.user.ssh.DeleteSSHKeyPairCmd; +import org.apache.cloudstack.api.command.user.ssh.ListSSHKeyPairsCmd; +import org.apache.cloudstack.api.command.user.ssh.RegisterSSHKeyPairCmd; +import org.apache.cloudstack.api.command.user.tag.CreateTagsCmd; +import org.apache.cloudstack.api.command.user.tag.DeleteTagsCmd; +import org.apache.cloudstack.api.command.user.tag.ListTagsCmd; +import org.apache.cloudstack.api.command.user.template.CopyTemplateCmd; +import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd; +import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd; +import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd; +import org.apache.cloudstack.api.command.user.template.ListTemplatePermissionsCmd; +import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd; +import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; +import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd; +import org.apache.cloudstack.api.command.user.template.UpdateTemplatePermissionsCmd; +import org.apache.cloudstack.api.command.user.vm.AddIpToVmNicCmd; +import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd; +import org.apache.cloudstack.api.command.user.vm.DeployVMCmd; +import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd; +import org.apache.cloudstack.api.command.user.vm.GetVMPasswordCmd; +import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; +import org.apache.cloudstack.api.command.user.vm.ListVMsCmd; +import org.apache.cloudstack.api.command.user.vm.RebootVMCmd; +import org.apache.cloudstack.api.command.user.vm.RemoveIpFromVmNicCmd; +import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd; +import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd; +import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd; +import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd; +import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd; +import org.apache.cloudstack.api.command.user.vm.StartVMCmd; +import org.apache.cloudstack.api.command.user.vm.StopVMCmd; +import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd; +import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd; +import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd; +import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd; +import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd; +import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd; +import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd; +import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd; +import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd; +import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd; +import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToVMSnapshotCmd; +import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.DeleteVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd; +import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; +import org.apache.cloudstack.api.command.user.vpc.CreateStaticRouteCmd; +import org.apache.cloudstack.api.command.user.vpc.CreateVPCCmd; +import org.apache.cloudstack.api.command.user.vpc.DeleteStaticRouteCmd; +import org.apache.cloudstack.api.command.user.vpc.DeleteVPCCmd; +import org.apache.cloudstack.api.command.user.vpc.ListPrivateGatewaysCmd; +import org.apache.cloudstack.api.command.user.vpc.ListStaticRoutesCmd; +import org.apache.cloudstack.api.command.user.vpc.ListVPCOfferingsCmd; +import org.apache.cloudstack.api.command.user.vpc.ListVPCsCmd; +import org.apache.cloudstack.api.command.user.vpc.RestartVPCCmd; +import org.apache.cloudstack.api.command.user.vpc.UpdateVPCCmd; +import org.apache.cloudstack.api.command.user.vpn.AddVpnUserCmd; +import org.apache.cloudstack.api.command.user.vpn.CreateRemoteAccessVpnCmd; +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.DeleteRemoteAccessVpnCmd; +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.ListRemoteAccessVpnsCmd; +import org.apache.cloudstack.api.command.user.vpn.ListVpnConnectionsCmd; +import org.apache.cloudstack.api.command.user.vpn.ListVpnCustomerGatewaysCmd; +import org.apache.cloudstack.api.command.user.vpn.ListVpnGatewaysCmd; +import org.apache.cloudstack.api.command.user.vpn.ListVpnUsersCmd; +import org.apache.cloudstack.api.command.user.vpn.RemoveVpnUserCmd; +import org.apache.cloudstack.api.command.user.vpn.ResetVpnConnectionCmd; +import org.apache.cloudstack.api.command.user.vpn.UpdateVpnCustomerGatewayCmd; +import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; +import org.apache.cloudstack.api.response.ExtractResponse; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; + import com.cloud.agent.AgentManager; import com.cloud.agent.api.GetVncPortAnswer; import com.cloud.agent.api.GetVncPortCommand; @@ -103,28 +421,53 @@ import com.cloud.alert.AlertManager; import com.cloud.alert.AlertVO; import com.cloud.alert.dao.AlertDao; import com.cloud.api.ApiDBUtils; -import com.cloud.async.*; +import com.cloud.async.AsyncJobExecutor; +import com.cloud.async.AsyncJobManager; +import com.cloud.async.AsyncJobResult; +import com.cloud.async.AsyncJobVO; +import com.cloud.async.BaseAsyncJobExecutor; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityVO; import com.cloud.capacity.dao.CapacityDao; import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity; import com.cloud.cluster.ClusterManager; +import com.cloud.configuration.Config; +import com.cloud.configuration.Configuration; +import com.cloud.configuration.ConfigurationManager; +import com.cloud.configuration.ConfigurationVO; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.consoleproxy.ConsoleProxyManagementState; import com.cloud.consoleproxy.ConsoleProxyManager; -import com.cloud.dc.*; +import com.cloud.dc.AccountVlanMapVO; +import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; +import com.cloud.dc.Pod; +import com.cloud.dc.PodVlanMapVO; +import com.cloud.dc.Vlan; import com.cloud.dc.Vlan.VlanType; -import com.cloud.dc.dao.*; +import com.cloud.dc.VlanVO; +import com.cloud.dc.dao.AccountVlanMapDao; +import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.dc.dao.PodVlanMapDao; +import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DataCenterDeployment; -import com.cloud.deploy.DeploymentPlanner; import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; +import com.cloud.event.ActionEventUtils; import com.cloud.event.EventTypes; import com.cloud.event.EventVO; import com.cloud.event.dao.EventDao; -import com.cloud.exception.*; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.OperationTimedoutException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.StorageUnavailableException; import com.cloud.ha.HighAvailabilityManager; import com.cloud.host.DetailVO; import com.cloud.host.Host; @@ -141,7 +484,12 @@ import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.info.ConsoleProxyInfo; import com.cloud.keystore.KeystoreManager; import com.cloud.network.IpAddress; -import com.cloud.network.dao.*; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.LoadBalancerDao; +import com.cloud.network.dao.LoadBalancerVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; import com.cloud.org.Cluster; import com.cloud.org.Grouping.AllocationState; import com.cloud.projects.Project; @@ -150,11 +498,29 @@ import com.cloud.projects.ProjectManager; import com.cloud.resource.ResourceManager; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.server.auth.UserAuthenticator; -import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.*; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.GuestOS; +import com.cloud.storage.GuestOSCategoryVO; +import com.cloud.storage.GuestOSVO; +import com.cloud.storage.GuestOsCategory; +import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePool; +import com.cloud.storage.Upload; import com.cloud.storage.Upload.Mode; +import com.cloud.storage.UploadVO; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Volume; +import com.cloud.storage.VolumeManager; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.DiskOfferingDao; +import com.cloud.storage.dao.GuestOSCategoryDao; +import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.UploadDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; @@ -164,7 +530,13 @@ import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.TemplateManager; import com.cloud.template.VirtualMachineTemplate.TemplateFilter; -import com.cloud.user.*; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.SSHKeyPair; +import com.cloud.user.SSHKeyPairVO; +import com.cloud.user.User; +import com.cloud.user.UserContext; +import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.SSHKeyPairDao; import com.cloud.user.dao.UserDao; @@ -177,91 +549,39 @@ import com.cloud.utils.component.ComponentLifecycle; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.crypt.DBEncryptionUtil; -import com.cloud.utils.db.*; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.GlobalLock; +import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.JoinBuilder.JoinType; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.MacAddress; import com.cloud.utils.net.NetUtils; import com.cloud.utils.ssh.SSHKeysHelper; -import com.cloud.vm.*; +import com.cloud.vm.ConsoleProxyVO; +import com.cloud.vm.DiskProfile; +import com.cloud.vm.InstanceGroupVO; +import com.cloud.vm.SecondaryStorageVmVO; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.dao.*; +import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.VirtualMachineProfileImpl; +import com.cloud.vm.dao.ConsoleProxyDao; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.InstanceGroupDao; +import com.cloud.vm.dao.SecondaryStorageVmDao; +import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.dao.VMInstanceDao; + import edu.emory.mathcs.backport.java.util.Arrays; import edu.emory.mathcs.backport.java.util.Collections; -import org.apache.cloudstack.acl.ControlledEntity; -import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd; -import org.apache.cloudstack.api.command.admin.autoscale.DeleteCounterCmd; -import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd; -import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd; -import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd; -import org.apache.cloudstack.api.command.admin.cluster.UpdateClusterCmd; -import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd; -import org.apache.cloudstack.api.command.admin.config.ListHypervisorCapabilitiesCmd; -import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd; -import org.apache.cloudstack.api.command.admin.config.UpdateHypervisorCapabilitiesCmd; -import org.apache.cloudstack.api.command.admin.ldap.LDAPConfigCmd; -import org.apache.cloudstack.api.command.admin.ldap.LDAPRemoveCmd; -import org.apache.cloudstack.api.command.admin.pod.CreatePodCmd; -import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd; -import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd; -import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd; -import org.apache.cloudstack.api.command.admin.region.AddRegionCmd; -import org.apache.cloudstack.api.command.admin.region.RemoveRegionCmd; -import org.apache.cloudstack.api.command.admin.region.UpdateRegionCmd; -import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd; -import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd; -import org.apache.cloudstack.api.command.admin.template.PrepareTemplateCmd; -import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd; -import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd; -import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd; -import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd; -import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd; -import org.apache.cloudstack.api.command.admin.vm.MigrateVirtualMachineWithVolumeCmd; -import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd; -import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd; -import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd; -import org.apache.cloudstack.api.command.admin.zone.MarkDefaultZoneForAccountCmd; -import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd; -import org.apache.cloudstack.api.command.user.account.AddAccountToProjectCmd; -import org.apache.cloudstack.api.command.user.account.DeleteAccountFromProjectCmd; -import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; -import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd; -import org.apache.cloudstack.api.command.user.address.AssociateIPAddrCmd; -import org.apache.cloudstack.api.command.user.address.DisassociateIPAddrCmd; -import org.apache.cloudstack.api.command.user.address.ListPublicIpAddressesCmd; -import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd; -import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd; -import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd; -import org.apache.cloudstack.api.command.user.event.ListEventTypesCmd; -import org.apache.cloudstack.api.command.user.event.ListEventsCmd; -import org.apache.cloudstack.api.command.user.guest.ListGuestOsCategoriesCmd; -import org.apache.cloudstack.api.command.user.guest.ListGuestOsCmd; -import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd; -import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd; -import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd; -import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd; -import org.apache.cloudstack.api.command.user.region.ListRegionsCmd; -import org.apache.cloudstack.api.command.user.region.ha.gslb.*; -import org.apache.cloudstack.api.command.user.ssh.CreateSSHKeyPairCmd; -import org.apache.cloudstack.api.command.user.ssh.DeleteSSHKeyPairCmd; -import org.apache.cloudstack.api.command.user.ssh.ListSSHKeyPairsCmd; -import org.apache.cloudstack.api.command.user.ssh.RegisterSSHKeyPairCmd; -import org.apache.cloudstack.api.command.user.tag.CreateTagsCmd; -import org.apache.cloudstack.api.command.user.tag.DeleteTagsCmd; -import org.apache.cloudstack.api.command.user.tag.ListTagsCmd; -import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd; -import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd; -import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd; -import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd; -import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd; -import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd; -import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd; -import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToVMSnapshotCmd; -import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; + public class ManagementServerImpl extends ManagerBase implements ManagementServer { public static final Logger s_logger = Logger.getLogger(ManagementServerImpl.class.getName()); @@ -2542,11 +2862,21 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(AssignToGlobalLoadBalancerRuleCmd.class); cmdList.add(RemoveFromGlobalLoadBalancerRuleCmd.class); cmdList.add(ListStorageProvidersCmd.class); + cmdList.add(CreateApplicationLoadBalancerCmd.class); + cmdList.add(ListApplicationLoadBalancersCmd.class); + cmdList.add(DeleteApplicationLoadBalancerCmd.class); + cmdList.add(ConfigureInternalLoadBalancerElementCmd.class); + cmdList.add(CreateInternalLoadBalancerElementCmd.class); + cmdList.add(ListInternalLoadBalancerElementsCmd.class); cmdList.add(CreateAffinityGroupCmd.class); cmdList.add(DeleteAffinityGroupCmd.class); cmdList.add(ListAffinityGroupsCmd.class); cmdList.add(UpdateVMAffinityGroupCmd.class); cmdList.add(ListAffinityGroupTypesCmd.class); + cmdList.add(StopInternalLBVMCmd.class); + cmdList.add(StartInternalLBVMCmd.class); + cmdList.add(ListInternalLBVMsCmd.class); + cmdList.add(ListNetworkIsolationMethodsCmd.class); cmdList.add(ListNetworkIsolationMethodsCmd.class); return cmdList; diff --git a/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java b/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java new file mode 100644 index 00000000000..ec0be8c9d96 --- /dev/null +++ b/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java @@ -0,0 +1,524 @@ +// 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.network.lb; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.api.command.user.loadbalancer.ListApplicationLoadBalancersCmd; +import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO; +import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.event.ActionEvent; +import com.cloud.event.EventTypes; +import com.cloud.event.UsageEventUtils; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.UnsupportedServiceException; +import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.dao.FirewallRulesDao; +import com.cloud.network.lb.LoadBalancingRule; +import com.cloud.network.lb.LoadBalancingRule.LbDestination; +import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy; +import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; +import com.cloud.network.lb.LoadBalancingRulesManager; +import com.cloud.network.rules.FirewallRule.State; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; +import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.tags.ResourceTagVO; +import com.cloud.tags.dao.ResourceTagDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.UserContext; +import com.cloud.utils.Pair; +import com.cloud.utils.Ternary; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.Ip; +import com.cloud.utils.net.NetUtils; + +@Component +@Local(value = { ApplicationLoadBalancerService.class }) +public class ApplicationLoadBalancerManagerImpl extends ManagerBase implements ApplicationLoadBalancerService { + private static final Logger s_logger = Logger.getLogger(ApplicationLoadBalancerManagerImpl.class); + + @Inject NetworkModel _networkModel; + @Inject ApplicationLoadBalancerRuleDao _lbDao; + @Inject AccountManager _accountMgr; + @Inject LoadBalancingRulesManager _lbMgr; + @Inject FirewallRulesDao _firewallDao; + @Inject ResourceTagDao _resourceTagDao; + @Inject NetworkManager _ntwkMgr; + + + @Override + @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_CREATE, eventDescription = "creating load balancer") + public ApplicationLoadBalancerRule createApplicationLoadBalancer(String name, String description, Scheme scheme, long sourceIpNetworkId, String sourceIp, + int sourcePort, int instancePort, String algorithm, long networkId, long lbOwnerId) throws InsufficientAddressCapacityException, + NetworkRuleConflictException, InsufficientVirtualNetworkCapcityException { + + //Validate LB rule guest network + Network guestNtwk = _networkModel.getNetwork(networkId); + if (guestNtwk == null || guestNtwk.getTrafficType() != TrafficType.Guest) { + throw new InvalidParameterValueException("Can't find guest network by id"); + } + + Account caller = UserContext.current().getCaller(); + _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, guestNtwk); + + Network sourceIpNtwk = _networkModel.getNetwork(sourceIpNetworkId); + if (sourceIpNtwk == null) { + throw new InvalidParameterValueException("Can't find source ip network by id"); + } + + Account lbOwner = _accountMgr.getAccount(lbOwnerId); + if (lbOwner == null) { + throw new InvalidParameterValueException("Can't find the lb owner account"); + } + + return createApplicationLoadBalancer(name, description, scheme, sourceIpNtwk, sourceIp, sourcePort, instancePort, algorithm, lbOwner, guestNtwk); + } + + + protected ApplicationLoadBalancerRule createApplicationLoadBalancer(String name, String description, Scheme scheme, Network sourceIpNtwk, String sourceIp, int sourcePort, int instancePort, String algorithm, + Account lbOwner, Network guestNtwk) throws NetworkRuleConflictException, InsufficientVirtualNetworkCapcityException { + + //Only Internal scheme is supported in this release + if (scheme != Scheme.Internal) { + throw new UnsupportedServiceException("Only scheme of type " + Scheme.Internal + " is supported"); + } + + //1) Validate LB rule's parameters + validateLbRule(sourcePort, instancePort, algorithm, guestNtwk, scheme); + + //2) Validate source network + validateSourceIpNtwkForLbRule(sourceIpNtwk, scheme); + + //3) Get source ip address + Ip sourceIpAddr = getSourceIp(scheme, sourceIpNtwk, sourceIp); + + ApplicationLoadBalancerRuleVO newRule = new ApplicationLoadBalancerRuleVO(name, description, sourcePort, instancePort, algorithm, guestNtwk.getId(), + lbOwner.getId(), lbOwner.getDomainId(), sourceIpAddr, sourceIpNtwk.getId(), scheme); + + //4) Validate Load Balancing rule on the providers + LoadBalancingRule loadBalancing = new LoadBalancingRule(newRule, new ArrayList(), + new ArrayList(), new ArrayList(), sourceIpAddr); + if (!_lbMgr.validateLbRule(loadBalancing)) { + throw new InvalidParameterValueException("LB service provider cannot support this rule"); + } + + //5) Persist Load Balancer rule + return persistLbRule(newRule); + } + + + @DB + protected ApplicationLoadBalancerRule persistLbRule(ApplicationLoadBalancerRuleVO newRule) throws NetworkRuleConflictException { + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + //1) Persist the rule + newRule = _lbDao.persist(newRule); + boolean success = true; + + try { + //2) Detect conflicts + detectLbRulesConflicts(newRule); + if (!_firewallDao.setStateToAdd(newRule)) { + throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + } + s_logger.debug("Load balancer " + newRule.getId() + " for Ip address " + newRule.getSourceIp().addr() + ", source port " + + newRule.getSourcePortStart() + ", instance port " + newRule.getDefaultPortStart() + " is added successfully."); + UserContext.current().setEventDetails("Load balancer Id: " + newRule.getId()); + 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()); + txn.commit(); + + return newRule; + } catch (Exception e) { + success = false; + if (e instanceof NetworkRuleConflictException) { + throw (NetworkRuleConflictException) e; + } + throw new CloudRuntimeException("Unable to add lb rule for ip address " + newRule.getSourceIpAddressId(), e); + } finally { + if (!success && newRule != null) { + _lbMgr.removeLBRule(newRule); + } + } + } + + /** + * Validates Lb rule parameters + * @param sourcePort + * @param instancePort + * @param algorithm + * @param network + * @param scheme TODO + * @param networkId + */ + protected void validateLbRule(int sourcePort, int instancePort, String algorithm, Network network, Scheme scheme) { + //1) verify that lb service is supported by the network + if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb)) { + InvalidParameterValueException ex = new InvalidParameterValueException( + "LB service is not supported in specified network id"); + ex.addProxyObject(network, network.getId(), "networkId"); + throw ex; + } + + //2) verify that lb service is supported by the network + _lbMgr.isLbServiceSupportedInNetwork(network.getId(), scheme); + + Map caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Lb); + String supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase(); + if (!supportedProtocols.contains(NetUtils.TCP_PROTO.toLowerCase())) { + throw new InvalidParameterValueException("Protocol " + NetUtils.TCP_PROTO.toLowerCase() + " is not supported in zone " + network.getDataCenterId()); + } + + //3) Validate rule parameters + if (!NetUtils.isValidPort(instancePort)) { + throw new InvalidParameterValueException("Invalid value for instance port: " + instancePort); + } + + if (!NetUtils.isValidPort(sourcePort)) { + throw new InvalidParameterValueException("Invalid value for source port: " + sourcePort); + } + + if ((algorithm == null) || !NetUtils.isValidAlgorithm(algorithm)) { + throw new InvalidParameterValueException("Invalid algorithm: " + algorithm); + } + } + + + /** + * Gets source ip address based on the LB rule scheme/source IP network/requested IP address + * @param scheme + * @param sourceIpNtwk + * @param requestedIp + * @return + * @throws InsufficientVirtualNetworkCapcityException + */ + protected Ip getSourceIp(Scheme scheme, Network sourceIpNtwk, String requestedIp) throws InsufficientVirtualNetworkCapcityException { + + if (requestedIp != null) { + if (_lbDao.countBySourceIp(new Ip(requestedIp), sourceIpNtwk.getId()) > 0) { + s_logger.debug("IP address " + requestedIp + " is already used by existing LB rule, returning it"); + return new Ip(requestedIp); + } + + validateRequestedSourceIpForLbRule(sourceIpNtwk, new Ip(requestedIp), scheme); + } + + requestedIp = allocateSourceIpForLbRule(scheme, sourceIpNtwk, requestedIp); + + if (requestedIp == null) { + throw new InsufficientVirtualNetworkCapcityException("Unable to acquire IP address for network " + sourceIpNtwk, Network.class, sourceIpNtwk.getId()); + } + return new Ip(requestedIp); + } + + + /** + * Allocates new Source IP address for the Load Balancer rule based on LB rule scheme/sourceNetwork + * @param scheme + * @param sourceIpNtwk + * @param requestedIp TODO + * @param sourceIp + * @return + */ + protected String allocateSourceIpForLbRule(Scheme scheme, Network sourceIpNtwk, String requestedIp) { + String sourceIp = null; + if (scheme != Scheme.Internal) { + throw new InvalidParameterValueException("Only scheme " + Scheme.Internal + " is supported"); + } else { + sourceIp = allocateSourceIpForInternalLbRule(sourceIpNtwk, requestedIp); + } + return sourceIp; + } + + + /** + * Allocates sourceIp for the Internal LB rule + * @param sourceIpNtwk + * @param requestedIp TODO + * @return + */ + protected String allocateSourceIpForInternalLbRule(Network sourceIpNtwk, String requestedIp) { + return _ntwkMgr.acquireGuestIpAddress(sourceIpNtwk, requestedIp); + } + + + /** + * Validates requested source ip address of the LB rule based on Lb rule scheme/sourceNetwork + * @param sourceIpNtwk + * @param requestedSourceIp + * @param scheme + */ + void validateRequestedSourceIpForLbRule(Network sourceIpNtwk, Ip requestedSourceIp, Scheme scheme) { + //only Internal scheme is supported in this release + if (scheme != Scheme.Internal) { + throw new UnsupportedServiceException("Only scheme of type " + Scheme.Internal + " is supported"); + } else { + //validate guest source ip + validateRequestedSourceIpForInternalLbRule(sourceIpNtwk, requestedSourceIp); + } + } + + + /** + * Validates requested source IP address of Internal Lb rule against sourceNetworkId + * @param sourceIpNtwk + * @param requestedSourceIp + */ + protected void validateRequestedSourceIpForInternalLbRule(Network sourceIpNtwk, Ip requestedSourceIp) { + //Check if the IP is within the network cidr + Pair cidr = NetUtils.getCidr(sourceIpNtwk.getCidr()); + if (!NetUtils.getCidrSubNet(requestedSourceIp.addr(), cidr.second()).equalsIgnoreCase(NetUtils.getCidrSubNet(cidr.first(), cidr.second()))) { + throw new InvalidParameterValueException("The requested IP is not in the network's CIDR subnet."); + } + } + + + /** + * Validates source IP network for the LB rule + * @param sourceNtwk + * @param scheme + * @return + */ + protected Network validateSourceIpNtwkForLbRule(Network sourceNtwk, Scheme scheme) { + //only Internal scheme is supported in this release + if (scheme != Scheme.Internal) { + throw new UnsupportedServiceException("Only scheme of type " + Scheme.Internal + " is supported"); + } else { + //validate source ip network + return validateSourceIpNtwkForInternalLbRule(sourceNtwk); + } + + } + + /** + * Validates source IP network for the Internal LB rule + * @param sourceIpNtwk + * @return + */ + protected Network validateSourceIpNtwkForInternalLbRule(Network sourceIpNtwk) { + if (sourceIpNtwk.getTrafficType() != TrafficType.Guest) { + throw new InvalidParameterValueException("Only traffic type " + TrafficType.Guest + " is supported"); + } + + //Can't create the LB rule if the network's cidr is NULL + String ntwkCidr = sourceIpNtwk.getCidr(); + if (ntwkCidr == null) { + throw new InvalidParameterValueException("Can't create the application load balancer rule for the network having NULL cidr"); + } + + //check if the requested ip address is within the cidr + return sourceIpNtwk; + } + + + @Override + public boolean deleteApplicationLoadBalancer(long id) { + return _lbMgr.deleteLoadBalancerRule(id, true); + } + + @Override + public Pair, Integer> listApplicationLoadBalancers(ListApplicationLoadBalancersCmd cmd) { + Long id = cmd.getId(); + String name = cmd.getLoadBalancerRuleName(); + String ip = cmd.getSourceIp(); + Long ipNtwkId = cmd.getSourceIpNetworkId(); + String keyword = cmd.getKeyword(); + Scheme scheme = cmd.getScheme(); + Long networkId = cmd.getNetworkId(); + + Map tags = cmd.getTags(); + + Account caller = UserContext.current().getCaller(); + List permittedAccounts = new ArrayList(); + + Ternary domainIdRecursiveListProject = new Ternary( + cmd.getDomainId(), cmd.isRecursive(), null); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, + domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); + Boolean isRecursive = domainIdRecursiveListProject.second(); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + + Filter searchFilter = new Filter(ApplicationLoadBalancerRuleVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchBuilder sb = _lbDao.createSearchBuilder(); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.and("sourceIpAddress", sb.entity().getSourceIp(), SearchCriteria.Op.EQ); + sb.and("sourceIpAddressNetworkId", sb.entity().getSourceIpNetworkId(), SearchCriteria.Op.EQ); + sb.and("scheme", sb.entity().getScheme(), SearchCriteria.Op.EQ); + sb.and("networkId", sb.entity().getNetworkId(), SearchCriteria.Op.EQ); + + //list only load balancers having not null sourceIp/sourceIpNtwkId + sb.and("sourceIpAddress", sb.entity().getSourceIp(), SearchCriteria.Op.NNULL); + sb.and("sourceIpAddressNetworkId", sb.entity().getSourceIpNetworkId(), SearchCriteria.Op.NNULL); + + if (tags != null && !tags.isEmpty()) { + SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); + for (int count = 0; count < tags.size(); count++) { + tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); + tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); + tagSearch.cp(); + } + tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.groupBy(sb.entity().getId()); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), + JoinBuilder.JoinType.INNER); + } + + SearchCriteria sc = sb.create(); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + if (keyword != null) { + SearchCriteria ssc = _lbDao.createSearchCriteria(); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (name != null) { + sc.setParameters("name", name); + } + + if (id != null) { + sc.setParameters("id", id); + } + + if (ip != null) { + sc.setParameters("sourceIpAddress", ip); + } + + if (ipNtwkId != null) { + sc.setParameters("sourceIpAddressNetworkId", ipNtwkId); + } + + if (scheme != null) { + sc.setParameters("scheme", scheme); + } + + if (networkId != null) { + sc.setParameters("networkId", networkId); + } + + if (tags != null && !tags.isEmpty()) { + int count = 0; + sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.LoadBalancer.toString()); + for (String key : tags.keySet()) { + sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key); + sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key)); + count++; + } + } + + Pair, Integer> result = _lbDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); + } + + @Override + public ApplicationLoadBalancerRule getApplicationLoadBalancer(long ruleId) { + ApplicationLoadBalancerRule lbRule = _lbDao.findById(ruleId); + if (lbRule == null) { + throw new InvalidParameterValueException("Can't find the load balancer by id"); + } + return lbRule; + } + + + /** + * Detects lb rule conflicts against other rules + * @param newLbRule + * @throws NetworkRuleConflictException + */ + protected void detectLbRulesConflicts(ApplicationLoadBalancerRule newLbRule) throws NetworkRuleConflictException { + if (newLbRule.getScheme() != Scheme.Internal) { + throw new UnsupportedServiceException("Only scheme of type " + Scheme.Internal + " is supported"); + } else { + detectInternalLbRulesConflict(newLbRule); + } + } + + + /** + * Detects Internal Lb Rules conflicts + * @param newLbRule + * @throws NetworkRuleConflictException + */ + protected void detectInternalLbRulesConflict(ApplicationLoadBalancerRule newLbRule) throws NetworkRuleConflictException { + List lbRules = _lbDao.listBySourceIpAndNotRevoked(newLbRule.getSourceIp(), newLbRule.getSourceIpNetworkId()); + + for (ApplicationLoadBalancerRuleVO lbRule : lbRules) { + if (lbRule.getId() == newLbRule.getId()) { + continue; // Skips my own rule. + } + + if (lbRule.getNetworkId() != newLbRule.getNetworkId() && lbRule.getState() != State.Revoke) { + throw new NetworkRuleConflictException("New rule is for a different network than what's specified in rule " + + lbRule.getXid()); + } + + if ((lbRule.getSourcePortStart().intValue() <= newLbRule.getSourcePortStart().intValue() + && lbRule.getSourcePortEnd().intValue() >= newLbRule.getSourcePortStart().intValue()) + || (lbRule.getSourcePortStart().intValue() <= newLbRule.getSourcePortEnd().intValue() + && lbRule.getSourcePortEnd().intValue() >= newLbRule.getSourcePortEnd().intValue()) + || (newLbRule.getSourcePortStart().intValue() <= lbRule.getSourcePortStart().intValue() + && newLbRule.getSourcePortEnd().intValue() >= lbRule.getSourcePortStart().intValue()) + || (newLbRule.getSourcePortStart().intValue() <= lbRule.getSourcePortEnd().intValue() + && newLbRule.getSourcePortEnd().intValue() >= lbRule.getSourcePortEnd().intValue())) { + + + throw new NetworkRuleConflictException("The range specified, " + newLbRule.getSourcePortStart() + "-" + newLbRule.getSourcePortEnd() + ", conflicts with rule " + lbRule.getId() + + " which has " + lbRule.getSourcePortStart() + "-" + lbRule.getSourcePortEnd()); + } + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("No network rule conflicts detected for " + newLbRule + " against " + (lbRules.size() - 1) + " existing rules"); + } + } +} diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index 2f717c8c156..eb5fc253784 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -16,13 +16,33 @@ // under the License. package com.cloud.network; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.acl.ControlledEntity.ACLType; +import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd; +import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; +import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; +import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; +import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; +import org.springframework.stereotype.Component; + import com.cloud.dc.DataCenter; import com.cloud.dc.Pod; import com.cloud.dc.Vlan.VlanType; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; -import com.cloud.exception.*; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.Networks.TrafficType; @@ -37,6 +57,7 @@ import com.cloud.network.guru.NetworkGuru; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRule.State; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.rules.StaticNat; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; @@ -46,6 +67,7 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.ManagerBase; import com.cloud.vm.*; import com.cloud.vm.VirtualMachine.Type; +import com.cloud.vm.VirtualMachineProfile; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; @@ -62,6 +84,7 @@ import java.util.List; import java.util.Map; import java.util.Set; + @Component @Local(value = { NetworkManager.class, NetworkService.class }) public class MockNetworkManagerImpl extends ManagerBase implements NetworkManager, NetworkService { @@ -820,7 +843,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage } @Override - public LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network) { + public LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network, Scheme lbScheme) { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/network/MockNetworkModelImpl.java b/server/test/com/cloud/network/MockNetworkModelImpl.java index 7df45a01715..c3a0d6c5ae9 100644 --- a/server/test/com/cloud/network/MockNetworkModelImpl.java +++ b/server/test/com/cloud/network/MockNetworkModelImpl.java @@ -40,6 +40,7 @@ import com.cloud.network.dao.NetworkVO; import com.cloud.network.element.NetworkElement; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.offering.NetworkOffering; +import com.cloud.offering.NetworkOffering.Detail; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.user.Account; import com.cloud.utils.component.ManagerBase; @@ -853,6 +854,22 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { } @Override + public IpAddress getPublicIpAddress(String ipAddress, long zoneId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getUsedIpsInNetwork(Network network) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Map getNtwkOffDetails(long offId) { + return null; + } + public IsolationType[] listNetworkIsolationMethods() { // TODO Auto-generated method stub return null; diff --git a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java index 83b19247093..90587985f74 100755 --- a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java +++ b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java @@ -501,7 +501,7 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu @Override public NetworkOfferingVO createNetworkOffering(String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, Integer networkRate, Map> serviceProviderMap, boolean isDefault, GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, - Map> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent) { + Map> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent, Map details) { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index f884ba1d767..84ae818f489 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -16,17 +16,51 @@ // under the License. package com.cloud.vpc; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.acl.ControlledEntity.ACLType; +import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; +import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; +import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd; +import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; +import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; +import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; +import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + import com.cloud.dc.DataCenter; import com.cloud.dc.Pod; import com.cloud.dc.Vlan.VlanType; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; -import com.cloud.exception.*; -import com.cloud.network.*; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.GuestVlan; +import com.cloud.network.IpAddress; +import com.cloud.network.Network; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkProfile; +import com.cloud.network.NetworkRuleApplier; +import com.cloud.network.NetworkService; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PhysicalNetworkTrafficType; +import com.cloud.network.PublicIpAddress; import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.AccountGuestVlanMapVO; import com.cloud.network.dao.IPAddressVO; @@ -40,6 +74,7 @@ import com.cloud.network.guru.NetworkGuru; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRule.State; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.rules.StaticNat; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; @@ -48,8 +83,15 @@ import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.utils.Pair; import com.cloud.utils.component.ManagerBase; -import com.cloud.vm.*; +import com.cloud.vm.Nic; +import com.cloud.vm.NicProfile; +import com.cloud.vm.NicSecondaryIp; +import com.cloud.vm.NicVO; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.Type; +import com.cloud.vm.VirtualMachineProfile; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; @@ -61,12 +103,6 @@ import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import javax.ejb.Local; -import javax.inject.Inject; -import javax.naming.ConfigurationException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; @Component @Local(value = { NetworkManager.class, NetworkService.class }) @@ -1301,7 +1337,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage } @Override - public LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network) { + public LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network, Scheme lbScheme) { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/vpc/MockNetworkModelImpl.java b/server/test/com/cloud/vpc/MockNetworkModelImpl.java index c9d043ad0d1..d9e33b75616 100644 --- a/server/test/com/cloud/vpc/MockNetworkModelImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkModelImpl.java @@ -47,6 +47,7 @@ import com.cloud.network.dao.NetworkVO; import com.cloud.network.element.NetworkElement; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.offering.NetworkOffering; +import com.cloud.offering.NetworkOffering.Detail; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; import com.cloud.user.Account; @@ -865,6 +866,22 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { } @Override + public IpAddress getPublicIpAddress(String ipAddress, long zoneId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getUsedIpsInNetwork(Network network) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Map getNtwkOffDetails(long offId) { + return null; + } + public IsolationType[] listNetworkIsolationMethods() { // TODO Auto-generated method stub return null; diff --git a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java index ef5478bb1f8..9010f1f5acb 100644 --- a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java +++ b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java @@ -36,6 +36,7 @@ import com.cloud.network.RemoteAccessVpn; import com.cloud.network.Site2SiteVpnConnection; import com.cloud.network.VpcVirtualNetworkApplianceService; import com.cloud.network.VpnUser; +import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VpcVirtualNetworkApplianceManager; import com.cloud.network.rules.FirewallRule; @@ -46,7 +47,6 @@ import com.cloud.network.vpc.Vpc; import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.uservm.UserVm; -import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; @@ -402,4 +402,16 @@ VpcVirtualNetworkApplianceService { return null; } + @Override + public boolean applyLoadBalancingRules(Network network, List rules, List routers) throws ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + + @Override + public VirtualRouter findRouter(long routerId) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/server/test/com/cloud/vpc/dao/MockNetworkOfferingDaoImpl.java b/server/test/com/cloud/vpc/dao/MockNetworkOfferingDaoImpl.java index dbf14113de4..a8208dd7d9c 100644 --- a/server/test/com/cloud/vpc/dao/MockNetworkOfferingDaoImpl.java +++ b/server/test/com/cloud/vpc/dao/MockNetworkOfferingDaoImpl.java @@ -101,28 +101,28 @@ public class MockNetworkOfferingDaoImpl extends NetworkOfferingDaoImpl implement if (id.longValue() == 1) { //network offering valid for vpc vo = new NetworkOfferingVO("vpc", "vpc", TrafficType.Guest, false, true, null, null, false, - Availability.Optional, null, Network.GuestType.Isolated, false, false, false); + Availability.Optional, null, Network.GuestType.Isolated, false, false, false, false, false); } else if (id.longValue() == 2) { //invalid offering - source nat is not included vo = new NetworkOfferingVO("vpc", "vpc", TrafficType.Guest, false, true, null, null, false, - Availability.Optional, null, Network.GuestType.Isolated, false, false, false); + Availability.Optional, null, Network.GuestType.Isolated, false, false, false, false, false); } else if (id.longValue() == 3) { //network offering invalid for vpc (conserve mode off) vo = new NetworkOfferingVO("non vpc", "non vpc", TrafficType.Guest, false, true, null, null, false, - Availability.Optional, null, Network.GuestType.Isolated, true, false, false); + Availability.Optional, null, Network.GuestType.Isolated, true, false, false, false, false); } else if (id.longValue() == 4) { //network offering invalid for vpc (Shared) vo = new NetworkOfferingVO("non vpc", "non vpc", TrafficType.Guest, false, true, null, null, false, - Availability.Optional, null, Network.GuestType.Shared, false, false, false); + Availability.Optional, null, Network.GuestType.Shared, false, false, false, false, false); } else if (id.longValue() == 5) { //network offering invalid for vpc (has redundant router) vo = new NetworkOfferingVO("vpc", "vpc", TrafficType.Guest, false, true, null, null, false, - Availability.Optional, null, Network.GuestType.Isolated, false, false, false); + Availability.Optional, null, Network.GuestType.Isolated, false, false, false, false, false); vo.setRedundantRouter(true); } else if (id.longValue() == 6) { //network offering invalid for vpc (has lb service) vo = new NetworkOfferingVO("vpc", "vpc", TrafficType.Guest, false, true, null, null, false, - Availability.Optional, null, Network.GuestType.Isolated, false, false, false); + Availability.Optional, null, Network.GuestType.Isolated, false, false, false, false, false); } if (vo != null) { diff --git a/server/test/com/cloud/vpc/dao/MockNetworkServiceMapDaoImpl.java b/server/test/com/cloud/vpc/dao/MockNetworkServiceMapDaoImpl.java index 002b61dcbc4..103f04ea8b9 100644 --- a/server/test/com/cloud/vpc/dao/MockNetworkServiceMapDaoImpl.java +++ b/server/test/com/cloud/vpc/dao/MockNetworkServiceMapDaoImpl.java @@ -95,4 +95,10 @@ public class MockNetworkServiceMapDaoImpl extends GenericDaoBase getProvidersForServiceInNetwork(long networkId, Service service) { + // TODO Auto-generated method stub + return null; + } } diff --git a/server/test/org/apache/cloudstack/lb/ApplicationLoadBalancerTest.java b/server/test/org/apache/cloudstack/lb/ApplicationLoadBalancerTest.java new file mode 100644 index 00000000000..461cbbdf012 --- /dev/null +++ b/server/test/org/apache/cloudstack/lb/ApplicationLoadBalancerTest.java @@ -0,0 +1,292 @@ +// 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.lb; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; + +import junit.framework.TestCase; + +import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; +import org.apache.cloudstack.network.lb.ApplicationLoadBalancerManagerImpl; +import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.cloud.event.dao.UsageEventDao; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.UnsupportedServiceException; +import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.dao.FirewallRulesDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.lb.LoadBalancingRule; +import com.cloud.network.lb.LoadBalancingRulesManager; +import com.cloud.network.rules.FirewallRuleVO; +import com.cloud.network.rules.LoadBalancerContainer.Scheme; +import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; +import com.cloud.user.UserContext; +import com.cloud.user.UserVO; +import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.Ip; +import com.cloud.utils.net.NetUtils; + +/** + * This class is responsible for unittesting the methods defined in ApplicationLoadBalancerService + * + */ + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations="classpath:/appLoadBalancer.xml") +public class ApplicationLoadBalancerTest extends TestCase{ + //The interface to test + @Inject ApplicationLoadBalancerManagerImpl _appLbSvc; + + //The interfaces below are mocked + @Inject ApplicationLoadBalancerRuleDao _lbDao; + @Inject LoadBalancingRulesManager _lbMgr; + @Inject NetworkModel _ntwkModel; + @Inject AccountManager _accountMgr; + @Inject FirewallRulesDao _firewallDao; + @Inject UsageEventDao _usageEventDao; + + + public static long existingLbId = 1L; + public static long nonExistingLbId = 2L; + + public static long validGuestNetworkId = 1L; + public static long invalidGuestNetworkId = 2L; + public static long validPublicNetworkId = 3L; + + public static long validAccountId = 1L; + public static long invalidAccountId = 2L; + + public String validRequestedIp = "10.1.1.1"; + + + + @Before + public void setUp() { + ComponentContext.initComponentsLifeCycle(); + //mockito for .getApplicationLoadBalancer tests + Mockito.when(_lbDao.findById(1L)).thenReturn(new ApplicationLoadBalancerRuleVO()); + Mockito.when(_lbDao.findById(2L)).thenReturn(null); + + //mockito for .deleteApplicationLoadBalancer tests + Mockito.when(_lbMgr.deleteLoadBalancerRule(existingLbId, true)).thenReturn(true); + Mockito.when(_lbMgr.deleteLoadBalancerRule(nonExistingLbId, true)).thenReturn(false); + + //mockito for .createApplicationLoadBalancer tests + NetworkVO guestNetwork = new NetworkVO(TrafficType.Guest, null, null, 1, + null, 1, 1L); + setId(guestNetwork, validGuestNetworkId); + guestNetwork.setCidr("10.1.1.1/24"); + + NetworkVO publicNetwork = new NetworkVO(TrafficType.Public, null, null, 1, + null, 1, 1L); + + Mockito.when(_ntwkModel.getNetwork(validGuestNetworkId)).thenReturn(guestNetwork); + Mockito.when(_ntwkModel.getNetwork(invalidGuestNetworkId)).thenReturn(null); + Mockito.when(_ntwkModel.getNetwork(validPublicNetworkId)).thenReturn(publicNetwork); + + Mockito.when(_accountMgr.getAccount(validAccountId)).thenReturn(new AccountVO()); + Mockito.when(_accountMgr.getAccount(invalidAccountId)).thenReturn(null); + Mockito.when(_ntwkModel.areServicesSupportedInNetwork(validGuestNetworkId, Service.Lb)).thenReturn(true); + Mockito.when(_ntwkModel.areServicesSupportedInNetwork(invalidGuestNetworkId, Service.Lb)).thenReturn(false); + + ApplicationLoadBalancerRuleVO lbRule = new ApplicationLoadBalancerRuleVO("new", "new", 22, 22, "roundrobin", + validGuestNetworkId, validAccountId, 1L, new Ip(validRequestedIp), validGuestNetworkId, Scheme.Internal); + Mockito.when(_lbDao.persist(Mockito.any(ApplicationLoadBalancerRuleVO.class))).thenReturn(lbRule); + + Mockito.when(_lbMgr.validateLbRule(Mockito.any(LoadBalancingRule.class))).thenReturn(true); + + Mockito.when(_firewallDao.setStateToAdd(Mockito.any(FirewallRuleVO.class))).thenReturn(true); + + Mockito.when(_accountMgr.getSystemUser()).thenReturn(new UserVO(1)); + Mockito.when(_accountMgr.getSystemAccount()).thenReturn(new AccountVO(2)); + UserContext.registerContext(_accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount(), null, false); + + Mockito.when(_ntwkModel.areServicesSupportedInNetwork(Mockito.anyLong(), Mockito.any(Network.Service.class))).thenReturn(true); + + Map caps = new HashMap(); + caps.put(Capability.SupportedProtocols, NetUtils.TCP_PROTO); + Mockito.when(_ntwkModel.getNetworkServiceCapabilities(Mockito.anyLong(), Mockito.any(Network.Service.class))).thenReturn(caps); + + + Mockito.when(_lbDao.countBySourceIp(new Ip(validRequestedIp), validGuestNetworkId)).thenReturn(1L); + + } + + /** + * TESTS FOR .getApplicationLoadBalancer + */ + + @Test + //Positive test - retrieve existing lb + public void searchForExistingLoadBalancer() { + ApplicationLoadBalancerRule rule = _appLbSvc.getApplicationLoadBalancer(existingLbId); + assertNotNull("Couldn't find existing application load balancer", rule); + } + + @Test + //Negative test - try to retrieve non-existing lb + public void searchForNonExistingLoadBalancer() { + boolean notFound = false; + ApplicationLoadBalancerRule rule = null; + try { + rule = _appLbSvc.getApplicationLoadBalancer(nonExistingLbId); + if (rule != null) { + notFound = false; + } + } catch (InvalidParameterValueException ex) { + notFound = true; + } + + assertTrue("Found non-existing load balancer; no invalid parameter value exception was thrown", notFound); + } + + /** + * TESTS FOR .deleteApplicationLoadBalancer + */ + + + @Test + //Positive test - delete existing lb + public void deleteExistingLoadBalancer() { + boolean result = false; + try { + result = _appLbSvc.deleteApplicationLoadBalancer(existingLbId); + } finally { + assertTrue("Couldn't delete existing application load balancer", result); + } + } + + + @Test + //Negative test - try to delete non-existing lb + public void deleteNonExistingLoadBalancer() { + boolean result = true; + try { + result = _appLbSvc.deleteApplicationLoadBalancer(nonExistingLbId); + } finally { + assertFalse("Didn't fail when try to delete non-existing load balancer", result); + } + } + + /** + * TESTS FOR .createApplicationLoadBalancer + * @throws NetworkRuleConflictException + * @throws InsufficientVirtualNetworkCapcityException + * @throws InsufficientAddressCapacityException + */ + + @Test (expected = CloudRuntimeException.class) + //Positive test + public void createValidLoadBalancer() throws InsufficientAddressCapacityException, + InsufficientVirtualNetworkCapcityException, NetworkRuleConflictException { + _appLbSvc.createApplicationLoadBalancer("alena", "alena", Scheme.Internal, validGuestNetworkId, validRequestedIp, + 22, 22, "roundrobin", validGuestNetworkId, validAccountId); + } + + + @Test(expected = UnsupportedServiceException.class) + //Negative test - only internal scheme value is supported in the current release + public void createPublicLoadBalancer() throws InsufficientAddressCapacityException, + InsufficientVirtualNetworkCapcityException, NetworkRuleConflictException { + _appLbSvc.createApplicationLoadBalancer("alena", "alena", Scheme.Public, validGuestNetworkId, validRequestedIp, + 22, 22, "roundrobin", validGuestNetworkId, validAccountId); + } + + + @Test(expected = InvalidParameterValueException.class) + //Negative test - invalid SourcePort + public void createWithInvalidSourcePort() throws InsufficientAddressCapacityException, + InsufficientVirtualNetworkCapcityException, NetworkRuleConflictException { + _appLbSvc.createApplicationLoadBalancer("alena", "alena", Scheme.Internal, validGuestNetworkId, validRequestedIp, + 65536, 22, "roundrobin", validGuestNetworkId, validAccountId); + } + + @Test(expected = InvalidParameterValueException.class) + //Negative test - invalid instancePort + public void createWithInvalidInstandePort() throws InsufficientAddressCapacityException, + InsufficientVirtualNetworkCapcityException, NetworkRuleConflictException { + _appLbSvc.createApplicationLoadBalancer("alena", "alena", Scheme.Internal, validGuestNetworkId, validRequestedIp, + 22, 65536, "roundrobin", validGuestNetworkId, validAccountId); + + } + + + @Test(expected = InvalidParameterValueException.class) + //Negative test - invalid algorithm + public void createWithInvalidAlgorithm() throws InsufficientAddressCapacityException, InsufficientVirtualNetworkCapcityException, NetworkRuleConflictException { + String expectedExcText = null; + _appLbSvc.createApplicationLoadBalancer("alena", "alena", Scheme.Internal, validGuestNetworkId, validRequestedIp, + 22, 22, "invalidalgorithm", validGuestNetworkId, validAccountId); + + } + + @Test(expected = InvalidParameterValueException.class) + //Negative test - invalid sourceNetworkId (of Public type, which is not supported) + public void createWithInvalidSourceIpNtwk() throws InsufficientAddressCapacityException, + InsufficientVirtualNetworkCapcityException, NetworkRuleConflictException { + _appLbSvc.createApplicationLoadBalancer("alena", "alena", Scheme.Internal, validPublicNetworkId, validRequestedIp, + 22, 22, "roundrobin", validGuestNetworkId, validAccountId); + + } + + + @Test(expected = InvalidParameterValueException.class) + //Negative test - invalid requested IP (outside of guest network cidr range) + public void createWithInvalidRequestedIp() throws InsufficientAddressCapacityException, + InsufficientVirtualNetworkCapcityException, NetworkRuleConflictException { + + _appLbSvc.createApplicationLoadBalancer("alena", "alena", Scheme.Internal, validGuestNetworkId, "10.2.1.1", + 22, 22, "roundrobin", validGuestNetworkId, validAccountId); + } + + + private static NetworkVO setId(NetworkVO vo, long id) { + NetworkVO voToReturn = vo; + Class c = voToReturn.getClass(); + try { + Field f = c.getDeclaredField("id"); + f.setAccessible(true); + f.setLong(voToReturn, id); + } catch (NoSuchFieldException ex) { + return null; + } catch (IllegalAccessException ex) { + return null; + } + + return voToReturn; + } +} diff --git a/server/test/org/apache/cloudstack/lb/ChildTestConfiguration.java b/server/test/org/apache/cloudstack/lb/ChildTestConfiguration.java new file mode 100644 index 00000000000..918de81c0c5 --- /dev/null +++ b/server/test/org/apache/cloudstack/lb/ChildTestConfiguration.java @@ -0,0 +1,103 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// 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.lb; + +import java.io.IOException; + +import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; +import org.apache.cloudstack.test.utils.SpringUtils; +import org.mockito.Mockito; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.ComponentScan.Filter; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.classreading.MetadataReaderFactory; +import org.springframework.core.type.filter.TypeFilter; + +import com.cloud.dc.dao.AccountVlanMapDaoImpl; +import com.cloud.event.dao.UsageEventDao; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkModel; +import com.cloud.network.dao.FirewallRulesDao; +import com.cloud.network.lb.LoadBalancingRulesManager; +import com.cloud.tags.dao.ResourceTagDao; +import com.cloud.user.AccountManager; + +@Configuration +@ComponentScan( + basePackageClasses={ + AccountVlanMapDaoImpl.class + }, + includeFilters={@Filter(value=ChildTestConfiguration.Library.class, type=FilterType.CUSTOM)}, + useDefaultFilters=false + ) + + public class ChildTestConfiguration { + + public static class Library implements TypeFilter { + + @Bean + public ApplicationLoadBalancerRuleDao applicationLoadBalancerDao() { + return Mockito.mock(ApplicationLoadBalancerRuleDao.class); + } + + @Bean + public NetworkModel networkModel() { + return Mockito.mock(NetworkModel.class); + } + + @Bean + public AccountManager accountManager() { + return Mockito.mock(AccountManager.class); + } + + @Bean + public LoadBalancingRulesManager loadBalancingRulesManager() { + return Mockito.mock(LoadBalancingRulesManager.class); + } + + @Bean + public FirewallRulesDao firewallRulesDao() { + return Mockito.mock(FirewallRulesDao.class); + } + + @Bean + public ResourceTagDao resourceTagDao() { + return Mockito.mock(ResourceTagDao.class); + } + + @Bean + public NetworkManager networkManager() { + return Mockito.mock(NetworkManager.class); + } + + @Bean + public UsageEventDao UsageEventDao() { + return Mockito.mock(UsageEventDao.class); + } + + @Override + public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { + mdr.getClassMetadata().getClassName(); + ComponentScan cs = ChildTestConfiguration.class.getAnnotation(ComponentScan.class); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + } + + } +} diff --git a/server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java b/server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java index 7946c1aa740..92aa2a2c8ff 100644 --- a/server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java +++ b/server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java @@ -84,6 +84,7 @@ public class CreateNetworkOfferingTest extends TestCase{ Mockito.when(configDao.findByName(Mockito.anyString())).thenReturn(configVO); Mockito.when(offDao.persist(Mockito.any(NetworkOfferingVO.class))).thenReturn(new NetworkOfferingVO()); + Mockito.when(offDao.persist(Mockito.any(NetworkOfferingVO.class), Mockito.anyMap())).thenReturn(new NetworkOfferingVO()); Mockito.when(mapDao.persist(Mockito.any(NetworkOfferingServiceMapVO.class))).thenReturn(new NetworkOfferingServiceMapVO()); Mockito.when(accountMgr.getSystemUser()).thenReturn(new UserVO(1)); Mockito.when(accountMgr.getSystemAccount()).thenReturn(new AccountVO(2)); @@ -96,7 +97,7 @@ public class CreateNetworkOfferingTest extends TestCase{ public void createSharedNtwkOffWithVlan() { NetworkOfferingVO off = configMgr.createNetworkOffering("shared", "shared", TrafficType.Guest, null, true, Availability.Optional, 200, null, false, Network.GuestType.Shared, false, - null, false, null, true, false); + null, false, null, true, false, null); assertNotNull("Shared network offering with specifyVlan=true failed to create ", off); } @@ -105,7 +106,7 @@ public class CreateNetworkOfferingTest extends TestCase{ try { NetworkOfferingVO off = configMgr.createNetworkOffering("shared", "shared", TrafficType.Guest, null, false, Availability.Optional, 200, null, false, Network.GuestType.Shared, false, - null, false, null, true, false); + null, false, null, true, false, null); assertNull("Shared network offering with specifyVlan=false was created", off); } catch (InvalidParameterValueException ex) { } @@ -115,7 +116,7 @@ public class CreateNetworkOfferingTest extends TestCase{ public void createSharedNtwkOffWithSpecifyIpRanges() { NetworkOfferingVO off = configMgr.createNetworkOffering("shared", "shared", TrafficType.Guest, null, true, Availability.Optional, 200, null, false, Network.GuestType.Shared, false, - null, false, null, true, false); + null, false, null, true, false, null); assertNotNull("Shared network offering with specifyIpRanges=true failed to create ", off); } @@ -125,7 +126,7 @@ public class CreateNetworkOfferingTest extends TestCase{ try { NetworkOfferingVO off = configMgr.createNetworkOffering("shared", "shared", TrafficType.Guest, null, true, Availability.Optional, 200, null, false, Network.GuestType.Shared, false, - null, false, null, false, false); + null, false, null, false, false, null); assertNull("Shared network offering with specifyIpRanges=false was created", off); } catch (InvalidParameterValueException ex) { } @@ -140,7 +141,7 @@ public class CreateNetworkOfferingTest extends TestCase{ serviceProviderMap.put(Network.Service.SourceNat, vrProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, false, Availability.Optional, 200, serviceProviderMap, false, Network.GuestType.Isolated, false, - null, false, null, false, false); + null, false, null, false, false, null); assertNotNull("Isolated network offering with specifyIpRanges=false failed to create ", off); } @@ -153,7 +154,7 @@ public class CreateNetworkOfferingTest extends TestCase{ serviceProviderMap.put(Network.Service.SourceNat, vrProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, true, Availability.Optional, 200, serviceProviderMap, false, Network.GuestType.Isolated, false, - null, false, null, false, false); + null, false, null, false, false, null); assertNotNull("Isolated network offering with specifyVlan=true wasn't created", off); } @@ -167,7 +168,7 @@ public class CreateNetworkOfferingTest extends TestCase{ serviceProviderMap.put(Network.Service.SourceNat, vrProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, false, Availability.Optional, 200, serviceProviderMap, false, Network.GuestType.Isolated, false, - null, false, null, true, false); + null, false, null, true, false, null); assertNull("Isolated network offering with specifyIpRanges=true and source nat service enabled, was created", off); } catch (InvalidParameterValueException ex) { } @@ -180,7 +181,7 @@ public class CreateNetworkOfferingTest extends TestCase{ Set vrProvider = new HashSet(); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, false, Availability.Optional, 200, serviceProviderMap, false, Network.GuestType.Isolated, false, - null, false, null, true, false); + null, false, null, true, false, null); assertNotNull("Isolated network offering with specifyIpRanges=true and with no sourceNatService, failed to create", off); } @@ -198,7 +199,7 @@ public class CreateNetworkOfferingTest extends TestCase{ serviceProviderMap.put(Network.Service.Lb , vrProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, true, Availability.Optional, 200, serviceProviderMap, false, Network.GuestType.Isolated, false, - null, false, null, false, false); + null, false, null, false, false, null); // System.out.println("Creating Vpc Network Offering"); assertNotNull("Vpc Isolated network offering with Vpc provider ", off); } @@ -218,7 +219,7 @@ public class CreateNetworkOfferingTest extends TestCase{ serviceProviderMap.put(Network.Service.Lb, lbProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, true, Availability.Optional, 200, serviceProviderMap, false, Network.GuestType.Isolated, false, null, false, - null, false, false); + null, false, false, null); // System.out.println("Creating Vpc Network Offering"); assertNotNull("Vpc Isolated network offering with Vpc and Netscaler provider ", off); } diff --git a/server/test/resources/appLoadBalancer.xml b/server/test/resources/appLoadBalancer.xml new file mode 100644 index 00000000000..d7c1502a715 --- /dev/null +++ b/server/test/resources/appLoadBalancer.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/setup/db/db/schema-40to410.sql b/setup/db/db/schema-40to410.sql index a3426e2caaa..b7b1c7a91dd 100644 --- a/setup/db/db/schema-40to410.sql +++ b/setup/db/db/schema-40to410.sql @@ -644,6 +644,7 @@ CREATE VIEW `cloud`.`domain_router_view` AS data_center.id data_center_id, data_center.uuid data_center_uuid, data_center.name data_center_name, + data_center.networktype data_center_type, data_center.dns1 dns1, data_center.dns2 dns2, data_center.ip6_dns1 ip6_dns1, @@ -684,7 +685,8 @@ CREATE VIEW `cloud`.`domain_router_view` AS domain_router.scripts_version scripts_version, domain_router.is_redundant_router is_redundant_router, domain_router.redundant_state redundant_state, - domain_router.stop_pending stop_pending + domain_router.stop_pending stop_pending, + domain_router.role role from `cloud`.`domain_router` inner join diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index c8ac1ecfc2e..065b35ca501 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -339,7 +339,7 @@ CREATE TABLE `cloud`.`vm_snapshots` ( ALTER TABLE `cloud`.`hypervisor_capabilities` ADD COLUMN `vm_snapshot_enabled` tinyint(1) DEFAULT 0 NOT NULL COMMENT 'Whether VM snapshot is supported by hypervisor'; UPDATE `cloud`.`hypervisor_capabilities` SET `vm_snapshot_enabled`=1 WHERE `hypervisor_type` in ('VMware', 'XenServer'); - + DROP VIEW IF EXISTS `cloud`.`user_vm_view`; CREATE VIEW `cloud`.`user_vm_view` AS select @@ -450,7 +450,7 @@ CREATE VIEW `cloud`.`user_vm_view` AS async_job.uuid job_uuid, async_job.job_status job_status, async_job.account_id job_account_id, - affinity_group.id affinity_group_id, + affinity_group.id affinity_group_id, affinity_group.uuid affinity_group_uuid, affinity_group.name affinity_group_name, affinity_group.description affinity_group_description @@ -515,7 +515,7 @@ CREATE VIEW `cloud`.`user_vm_view` AS and async_job.job_status = 0 left join `cloud`.`affinity_group_vm_map` ON vm_instance.id = affinity_group_vm_map.instance_id - left join + left join `cloud`.`affinity_group` ON affinity_group_vm_map.affinity_group_id = affinity_group.id; DROP VIEW IF EXISTS `cloud`.`affinity_group_view`; @@ -844,7 +844,8 @@ CREATE VIEW `cloud`.`domain_router_view` AS domain_router.scripts_version scripts_version, domain_router.is_redundant_router is_redundant_router, domain_router.redundant_state redundant_state, - domain_router.stop_pending stop_pending + domain_router.stop_pending stop_pending, + domain_router.role role from `cloud`.`domain_router` inner join @@ -919,7 +920,7 @@ CREATE TABLE `cloud`.`network_asa1000v_map` ( ALTER TABLE `cloud`.`network_offerings` ADD COLUMN `eip_associate_public_ip` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if public IP is associated with user VM creation by default when EIP service is enabled.' AFTER `elastic_ip_service`; -- Re-enable foreign key checking, at the end of the upgrade path -SET foreign_key_checks = 1; +SET foreign_key_checks = 1; -- Add "default" field to account/user tables @@ -1116,6 +1117,40 @@ CREATE VIEW `cloud`.`account_view` AS and async_job.job_status = 0; + +ALTER TABLE `cloud`.`load_balancing_rules` ADD COLUMN `source_ip_address` varchar(40) COMMENT 'source ip address for the load balancer rule'; +ALTER TABLE `cloud`.`load_balancing_rules` ADD COLUMN `source_ip_address_network_id` bigint unsigned COMMENT 'the id of the network where source ip belongs to'; +ALTER TABLE `cloud`.`load_balancing_rules` ADD COLUMN `scheme` varchar(40) NOT NULL COMMENT 'load balancer scheme; can be Internal or Public'; +UPDATE `cloud`.`load_balancing_rules` SET `scheme`='Public'; + + + +-- Add details talbe for the network offering +CREATE TABLE `cloud`.`network_offering_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `network_offering_id` bigint unsigned NOT NULL COMMENT 'network offering id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_network_offering_details__network_offering_id` FOREIGN KEY `fk_network_offering_details__network_offering_id`(`network_offering_id`) REFERENCES `network_offerings`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Change the constraint for the network service map table. Now we support multiple provider for the same service +ALTER TABLE `cloud`.`ntwk_service_map` DROP FOREIGN KEY `fk_ntwk_service_map__network_id`; +ALTER TABLE `cloud`.`ntwk_service_map` DROP INDEX `network_id`; + +ALTER TABLE `cloud`.`ntwk_service_map` ADD UNIQUE `network_id` (`network_id`,`service`,`provider`); +ALTER TABLE `cloud`.`ntwk_service_map` ADD CONSTRAINT `fk_ntwk_service_map__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks` (`id`) ON DELETE CASCADE; + + +ALTER TABLE `cloud`.`network_offerings` ADD COLUMN `internal_lb` int(1) unsigned NOT NULL DEFAULT '0' COMMENT 'true if the network offering supports Internal lb service'; +ALTER TABLE `cloud`.`network_offerings` ADD COLUMN `public_lb` int(1) unsigned NOT NULL DEFAULT '0' COMMENT 'true if the network offering supports Public lb service'; +UPDATE `cloud`.`network_offerings` SET public_lb=1 where id IN (SELECT DISTINCT network_offering_id FROM `cloud`.`ntwk_offering_service_map` WHERE service='Lb'); + + +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'NetworkManager', 'internallbvm.service.offering', null, 'Uuid of the service offering used by internal lb vm; if NULL - default system internal lb offering will be used'); + + alter table `cloud_usage`.`usage_network_offering` add column nic_id bigint(20) unsigned NOT NULL; ALTER TABLE `cloud`.`data_center_details` MODIFY value varchar(1024); ALTER TABLE `cloud`.`cluster_details` MODIFY value varchar(255); diff --git a/setup/dev/advanced.cfg b/setup/dev/advanced.cfg index 63e435bb18f..83357866ca7 100644 --- a/setup/dev/advanced.cfg +++ b/setup/dev/advanced.cfg @@ -45,6 +45,10 @@ { "broadcastdomainrange": "ZONE", "name": "VpcVirtualRouter" + }, + { + "broadcastdomainrange": "ZONE", + "name": "InternalLbVm" } ], "isolationmethods": [ diff --git a/test/integration/component/test_multiple_ip_ranges.py b/test/integration/component/test_multiple_ip_ranges.py index 7e9eeb1028d..7e9e712aef0 100644 --- a/test/integration/component/test_multiple_ip_ranges.py +++ b/test/integration/component/test_multiple_ip_ranges.py @@ -369,6 +369,7 @@ class TestMultipleIpRanges(cloudstackTestCase): self.fail("CS should not accept overlapped ip ranges in guest traffic, but it allowed") return + @attr(tags=["advanced_sg", "sg"]) def test_06_add_ip_range_overlapped_with_two_ranges(self): """Test adding overlapped ip range in existing cidr diff --git a/test/integration/smoke/test_guest_vlan_range.py b/test/integration/smoke/test_guest_vlan_range.py index bd533430f51..704fe59bfff 100644 --- a/test/integration/smoke/test_guest_vlan_range.py +++ b/test/integration/smoke/test_guest_vlan_range.py @@ -44,6 +44,7 @@ class Services: "password": "password", }, "name": "testphysicalnetwork", + "vlan": "2118-2120", } @@ -149,6 +150,19 @@ class TestDedicateGuestVlanRange(cloudstackTestCase): ) self.debug("Releasing guest vlan range"); +<<<<<<< HEAD + dedicated_guest_vlan_response.release(self.apiclient) + list_dedicated_guest_vlan_range_response = PhysicalNetwork.listDedicated( + self.apiclient, + id=dedicate_guest_vlan_range_response.id + ) + dedicated_guest_vlan_response = list_dedicated_guest_vlan_range_response[0] + self.assertEqual( + dedicated_guest_vlan_response.account, + "system", + "Check account name is system account in listDedicatedGuestVlanRanges" + ) +======= dedicate_guest_vlan_range_response.release(self.apiclient) list_dedicated_guest_vlan_range_response = PhysicalNetwork.listDedicated(self.apiclient) self.assertEqual( @@ -157,4 +171,5 @@ class TestDedicateGuestVlanRange(cloudstackTestCase): "Check vlan range is not available in listDedicatedGuestVlanRanges" ) +>>>>>>> master diff --git a/test/integration/smoke/test_internal_lb.py b/test/integration/smoke/test_internal_lb.py new file mode 100644 index 00000000000..ae64297bf1c --- /dev/null +++ b/test/integration/smoke/test_internal_lb.py @@ -0,0 +1,250 @@ +# 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. +""" Tests for configuring Internal Load Balancing Rules. +""" +#Import Local Modules +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * + + +class TestInternalLb(cloudstackTestCase): + networkOfferingId = None + networkId = None + vmId = None + lbId = None + + zoneId = 1 + serviceOfferingId = 1 + templateId = 5 + + + serviceProviderList = [ + { + "provider": "VpcVirtualRouter", + "service": "Vpn" + }, + { + "provider": "VpcVirtualRouter", + "service": "UserData" + }, + { + "provider": "VpcVirtualRouter", + "service": "Dhcp" + }, + { + "provider": "VpcVirtualRouter", + "service": "Dns" + }, + { + "provider": "InternalLbVM", + "service": "Lb" + }, + { + "provider": "VpcVirtualRouter", + "service": "SourceNat" + }, + { + "provider": "VpcVirtualRouter", + "service": "StaticNat" + }, + { + "provider": "VpcVirtualRouter", + "service": "PortForwarding" + }, + { + "provider": "VpcVirtualRouter", + "service": "NetworkACL" + } + ] + + serviceCapsList = [ + { + "service": "SourceNat", + "capabilitytype": "SupportedSourceNatTypes", + "capabilityvalue": "peraccount" + }, + { + "service": "Lb", + "capabilitytype": "SupportedLbIsolation", + "capabilityvalue": "dedicated" + }, + { + "service": "Lb", + "capabilitytype": "lbSchemes", + "capabilityvalue": "internal" + } + ] + + def setUp(self): + self.apiClient = self.testClient.getApiClient() + + + + def test_internallb(self): + + #1) Create and enable network offering with Internal Lb vm service + self.createNetworkOffering() + + #2) Create VPC and network in it + self.createNetwork() + + #3) Deploy a vm + self.deployVm() + + #4) Create an Internal Load Balancer + self.createInternalLoadBalancer() + + #5) Assign the VM to the Internal Load Balancer + self.assignToLoadBalancerRule() + + #6) Remove the vm from the Interanl Load Balancer + self.removeFromLoadBalancerRule() + + #7) Delete the Load Balancer + self.deleteLoadBalancer() + + + def deployVm(self): + deployVirtualMachineCmd = deployVirtualMachine.deployVirtualMachineCmd() + deployVirtualMachineCmd.networkids = TestInternalLb.networkId + deployVirtualMachineCmd.serviceofferingid = TestInternalLb.serviceOfferingId + deployVirtualMachineCmd.zoneid = TestInternalLb.zoneId + deployVirtualMachineCmd.templateid = TestInternalLb.templateId + deployVirtualMachineCmd.hypervisor = "XenServer" + deployVMResponse = self.apiClient.deployVirtualMachine(deployVirtualMachineCmd) + TestInternalLb.vmId = deployVMResponse.id + + + def createInternalLoadBalancer(self): + createLoadBalancerCmd = createLoadBalancer.createLoadBalancerCmd() + createLoadBalancerCmd.name = "lb rule" + createLoadBalancerCmd.sourceport = 22 + createLoadBalancerCmd.instanceport = 22 + createLoadBalancerCmd.algorithm = "roundrobin" + createLoadBalancerCmd.scheme = "internal" + createLoadBalancerCmd.sourceipaddressnetworkid = TestInternalLb.networkId + createLoadBalancerCmd.networkid = TestInternalLb.networkId + createLoadBalancerResponse = self.apiClient.createLoadBalancer(createLoadBalancerCmd) + TestInternalLb.lbId = createLoadBalancerResponse.id + self.assertIsNotNone(createLoadBalancerResponse.id, "Failed to create a load balancer") + + + def assignToLoadBalancerRule(self): + assignToLoadBalancerRuleCmd = assignToLoadBalancerRule.assignToLoadBalancerRuleCmd() + assignToLoadBalancerRuleCmd.id = TestInternalLb.lbId + assignToLoadBalancerRuleCmd.virtualMachineIds = TestInternalLb.vmId + assignToLoadBalancerRuleResponse = self.apiClient.assignToLoadBalancerRule(assignToLoadBalancerRuleCmd) + self.assertTrue(assignToLoadBalancerRuleResponse.success, "Failed to assign the vm to the load balancer") + + + + def removeFromLoadBalancerRule(self): + removeFromLoadBalancerRuleCmd = removeFromLoadBalancerRule.removeFromLoadBalancerRuleCmd() + removeFromLoadBalancerRuleCmd.id = TestInternalLb.lbId + removeFromLoadBalancerRuleCmd.virtualMachineIds = TestInternalLb.vmId + removeFromLoadBalancerRuleResponse = self.apiClient.removeFromLoadBalancerRule(removeFromLoadBalancerRuleCmd) + self.assertTrue(removeFromLoadBalancerRuleResponse.success, "Failed to remove the vm from the load balancer") + + + + #def removeInternalLoadBalancer(self): + def deleteLoadBalancer(self): + deleteLoadBalancerCmd = deleteLoadBalancer.deleteLoadBalancerCmd() + deleteLoadBalancerCmd.id = TestInternalLb.lbId + deleteLoadBalancerResponse = self.apiClient.deleteLoadBalancer(deleteLoadBalancerCmd) + self.assertTrue(deleteLoadBalancerResponse.success, "Failed to remove the load balancer") + + + + def createNetwork(self): + createVPCCmd = createVPC.createVPCCmd() + createVPCCmd.name = "new vpc" + createVPCCmd.cidr = "10.1.1.0/24" + createVPCCmd.displaytext = "new vpc" + createVPCCmd.vpcofferingid = 1 + createVPCCmd.zoneid = self.zoneId + createVPCResponse = self.apiClient.createVPC(createVPCCmd) + + + createNetworkCmd = createNetwork.createNetworkCmd() + createNetworkCmd.name = "vpc network" + createNetworkCmd.displaytext = "vpc network" + createNetworkCmd.netmask = "255.255.255.0" + createNetworkCmd.gateway = "10.1.1.1" + createNetworkCmd.zoneid = self.zoneId + createNetworkCmd.vpcid = createVPCResponse.id + createNetworkCmd.networkofferingid = TestInternalLb.networkOfferingId + createNetworkResponse = self.apiClient.createNetwork(createNetworkCmd) + TestInternalLb.networkId = createNetworkResponse.id + + self.assertIsNotNone(createNetworkResponse.id, "Network failed to create") + + + def createNetworkOffering(self): + createNetworkOfferingCmd = createNetworkOffering.createNetworkOfferingCmd() + createNetworkOfferingCmd.name = "Network offering for internal lb service - " + str(random.randrange(1,100+1)) + createNetworkOfferingCmd.displaytext = "Network offering for internal lb service" + createNetworkOfferingCmd.guestiptype = "isolated" + createNetworkOfferingCmd.traffictype = "Guest" + createNetworkOfferingCmd.conservemode = "false" + createNetworkOfferingCmd.supportedservices = "Vpn,Dhcp,Dns,Lb,UserData,SourceNat,StaticNat,PortForwarding,NetworkACL" + + + createNetworkOfferingCmd.serviceproviderlist = [] + for item in self.serviceProviderList: + createNetworkOfferingCmd.serviceproviderlist.append({ + 'service': item['service'], + 'provider': item['provider'] + }) + + createNetworkOfferingCmd.servicecapabilitylist = [] + for item in self.serviceCapsList: + createNetworkOfferingCmd.servicecapabilitylist.append({ + 'service': item['service'], + 'capabilitytype': item['capabilitytype'], + 'capabilityvalue': item['capabilityvalue'] + }) + + + createNetworkOfferingResponse = self.apiClient.createNetworkOffering(createNetworkOfferingCmd) + TestInternalLb.networkOfferingId = createNetworkOfferingResponse.id + + #enable network offering + updateNetworkOfferingCmd = updateNetworkOffering.updateNetworkOfferingCmd() + updateNetworkOfferingCmd.id = TestInternalLb.networkOfferingId + updateNetworkOfferingCmd.state = "Enabled" + updateNetworkOfferingResponse = self.apiClient.updateNetworkOffering(updateNetworkOfferingCmd) + + + #list network offering to see if its enabled + listNetworkOfferingsCmd = listNetworkOfferings.listNetworkOfferingsCmd() + listNetworkOfferingsCmd.id = TestInternalLb.networkOfferingId + listOffResponse = self.apiClient.listNetworkOfferings(listNetworkOfferingsCmd) + + self.assertNotEqual(len(listOffResponse), 0, "Check if the list network offerings API \ + returns a non-empty response") + + + def tearDown(self): + #destroy the vm + if TestInternalLb.vmId is not None: + destroyVirtualMachineCmd = destroyVirtualMachine.destroyVirtualMachineCmd() + destroyVirtualMachineCmd.id = TestInternalLb.vmId + destroyVirtualMachineResponse = self.apiClient.destroyVirtualMachine(destroyVirtualMachineCmd) diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index f8bdae281b2..bd8c0f1668f 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -140,6 +140,7 @@ known_categories = { 'removeIpFromNic': 'Nic', 'listNics':'Nic', 'AffinityGroup': 'Affinity Group', + 'InternalLoadBalancer': 'Internal LB', } diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index 21685923b37..7059059beb1 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -216,6 +216,18 @@ class deployDataCenters(): vrconfig.id = vrprovid self.apiClient.configureVirtualRouterElement(vrconfig) self.enableProvider(pnetprovres[0].id) + elif provider.name == 'InternalLbVm': + internallbprov = listInternalLoadBalancerElements.listInternalLoadBalancerElementsCmd() + internallbprov.nspid = pnetprovres[0].id + internallbresponse = self.apiClient.listInternalLoadBalancerElements(internallbprov) + internallbid = internallbresponse[0].id + + internallbconfig = \ + configureInternalLoadBalancerElement.configureInternalLoadBalancerElementCmd() + internallbconfig.enabled = "true" + internallbconfig.id = internallbid + self.apiClient.configureInternalLoadBalancerElement(internallbconfig) + self.enableProvider(pnetprovres[0].id) elif provider.name == 'SecurityGroupProvider': self.enableProvider(pnetprovres[0].id) elif provider.name in ['Netscaler', 'JuniperSRX', 'F5BigIp']: diff --git a/tools/marvin/marvin/sandbox/advanced/advanced_env.py b/tools/marvin/marvin/sandbox/advanced/advanced_env.py index bf880f38055..6343293aa62 100644 --- a/tools/marvin/marvin/sandbox/advanced/advanced_env.py +++ b/tools/marvin/marvin/sandbox/advanced/advanced_env.py @@ -50,6 +50,9 @@ def describeResources(config): vpcprovider = provider() vpcprovider.name = 'VpcVirtualRouter' + + lbprovider = provider() + lbprovider.name = 'InternalLbVm' pn = physical_network() pn.name = "Sandbox-pnet" @@ -60,6 +63,7 @@ def describeResources(config): traffictype("Public", {"simulator":"cloud-simulator-public"})] pn.isolationmethods = ["VLAN"] pn.providers.append(vpcprovider) + pn.providers.append(lbprovider) pn2 = physical_network() pn2.name = "Sandbox-pnet2" @@ -68,6 +72,7 @@ def describeResources(config): pn2.traffictypes = [traffictype('Guest', {'simulator': 'cloud-simulator-guest'})] pn2.isolationmethods = ["VLAN"] pn2.providers.append(vpcprovider) + pn2.providers.append(lbprovider) z.physical_networks.append(pn) z.physical_networks.append(pn2) diff --git a/tools/marvin/marvin/sandbox/advanced/sandbox.cfg b/tools/marvin/marvin/sandbox/advanced/sandbox.cfg new file mode 100644 index 00000000000..01a84730dad --- /dev/null +++ b/tools/marvin/marvin/sandbox/advanced/sandbox.cfg @@ -0,0 +1,209 @@ +{ + "zones": [ + { + "name": "Sandbox-Simulator", + "guestcidraddress": "10.1.1.0/24", + "dns1": "10.147.28.6", + "physical_networks": [ + { + "providers": [ + { + "broadcastdomainrange": "ZONE", + "name": "VirtualRouter" + }, + { + "broadcastdomainrange": "ZONE", + "name": "VpcVirtualRouter" + }, + { + "broadcastdomainrange": "ZONE", + "name": "InternalLb" + } + ], + "name": "Sandbox-pnet", + "tags": [ + "cloud-simulator-public" + ], + "broadcastdomainrange": "Zone", + "vlan": "675-679", + "traffictypes": [ + { + "typ": "Guest" + }, + { + "typ": "Management", + "simulator": "cloud-simulator-mgmt" + }, + { + "typ": "Public", + "simulator": "cloud-simulator-public" + } + ], + "isolationmethods": [ + "VLAN" + ] + }, + { + "providers": [ + { + "broadcastdomainrange": "ZONE", + "name": "VirtualRouter" + }, + { + "broadcastdomainrange": "ZONE", + "name": "VpcVirtualRouter" + }, + { + "broadcastdomainrange": "ZONE", + "name": "InternalLb" + } + ], + "name": "Sandbox-pnet2", + "tags": [ + "cloud-simulator-guest" + ], + "broadcastdomainrange": "Zone", + "vlan": "800-1000", + "traffictypes": [ + { + "typ": "Guest", + "simulator": "cloud-simulator-guest" + } + ], + "isolationmethods": [ + "VLAN" + ] + } + ], + "securitygroupenabled": "false", + "ipranges": [ + { + "startip": "10.147.31.150", + "endip": "10.147.31.159", + "netmask": "255.255.255.0", + "vlan": "31", + "gateway": "10.147.31.1" + } + ], + "networktype": "Advanced", + "pods": [ + { + "endip": "10.147.29.159", + "name": "POD0", + "startip": "10.147.29.150", + "netmask": "255.255.255.0", + "clusters": [ + { + "clustername": "C0", + "hypervisor": "Simulator", + "hosts": [ + { + "username": "root", + "url": "http://simulator0", + "password": "password" + } + ], + "clustertype": "CloudManaged", + "primaryStorages": [ + { + "url": "nfs://10.147.28.6:/export/home/sandbox/primary", + "name": "PS0" + } + ] + } + ], + "gateway": "10.147.29.1" + } + ], + "internaldns1": "10.147.28.6", + "secondaryStorages": [ + { + "url": "nfs://10.147.28.6:/export/home/sandbox/sstor" + } + ] + } + ], + "dbSvr": { + "dbSvr": "localhost", + "passwd": "cloud", + "db": "cloud", + "port": 3306, + "user": "cloud" + }, + "logger": [ + { + "name": "TestClient", + "file": "testclient.log" + }, + { + "name": "TestCase", + "file": "testcase.log" + } + ], + "globalConfig": [ + { + "name": "storage.cleanup.interval", + "value": "300" + }, + { + "name": "direct.agent.load.size", + "value": "1000" + }, + { + "name": "default.page.size", + "value": "10000" + }, + { + "name": "instance.name", + "value": "QA" + }, + { + "name": "workers", + "value": "10" + }, + { + "name": "vm.op.wait.interval", + "value": "5" + }, + { + "name": "account.cleanup.interval", + "value": "600" + }, + { + "name": "guest.domain.suffix", + "value": "sandbox.simulator" + }, + { + "name": "expunge.delay", + "value": "60" + }, + { + "name": "vm.allocation.algorithm", + "value": "random" + }, + { + "name": "expunge.interval", + "value": "60" + }, + { + "name": "expunge.workers", + "value": "3" + }, + { + "name": "secstorage.allowed.internal.sites", + "value": "10.147.28.0/24" + }, + { + "name": "check.pod.cidrs", + "value": "true" + } + ], + "mgtSvr": [ + { + "mgtSvrIp": "localhost", + "passwd": "password", + "user": "root", + "port": 8096 + } + ] +} \ No newline at end of file diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js index b28258544b7..9b28c327b78 100755 --- a/ui/scripts/zoneWizard.js +++ b/ui/scripts/zoneWizard.js @@ -2376,6 +2376,110 @@ }); // ***** Virtual Router ***** (end) ***** + // ***** Internal LB ***** (begin) ***** + var internalLbProviderId; + $.ajax({ + url: createURL("listNetworkServiceProviders&name=Internallbvm&physicalNetworkId=" + thisPhysicalNetwork.id), + dataType: "json", + async: false, + success: function(json) { + var items = json.listnetworkserviceprovidersresponse.networkserviceprovider; + if(items != null && items.length > 0) { + internalLbProviderId = items[0].id; + } + } + }); + if(internalLbProviderId == null) { + alert("error: listNetworkServiceProviders API doesn't return internalLb provider ID"); + return; + } + + var internalLbElementId; + $.ajax({ + url: createURL("listInternalLoadBalancerElements&nspid=" + internalLbProviderId), + dataType: "json", + async: false, + success: function(json) { + var items = json.listinternalloadbalancerelementsresponse.internalloadbalancerelement; + if(items != null && items.length > 0) { + internalLbElementId = items[0].id; + } + } + }); + if(internalLbElementId == null) { + alert("error: listInternalLoadBalancerElements API doesn't return Internal LB Element Id"); + return; + } + + $.ajax({ + url: createURL("configureInternalLoadBalancerElement&enabled=true&id=" + internalLbElementId), + dataType: "json", + async: false, + success: function(json) { + var jobId = json.configureinternalloadbalancerelementresponse.jobid; + var enableInternalLbElementIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId="+jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(enableInternalLbElementIntervalID); + + if (result.jobstatus == 1) { //configureVirtualRouterElement succeeded + $.ajax({ + url: createURL("updateNetworkServiceProvider&state=Enabled&id=" + internalLbProviderId), + dataType: "json", + async: false, + success: function(json) { + var jobId = json.updatenetworkserviceproviderresponse.jobid; + var enableInternalLbProviderIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId="+jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(enableInternalLbProviderIntervalID); + + if (result.jobstatus == 1) { //Internal LB has been enabled successfully + //don't need to do anything here + } + else if (result.jobstatus == 2) { + alert("failed to enable Internal LB Provider. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("failed to enable Internal LB Provider. Error: " + errorMsg); + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + } + else if (result.jobstatus == 2) { + alert("configureVirtualRouterElement failed. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("configureVirtualRouterElement failed. Error: " + errorMsg); + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + // ***** Internal LB ***** (end) ***** + if(args.data.zone.sgEnabled != true) { //Advanced SG-disabled zone // ***** VPC Virtual Router ***** (begin) ***** var vpcVirtualRouterProviderId; From 19f014585e1d2a85b66ecd5ad57ee0c6338beb4c Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 9 May 2013 14:47:49 -0700 Subject: [PATCH 54/71] Marvin test: exclude sandbox.cfg from the rat check --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 9dbd1bf8d7a..e8fdb2f83ea 100644 --- a/pom.xml +++ b/pom.xml @@ -437,6 +437,7 @@ patches/systemvm/debian/config/var/www/html/latest/.htaccess patches/systemvm/debian/vpn/etc/ipsec.d/l2tp.conf tools/transifex/.tx/config + tools/marvin/marvin/sandbox/advanced/sandbox.cfg From 75a2457af639e6bcf751c2e97d1360df1a0265e4 Mon Sep 17 00:00:00 2001 From: Hari Patanala Date: Fri, 10 May 2013 09:29:41 +0530 Subject: [PATCH 55/71] CLOUDSTACK-658 - Adding scale vm support for vmware with unit tests Signed off by : Nitin Mehta --- plugins/hypervisors/vmware/pom.xml | 10 +++ .../vmware/resource/VmwareResource.java | 31 ++++++- .../vmware/resource/VmwareResourceTest.java | 82 +++++++++++++++++++ .../src/com/cloud/vm/UserVmManagerImpl.java | 2 +- .../hypervisor/vmware/util/VmwareHelper.java | 26 +++++- 5 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml index d65ef640655..79779decf62 100644 --- a/plugins/hypervisors/vmware/pom.xml +++ b/plugins/hypervisors/vmware/pom.xml @@ -58,5 +58,15 @@ wsdl4j 1.4 + + junit + junit + 4.10 + + + org.mockito + mockito-all + 1.9.5 +
    diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index d87da64040b..6d7e0e7289c 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -111,6 +111,8 @@ import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.RevertToVMSnapshotAnswer; import com.cloud.agent.api.RevertToVMSnapshotCommand; +import com.cloud.agent.api.ScaleVmCommand; +import com.cloud.agent.api.ScaleVmAnswer; import com.cloud.agent.api.SetupAnswer; import com.cloud.agent.api.SetupCommand; import com.cloud.agent.api.SetupGuestNetworkAnswer; @@ -485,6 +487,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return execute((ResizeVolumeCommand) cmd); } else if (clz == UnregisterVMCommand.class) { return execute((UnregisterVMCommand) cmd); + } else if (clz == ScaleVmCommand.class) { + return execute((ScaleVmCommand) cmd); } else { answer = Answer.createUnsupportedCommandAnswer(cmd); } @@ -2088,6 +2092,28 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return validatedDisks.toArray(new VolumeTO[0]); } + protected ScaleVmAnswer execute(ScaleVmCommand cmd) { + + VmwareContext context = getServiceContext(); + VirtualMachineTO vmSpec = cmd.getVirtualMachine(); + try{ + VmwareHypervisorHost hyperHost = getHyperHost(context); + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName()); + VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); + int ramMb = (int) (vmSpec.getMinRam()); + + VmwareHelper.setVmScaleUpConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getSpeed(), vmSpec.getSpeed(),(int) (vmSpec.getMaxRam()), ramMb, vmSpec.getLimitCpuUse()); + + if(!vmMo.configureVm(vmConfigSpec)) { + throw new Exception("Unable to execute ScaleVmCommand"); + } + }catch(Exception e) { + s_logger.error("Unexpected exception: ", e); + return new ScaleVmAnswer(cmd, false, "Unable to execute ScaleVmCommand due to " + e.toString()); + } + return new ScaleVmAnswer(cmd, true, null); + } + protected StartAnswer execute(StartCommand cmd) { if (s_logger.isInfoEnabled()) { @@ -2191,7 +2217,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), vmSpec.getMinSpeed(),(int) (vmSpec.getMaxRam()/(1024*1024)), ramMb, translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), vmSpec.getLimitCpuUse()); - + + vmConfigSpec.setMemoryHotAddEnabled(true); + vmConfigSpec.setCpuHotAddEnabled(true); + if ("true".equals(vmSpec.getDetails().get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG))) { s_logger.debug("Nested Virtualization enabled in configuration, checking hypervisor capability"); ManagedObjectReference hostMor = vmMo.getRunningHost().getMor(); diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java new file mode 100644 index 00000000000..3ca0b600e36 --- /dev/null +++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java @@ -0,0 +1,82 @@ +// 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.hypervisor.vmware.resource; + +import com.cloud.agent.api.Command; +import com.cloud.agent.api.ScaleVmAnswer; +import com.cloud.agent.api.ScaleVmCommand; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.hypervisor.vmware.mo.VirtualMachineMO; +import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost; +import com.cloud.hypervisor.vmware.util.VmwareContext; +import com.cloud.hypervisor.vmware.util.VmwareHelper; +import com.vmware.vim25.VirtualMachineConfigSpec; +import org.junit.Test; +import org.junit.Before; + +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.MockitoAnnotations; +import static org.mockito.Mockito.*; + + +public class VmwareResourceTest { + + @Spy VmwareResource _resource = new VmwareResource() { + + @Override + public ScaleVmAnswer execute(ScaleVmCommand cmd) { + return super.execute(cmd); + } + @Override + public VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd) { + return hyperHost; + } + }; + + @Mock VmwareContext context; + @Mock ScaleVmCommand cmd; + @Mock VirtualMachineTO vmSpec; + @Mock + VmwareHypervisorHost hyperHost; + @Mock VirtualMachineMO vmMo; + @Mock VirtualMachineConfigSpec vmConfigSpec; + + @Before + public void setup(){ + MockitoAnnotations.initMocks(this); + doReturn(context).when(_resource).getServiceContext(null); + when(cmd.getVirtualMachine()).thenReturn(vmSpec); + } + //Test successful scaling up the vm + @Test + public void testScaleVMF1() throws Exception { + when(_resource.getHyperHost(context, null)).thenReturn(hyperHost); + doReturn("i-2-3-VM").when(cmd).getVmName(); + when(hyperHost.findVmOnHyperHost("i-2-3-VM")).thenReturn(vmMo); + doReturn(1024L).when(vmSpec).getMinRam(); + doReturn(1).when(vmSpec).getCpus(); + doReturn(1000).when(vmSpec).getSpeed(); + doReturn(1024L).when(vmSpec).getMaxRam(); + doReturn(false).when(vmSpec).getLimitCpuUse(); + when(vmMo.configureVm(vmConfigSpec)).thenReturn(true); + + ScaleVmAnswer answer = _resource.execute(cmd); + verify(_resource).execute(cmd); + } + +} diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index eee8503b3f5..9fbc5099374 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1064,7 +1064,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use // Verify input parameters VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId); - if(vmInstance.getHypervisorType() != HypervisorType.XenServer){ + if(vmInstance.getHypervisorType() != HypervisorType.XenServer && vmInstance.getHypervisorType() != HypervisorType.VMware){ throw new InvalidParameterValueException("This operation not permitted for this hypervisor of the vm"); } diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java index 9c467dc8b6b..4a6a135a5b8 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java @@ -524,7 +524,31 @@ public class VmwareHelper { return options; } - public static void setBasicVmConfig(VirtualMachineConfigSpec vmConfig, int cpuCount, int cpuSpeedMHz, int cpuReservedMhz, + public static void setVmScaleUpConfig(VirtualMachineConfigSpec vmConfig, int cpuCount, int cpuSpeedMHz, int cpuReservedMhz, + int memoryMB, int memoryReserveMB, boolean limitCpuUse) { + + // VM config for scaling up + vmConfig.setMemoryMB((long)memoryMB); + vmConfig.setNumCPUs(cpuCount); + + ResourceAllocationInfo cpuInfo = new ResourceAllocationInfo(); + if (limitCpuUse) { + cpuInfo.setLimit((long)(cpuSpeedMHz * cpuCount)); + } else { + cpuInfo.setLimit(-1L); + } + + cpuInfo.setReservation((long)cpuReservedMhz); + vmConfig.setCpuAllocation(cpuInfo); + + ResourceAllocationInfo memInfo = new ResourceAllocationInfo(); + memInfo.setLimit((long)memoryMB); + memInfo.setReservation((long)memoryReserveMB); + vmConfig.setMemoryAllocation(memInfo); + + } + + public static void setBasicVmConfig(VirtualMachineConfigSpec vmConfig, int cpuCount, int cpuSpeedMHz, int cpuReservedMhz, int memoryMB, int memoryReserveMB, String guestOsIdentifier, boolean limitCpuUse) { // VM config basics From 7fea21e31f25e0a42a4e2d311faa3cba429e0101 Mon Sep 17 00:00:00 2001 From: Radhika PC Date: Fri, 10 May 2013 10:03:11 +0530 Subject: [PATCH 56/71] CLOUDSTACK-893 conceptual info around gslb --- docs/en-US/added-API-commands-4.2.xml | 33 ++++--- docs/en-US/gslb.xml | 120 ++++++++++++++++++++------ 2 files changed, 118 insertions(+), 35 deletions(-) diff --git a/docs/en-US/added-API-commands-4.2.xml b/docs/en-US/added-API-commands-4.2.xml index 7417bd15f35..3abb780663e 100644 --- a/docs/en-US/added-API-commands-4.2.xml +++ b/docs/en-US/added-API-commands-4.2.xml @@ -91,20 +91,31 @@ listGlobalLoadBalancerRule - Lists load balancer rules. account (lists resources by account. Use with the domainId - parameter); domainid (lists only resources belonging to the domain specified) id (the unique - ID of the global load balancer rule) isrecursive (defaults to false, but if true, lists all - resources from the parent specified by the domainId till leaves); keyword (List by keyword); - listall (if set to false, list only resources belonging to the command's caller; if set to - true - list resources that the caller is authorized to see. Default value is false); page; - pagesize; projectid (lists objects by project); regionid (region ID); tags (lists resources - by tags: key/value pairs). + Lists load balancer rules. + The request parameters are: account (lists resources by account. Use with the domainid + parameter); domainid (lists only resources belonging to the domain specified); id (the + unique ID of the global load balancer rule); isrecursive (defaults to false; but if true, + lists all the resources from the parent specified by the domainid); keyword (lists by + keyword); listall (if set to false, lists only resources belonging to the command's caller; + if set to true, lists resources that the caller is authorized to see. Default value is + false); page; pagesize; projectid (lists objects by project); regionid ; tags (lists + resources by tags: key/value pairs). updateGlobalLoadBalancerRule - Archives the specified events. The request parameters are: ids (allowed to pass one or - more IDs separated by comma); type (string); olderthan (yyyy-mm-dd format). - The response parameters are: true, false + Updates global load balancer rules. + The request parameters are: id (the unique ID of the global load balancer rule); account + (lists resources by account. Use with the domainid parameter); description (the description + of the load balancer rule); domainid (lists only resources belonging to the domain + specified); gslblbmethod (the load balancer algorithm that is used to distributed traffic + across the zones participating in global server load balancing, if not specified defaults to + round robin); gslbstickysessionmethodname (the session sticky method; if not specified + defaults to sourceip); isrecursive (defaults to false, but if true, lists all resources from + the parent specified by the domainid till leaves); keyword (lists by keyword); listall (if + set to false, list only those resources belonging to the command's caller; if set to true, + lists resources that the caller is authorized to see. Default value is false); page; + pagesize; projectid (lists objects by project); regionid; tags (lists resources by tags: + key/value pairs) diff --git a/docs/en-US/gslb.xml b/docs/en-US/gslb.xml index 385642d394d..ac17d61d69c 100644 --- a/docs/en-US/gslb.xml +++ b/docs/en-US/gslb.xml @@ -41,6 +41,60 @@ alternate location for accessing a resource in the event of a failure, or to provide a means of shifting traffic easily to simplify maintenance, or both. +
    + Components of GSLB + A typical GSLB environment is comprised of the following components: + + + GSLB Site: In &PRODUCT;terminology, GSLB sites are + represented by zones that are mapped to data centers, each of which has various network + appliances. Each GSLB site is managed by a NetScaler appliance that is local to that site. + Each of these appliances treats its own site as the local site and all other sites, + managed by other appliances, as remote sites. + + + GSLB Services: A GSLB service is typically + represented by a load balancing or content switching virtual server. In a GSLB + environment, you can have a local as well as remote GSLB services. A local GSLB service + represents a local load balancing or content switching virtual server. A remote GSLB + service is the one configured at one of the other sites in the GSLB setup. At each site in + the GSLB setup, you can create one local GSLB service and any number of remote GSLB + services. + + + GSLB Virtual Servers: A GSLB virtual server refers to + one or more GSLB services and balances traffic between traffic across the VMs in multiple + zones by using the &PRODUCT; functionality. It evaluates the configured GSLB methods or + algorithms to select a GSLB service to which to send the client requests. One or more + virtual servers from different zones are bound to the GSLB virtual server. GSLB virtual + server does not have a public IP associated with it, instead it will have a FQDN DNS + name. + + + Load Balancing or Content Switching Virtual Servers: + According to Citrix NetScaler terminology, a load balancing or content switching virtual + server represents one or many servers on the local network. Clients send their requests to + the load balancing or content switching virtual server’s virtual IP (VIP) address, and the + virtual server balances the load across the local servers. After a GSLB virtual server + selects a GSLB service representing either a local or a remote load balancing or content + switching virtual server, the client sends the request to that virtual server’s VIP + address. + + + DNS VIPs: DNS virtual IP represents a load balancing + DNS virtual server on the GSLB service provider. The DNS requests for domains for which + the GSLB service provider is authoritative can be sent to a DNS VIP. + + + ADNS: ADNS (Authoritative Domain Name Server) is a + service that provides actual answer to DNS queries, such as web site IP address. In a GSLB + environment, an ADNS service responds only to DNS requests for domains for which the GSLB + service provider is authoritative. When an ADNS service is configured, the service + provider owns that IP address and advertises it. When you create an ADNS service, the + NetScaler responds to DNS queries on the configured ADNS service IP and port. + + +
    Prerequisites and Guidelines @@ -63,23 +117,23 @@ When users have VMs deployed in multiple availability zones which are GSLB enabled, - user is allowed to use the GSLB functionality to load balance traffic across the VMs in - multiple zones. + they can use the GSLB functionality to load balance traffic across the VMs in multiple + zones. - The users are allowed to use GSLB to load balance across the VMs across zones in a - region only if the admin has enabled GSLB in that region. + The users can use GSLB to load balance across the VMs across zones in a region only if + the admin has enabled GSLB in that region. - The users are allowed to load balance traffic across the availability zones in the - same region or different regions. + The users can load balance traffic across the availability zones in the same region or + different regions. - The admin is allowed to configure DNS name for the entire cloud. + The admin can configure DNS name for the entire cloud. - The users can specify an unique name, across the cloud, for a globally load balanced - service. The provided name will be used as the domain under the DNS name associated with + The users can specify an unique name across the cloud for a globally load balanced + service. The provided name is used as the domain name under the DNS name associated with the cloud. The user-provided name along with the admin-provided DNS name is used to produce a globally resolvable FQDN for the globally load balanced service of the user. For example, @@ -88,13 +142,12 @@ foo.xyztelco.com. - While setting up GSLB, users can select a load balancing method, such as round robin - or least RTT, that would be the load balance traffic used across the zones that are part - of GSLB. + While setting up GSLB, users can select a load balancing method, such as round robin, + for using across the zones that are part of GSLB. The user shall be able to set weight to zone-level virtual server. Weight shall be - considered by the load balancing method is distributing the traffic. + considered by the load balancing method for distributing the traffic. The GSLB functionality shall support session persistence, where series of client @@ -103,6 +156,24 @@
    +
    + Configuring GSLB + To configure GSLB in your cloud environment, as a cloud administrator you must perform the + following. + To configure such a GSLB setup, you must first configure a standard load balancing setup + for each server farm or data center. This enables you to balance load across the different + servers in each server farm. Then, configure both NetScaler appliances as authoritative DNS + (ADNS) servers. Next, create a GSLB site for each server farm, configure GSLB virtual servers + for each site, create GLSB services, and bind the GSLB services to the GSLB virtual servers. + Finally, bind the domain to the GSLB virtual servers. The GSLB configurations on the two + appliances at the two different sites are identical, although each sites load-balancing + configuration is specific to that site. + + + + + +
    Adding a GSLB Rule @@ -174,17 +245,18 @@
    How Does GSLB Works in &PRODUCT;? - The following is an illustrated conceptual model of how GLSB functionality is provided in - &PRODUCT;: An organization, xyztelco, has set up a public cloud that spans two zones, Zone-1 - and Zone-2, across geographically separated data centers that are managed by &PRODUCT;. - Tenant-A of the cloud launches a highly available solution by using xyztelco cloud. For that - purpose, they launch two instances each in both the zones: VM1 and VM2 in Zone-1 and VM5 and - VM6 in Zone-2. Tenant-A acquires a public IP, IP-1 in Zone-1, and configures a load balancer - rule to load balance the traffic between VM1 and VM2 instances. &PRODUCT; orchestrates setting - up a virtual server on the LB service provider in Zone-1. Virtual server 1 that is set up on - the LB service provider in Zone-1 represents a publicly accessible virtual server that client - reaches at IP-1. The client traffic to virtual server 1 at IP-1 will be load balanced across - VM1 and VM2 instances. + Global server load balancing is used to manage traffic flow to a web site hosted on two + separate zones that ideally are in different geographic locations. The following is an + illustration of how GLSB functionality is provided in &PRODUCT;: An organization, xyztelco, + has set up a public cloud that spans two zones, Zone-1 and Zone-2, across geographically + separated data centers that are managed by &PRODUCT;. Tenant-A of the cloud launches a highly + available solution by using xyztelco cloud. For that purpose, they launch two instances each + in both the zones: VM1 and VM2 in Zone-1 and VM5 and VM6 in Zone-2. Tenant-A acquires a public + IP, IP-1 in Zone-1, and configures a load balancer rule to load balance the traffic between + VM1 and VM2 instances. &PRODUCT; orchestrates setting up a virtual server on the LB service + provider in Zone-1. Virtual server 1 that is set up on the LB service provider in Zone-1 + represents a publicly accessible virtual server that client reaches at IP-1. The client + traffic to virtual server 1 at IP-1 will be load balanced across VM1 and VM2 instances. Tenant-A acquires another public IP, IP-2 in Zone-2 and sets up a load balancer rule to load balance the traffic between VM5 and VM6 instances. Similarly in Zone-2, &PRODUCT; orchestrates setting up a virtual server on the LB service provider. Virtual server 2 that is From fa9987753c530c8e9560297986ac8848b7526854 Mon Sep 17 00:00:00 2001 From: Sanjay Tripathi Date: Thu, 9 May 2013 18:01:40 +0530 Subject: [PATCH 57/71] CLOUDSTACK-2419 : Localization - Some Japanese are not working --- services/console-proxy/server/js/ajaxkeys.js | 70 +++++++++++++------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/services/console-proxy/server/js/ajaxkeys.js b/services/console-proxy/server/js/ajaxkeys.js index 1ed41c562d4..5f497bbb785 100644 --- a/services/console-proxy/server/js/ajaxkeys.js +++ b/services/console-proxy/server/js/ajaxkeys.js @@ -155,7 +155,7 @@ KEYBOARD_TYPE_JP = "jp"; KEYBOARD_TYPE_UK = "uk"; //JP keyboard type -// + var keyboardTables = [ {tindex: 0, keyboardType: KEYBOARD_TYPE_COOKED, mappingTable: {X11: [ {keycode: 222, entry: X11_KEY_CIRCUMFLEX_ACCENT}, @@ -220,15 +220,31 @@ var keyboardTables = [ {keycode: JS_KEY_SHIFT, entry : X11_KEY_SHIFT}, {keycode: JS_KEY_CTRL, entry : X11_KEY_CTRL}, {keycode: JS_KEY_ALT, entry : X11_KEY_ALT}, - {keycode: JS_KEY_GRAVE_ACCENT, entry : X11_KEY_GRAVE_ACCENT}, - {keycode: JS_KEY_SUBSTRACT, entry : X11_KEY_SUBSTRACT}, - {keycode: JS_KEY_ADD, entry : X11_KEY_ADD}, - {keycode: JS_KEY_OPEN_BRACKET, entry : X11_KEY_OPEN_BRACKET}, - {keycode: JS_KEY_CLOSE_BRACKET, entry : X11_KEY_CLOSE_BRACKET}, + //{keycode: JS_KEY_GRAVE_ACCENT, entry : X11_KEY_GRAVE_ACCENT}, + //[192 / 64 = "' @"] + {keycode: 192, entry : 0x5b, browser: "IE"}, + {keycode: 64, entry : 0x5b, browser: "Firefox"}, + //{keycode: JS_KEY_ADD, entry : X11_KEY_ADD}, + //[187 / 59 = "; +"] + {keycode: 187, entry : 0x3a, browser: "IE"}, + {keycode: 59, entry : 0x3b, browser: "Firefox"}, + //{keycode: JS_KEY_OPEN_BRACKET, entry : X11_KEY_OPEN_BRACKET}, + //[219 = "[{"] + {keycode: 219, entry : 0x5d, browser: "IE"}, + {keycode: 219, entry : 0x5d, browser: "Firefox"}, + //{keycode: JS_KEY_CLOSE_BRACKET, entry : X11_KEY_CLOSE_BRACKET}, + //[221 = "]}"] + {keycode: 221, entry : 0x5c, browser: "IE"}, + {keycode: 221, entry : 0x5c, browser: "Firefox"}, {keycode: JS_KEY_BACK_SLASH, entry : X11_KEY_BACK_SLASH}, - {keycode: JS_KEY_SINGLE_QUOTE, entry : X11_KEY_SINGLE_QUOTE}, + //{keycode: JS_KEY_SINGLE_QUOTE, entry : X11_KEY_SINGLE_QUOTE}, + //[222 / 160 = "~^"] + {keycode: 222, entry : 0x3d, browser: "IE"}, + {keycode: 160, entry : 0x3d, browser: "Firefox"}, + //[173 = "-=" ] specific to Firefox browser + {keycode: 173, entry : 0x2d, browser: "Firefox"}, {keycode: JS_KEY_COMMA, entry : X11_KEY_COMMA}, - {keycode: JS_KEY_PERIOD, entry : X11_KEY_PERIOD}, + {keycode: JS_KEY_PERIOD, entry : X11_KEY_PERIOD}, {keycode: JS_KEY_FORWARD_SLASH, entry : X11_KEY_FORWARD_SLASH}, {keycode: JS_KEY_DASH, entry : X11_KEY_DASH}, {keycode: JS_KEY_SEMI_COLON, entry : X11_KEY_SEMI_COLON}, @@ -243,8 +259,16 @@ var keyboardTables = [ {keycode: JS_KEY_NUMPAD8, entry : X11_KEY_NUMPAD8}, {keycode: JS_KEY_NUMPAD9, entry : X11_KEY_NUMPAD9}, {keycode: JS_KEY_DECIMAL_POINT, entry : X11_KEY_DECIMAL_POINT}, - {keycode: JS_KEY_DIVIDE, entry : X11_KEY_DIVIDE}, - + {keycode: JS_KEY_DIVIDE, entry : 0xffaf}, + {keycode: JS_KEY_MULTIPLY, entry : 0xffaa}, + {keycode: JS_KEY_ADD, entry : 0xffab}, + {keycode: JS_KEY_SUBSTRACT, entry : 0xffad}, + //Kanji Key = 243 / 244 + {keycode: 243, entry : 0x7e, browser: "IE"}, + {keycode: 244, entry : 0x7e, browser: "IE"}, + //Caps Lock = 240 + {keycode: 240, entry : 0xffe5}, + /* {keycode: JS_KEY_MULTIPLY, entry : [ {type: KEY_DOWN, code: X11_KEY_SHIFT, modifiers: 0 }, {type: KEY_DOWN, code: X11_KEY_ASTERISK, modifiers: 0 }, @@ -252,21 +276,17 @@ var keyboardTables = [ {type: KEY_UP, code: X11_KEY_SHIFT, modifiers: 0 } ]}, {keycode: JS_KEY_ADD, entry : false} - ], - keyPress: [ - {keycode: 61, entry: [ - {type: KEY_DOWN, code: X11_KEY_ADD, modifiers: 0, shift: false }, - {type: KEY_UP, code: X11_KEY_ADD, modifiers: 0, shift: false } - ]}, - {keycode: 43, entry: [ - {type: KEY_DOWN, code: X11_KEY_SHIFT, modifiers: 0, shift: false }, - {type: KEY_DOWN, code: X11_KEY_ADD, modifiers: 0, shift: false }, - {type: KEY_UP, code: X11_KEY_ADD, modifiers: 0, shift: false }, - {type: KEY_UP, code: X11_KEY_SHIFT, modifiers: 0, shift: false }, - {type: KEY_DOWN, code: X11_KEY_ADD, modifiers: 0, shift: true }, - {type: KEY_UP, code: X11_KEY_ADD, modifiers: 0, shift: true } - ]} - ] + */ + //[186 / 58 = "~^"] + {keycode: 186, entry : 0x22, browser: "IE"}, + {keycode: 58, entry : 0x22, browser: "Firefox"}, + ], + keyPress: [ + {keycode: 61, entry: [ + {type: KEY_DOWN, code: X11_KEY_ADD, modifiers: 0, shift: false }, + {type: KEY_UP, code: X11_KEY_ADD, modifiers: 0, shift: false } + ]}, + ] } }, {tindex: 2, keyboardType: KEYBOARD_TYPE_UK, mappingTable: {X11: [], From 3aed20c9d27cbe97afc32fd47909a2f08c4550c8 Mon Sep 17 00:00:00 2001 From: Sanjay Tripathi Date: Wed, 8 May 2013 14:17:20 +0530 Subject: [PATCH 58/71] CLOUDSTACK-1603: Management server .log Java Exceptions are displayed with Alerts --- .../storage/datastore/provider/DefaultHostListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java index f2cb1c45c82..2f0b43ad9f6 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java @@ -56,7 +56,7 @@ public class DefaultHostListener implements HypervisorHostListener { } if (!answer.getResult()) { - String msg = "Add host failed due to ModifyStoragePoolCommand failed" + answer.getDetails(); + String msg = "Unable to attach storage pool" + poolId + " to the host" + hostId; alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, pool.getDataCenterId(), pool.getPodId(), msg, msg); throw new CloudRuntimeException("Unable establish connection from storage head to storage pool " + pool.getId() + " due to " + answer.getDetails() + pool.getId()); } From e40aba3bc099d8ad49b87829803c58b4a5975717 Mon Sep 17 00:00:00 2001 From: Pranav Saxena Date: Fri, 10 May 2013 11:05:47 +0530 Subject: [PATCH 59/71] CLOUDSTACK-2411:UI:fail to enable conserve mode while creating NO with guest type as shared --- ui/scripts/configuration.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index 4a64eeac1a5..9a08c4c56b1 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -1210,7 +1210,7 @@ } } }); - if(havingVpcVirtualRouterForAtLeastOneService == true || $guestTypeField.val() == 'Shared') { + if(havingVpcVirtualRouterForAtLeastOneService == true ) { $conservemode.find("input[type=checkbox]").attr("disabled", "disabled"); $conservemode.find("input[type=checkbox]").attr('checked', false); From dfad178a9e334776e4ba6c056523b5bd627ccace Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Mon, 6 May 2013 09:58:18 +0530 Subject: [PATCH 60/71] Bug CLOUDSTACK-1390: Allow Root/Domain admin to move a User VM to another user under a different domain Add unit tests --- client/tomcatconf/commands.properties.in | 2 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 14 ++-- .../test/com/cloud/vm/UserVmManagerTest.java | 83 ++++++++++++++++++- 3 files changed, 88 insertions(+), 11 deletions(-) diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index cdc19929c19..0a6ec708166 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -67,7 +67,7 @@ getVMPassword=15 restoreVirtualMachine=15 changeServiceForVirtualMachine=15 scaleVirtualMachine=15 -assignVirtualMachine=1 +assignVirtualMachine=7 migrateVirtualMachine=1 migrateVirtualMachineWithVolume=1 recoverVirtualMachine=7 diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 9fbc5099374..f7f5fc7ad74 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -3725,19 +3725,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use + cmd.getAccountName() + " is disabled."); } - // make sure the accounts are under same domain - if (oldAccount.getDomainId() != newAccount.getDomainId()) { - throw new InvalidParameterValueException( - "The account should be under same domain for moving VM between two accounts. Old owner domain =" - + oldAccount.getDomainId() - + " New owner domain=" - + newAccount.getDomainId()); - } + //check caller has access to both the old and new account + _accountMgr.checkAccess(caller, null, true, oldAccount); + _accountMgr.checkAccess(caller, null, true, newAccount); // make sure the accounts are not same if (oldAccount.getAccountId() == newAccount.getAccountId()) { throw new InvalidParameterValueException( - "The account should be same domain for moving VM between two accounts. Account id =" + "The new account is the same as the old account. Account id =" + oldAccount.getAccountId()); } @@ -3829,6 +3824,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); volume.setAccountId(newAccount.getAccountId()); + volume.setDomainId(newAccount.getDomainId()); _volsDao.persist(volume); _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume); _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage, diff --git a/server/test/com/cloud/vm/UserVmManagerTest.java b/server/test/com/cloud/vm/UserVmManagerTest.java index 08f2a9c2abc..dfd7465aba0 100755 --- a/server/test/com/cloud/vm/UserVmManagerTest.java +++ b/server/test/com/cloud/vm/UserVmManagerTest.java @@ -17,19 +17,26 @@ package com.cloud.vm; +import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyFloat; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.when; import java.lang.reflect.Field; import java.util.List; +import java.util.UUID; +import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd; import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd; import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd; import org.junit.Before; @@ -44,9 +51,11 @@ import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.hypervisor.Hypervisor; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.offering.ServiceOffering; import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.VMTemplateVO; @@ -57,6 +66,7 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.AccountService; import com.cloud.user.AccountVO; import com.cloud.user.UserContext; import com.cloud.user.UserVO; @@ -73,6 +83,7 @@ public class UserVmManagerTest { @Mock VolumeManager _storageMgr; @Mock Account _account; @Mock AccountManager _accountMgr; + @Mock AccountService _accountService; @Mock ConfigurationManager _configMgr; @Mock CapacityManager _capacityMgr; @Mock AccountDao _accountDao; @@ -91,6 +102,7 @@ public class UserVmManagerTest { @Mock VMTemplateVO _templateMock; @Mock VolumeVO _volumeMock; @Mock List _rootVols; + @Mock Account _accountMock2; @Before public void setup(){ MockitoAnnotations.initMocks(this); @@ -102,6 +114,7 @@ public class UserVmManagerTest { _userVmMgr._itMgr = _itMgr; _userVmMgr.volumeMgr = _storageMgr; _userVmMgr._accountDao = _accountDao; + _userVmMgr._accountService = _accountService; _userVmMgr._userDao = _userDao; _userVmMgr._accountMgr = _accountMgr; _userVmMgr._configMgr = _configMgr; @@ -370,6 +383,74 @@ public class UserVmManagerTest { return serviceOffering; } - + // Test Move VM b/w accounts where caller is not ROOT/Domain admin + @Test(expected=InvalidParameterValueException.class) + public void testMoveVmToUser1() throws Exception { + AssignVMCmd cmd = new AssignVMCmd(); + Class _class = cmd.getClass(); + + Field virtualmachineIdField = _class.getDeclaredField("virtualMachineId"); + virtualmachineIdField.setAccessible(true); + virtualmachineIdField.set(cmd, 1L); + + Field accountNameField = _class.getDeclaredField("accountName"); + accountNameField.setAccessible(true); + accountNameField.set(cmd, "account"); + + Field domainIdField = _class.getDeclaredField("domainId"); + domainIdField.setAccessible(true); + domainIdField.set(cmd, 1L); + + // caller is of type 0 + Account caller = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, + UUID.randomUUID().toString()); + UserContext.registerContext(1, caller, null, true); + + _userVmMgr.moveVMToUser(cmd); + } + + + // Test Move VM b/w accounts where caller doesn't have access to the old or new account + @Test(expected=PermissionDeniedException.class) + public void testMoveVmToUser2() throws Exception { + AssignVMCmd cmd = new AssignVMCmd(); + Class _class = cmd.getClass(); + + Field virtualmachineIdField = _class.getDeclaredField("virtualMachineId"); + virtualmachineIdField.setAccessible(true); + virtualmachineIdField.set(cmd, 1L); + + Field accountNameField = _class.getDeclaredField("accountName"); + accountNameField.setAccessible(true); + accountNameField.set(cmd, "account"); + + Field domainIdField = _class.getDeclaredField("domainId"); + domainIdField.setAccessible(true); + domainIdField.set(cmd, 1L); + + // caller is of type 0 + Account caller = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 1, + UUID.randomUUID().toString()); + UserContext.registerContext(1, caller, null, true); + + Account oldAccount = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, + UUID.randomUUID().toString()); + Account newAccount = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 1, + UUID.randomUUID().toString()); + + UserVmVO vm = new UserVmVO(10L, "test", "test", 1L, HypervisorType.Any, 1L, false, false, 1L, 1L, + 5L, "test", "test", 1L); + vm.setState(VirtualMachine.State.Stopped); + when(_vmDao.findById(anyLong())).thenReturn(vm); + + when(_accountService.getActiveAccountById(anyLong())).thenReturn(oldAccount); + + when(_accountService.getActiveAccountByName(anyString(), anyLong())).thenReturn(newAccount); + + doThrow(new PermissionDeniedException("Access check failed")).when(_accountMgr).checkAccess(any(Account.class), any(AccessType.class), + any(Boolean.class), any(ControlledEntity.class)); + + _userVmMgr.moveVMToUser(cmd); + } } \ No newline at end of file From c704c90b1163d0f3386370e75fc5903dd76498c5 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Fri, 10 May 2013 16:35:15 +0530 Subject: [PATCH 61/71] CLOUDSTACK-2035: Fix source NAT configuration with Cisco VNMC/ASA Due to VNMC limitation source nat ip cannot be assigned to ASA 1000v outside interface. Working around this issue by acquiring additional public ip during network implement and assigning that to outside interface of ASA. Also made changes to ensure that source nat policy comes after pf and static nat policies in terms of evaluation by assigning a high 'order' value for it. --- .../cisco/CiscoVnmcConnectionImpl.java | 35 ++++++++++++------- .../network/element/CiscoVnmcElement.java | 33 ++++++++++++++--- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java index 527fb04698e..714eb82a559 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java @@ -279,7 +279,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { String xml = VnmcXml.CREATE_VDC.getXml(); String service = VnmcXml.CREATE_VDC.getService(); xml = replaceXmlValue(xml, "cookie", _cookie); - xml = replaceXmlValue(xml, "descr", "VDC for Tenant" + tenantName); + xml = replaceXmlValue(xml, "descr", "VDC for Tenant " + tenantName); xml = replaceXmlValue(xml, "name", getNameForTenantVDC(tenantName)); xml = replaceXmlValue(xml, "dn", getDnForTenantVDC(tenantName)); @@ -304,7 +304,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { String xml = VnmcXml.CREATE_EDGE_DEVICE_PROFILE.getXml(); String service = VnmcXml.CREATE_EDGE_DEVICE_PROFILE.getService(); xml = replaceXmlValue(xml, "cookie", _cookie); - xml = replaceXmlValue(xml, "descr", "Edge Device Profile for Tenant VDC" + tenantName); + xml = replaceXmlValue(xml, "descr", "Edge Device Profile for Tenant VDC " + tenantName); xml = replaceXmlValue(xml, "name", getNameForEdgeDeviceServiceProfile(tenantName)); xml = replaceXmlValue(xml, "dn", getDnForTenantVDCEdgeDeviceProfile(tenantName)); @@ -407,7 +407,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { String xml = VnmcXml.CREATE_EDGE_SECURITY_PROFILE.getXml(); String service = VnmcXml.CREATE_EDGE_SECURITY_PROFILE.getService(); xml = replaceXmlValue(xml, "cookie", _cookie); - xml = replaceXmlValue(xml, "descr", "Edge Security Profile for Tenant VDC" + tenantName); + xml = replaceXmlValue(xml, "descr", "Edge Security Profile for Tenant VDC " + tenantName); xml = replaceXmlValue(xml, "name", getNameForEdgeDeviceSecurityProfile(tenantName)); xml = replaceXmlValue(xml, "espdn", getDnForTenantVDCEdgeSecurityProfile(tenantName)); xml = replaceXmlValue(xml, "egressref", "default-egress"); @@ -505,7 +505,8 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { return createTenantVDCNatPolicyRef( getDnForSourceNatPolicyRef(tenantName), getNameForSourceNatPolicy(tenantName), - tenantName); + tenantName, + true); } @Override @@ -545,7 +546,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { String xml = VnmcXml.RESOLVE_NAT_POLICY_SET.getXml(); String service = VnmcXml.RESOLVE_NAT_POLICY_SET.getService(); xml = replaceXmlValue(xml, "cookie", _cookie); - xml = replaceXmlValue(xml, "descr", "Edge Security Profile for Tenant VDC" + tenantName); + xml = replaceXmlValue(xml, "descr", "Edge Security Profile for Tenant VDC " + tenantName); xml = replaceXmlValue(xml, "name", getNameForEdgeDeviceSecurityProfile(tenantName)); xml = replaceXmlValue(xml, "espdn", getDnForTenantVDCEdgeSecurityProfile(tenantName)); xml = replaceXmlValue(xml, "natpolicysetname", getNameForNatPolicySet(tenantName)); @@ -656,7 +657,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { String xml = VnmcXml.RESOLVE_ACL_POLICY_SET.getXml(); String service = VnmcXml.RESOLVE_ACL_POLICY_SET.getService(); xml = replaceXmlValue(xml, "cookie", _cookie); - xml = replaceXmlValue(xml, "descr", "Edge Security Profile for Tenant VDC" + tenantName); + xml = replaceXmlValue(xml, "descr", "Edge Security Profile for Tenant VDC " + tenantName); xml = replaceXmlValue(xml, "name", getNameForEdgeDeviceSecurityProfile(tenantName)); xml = replaceXmlValue(xml, "espdn", getDnForTenantVDCEdgeSecurityProfile(tenantName)); //xml = replaceXmlValue(xml, "egresspolicysetname", getNameForAclPolicySet(tenantName, false)); @@ -838,17 +839,23 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { return verifySuccess(response); } - private boolean createTenantVDCNatPolicyRef(String policyRefDn, String name, String tenantName) throws ExecutionException { + private boolean createTenantVDCNatPolicyRef(String policyRefDn, String name, String tenantName, boolean isSourceNat) throws ExecutionException { String xml = VnmcXml.CREATE_NAT_POLICY_REF.getXml(); String service = VnmcXml.CREATE_NAT_POLICY_REF.getService(); xml = replaceXmlValue(xml, "cookie", _cookie); xml = replaceXmlValue(xml, "natpolicyrefdn", policyRefDn); xml = replaceXmlValue(xml, "natpolicyname", name); - List policies = listNatPolicies(tenantName); - int order = 100; - if (policies != null) { - order += policies.size(); + // PF and static NAT policies need to come before source NAT, so leaving buffer + // and creating source NAT with a high order value. + // Initially tried setting MAX_INT as the order but VNMC complains about it + int order = 10000; // TODO: For now value should be sufficient, if required may need to increase + if (!isSourceNat) { + List policies = listNatPolicies(tenantName); + order = 100; // order starts at 100 + if (policies != null) { + order += policies.size(); + } } xml = replaceXmlValue(xml, "order", Integer.toString(order)); @@ -1062,7 +1069,8 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { return createTenantVDCNatPolicyRef( getDnForPFPolicyRef(tenantName, identifier), getNameForPFPolicy(tenantName, identifier), - tenantName); + tenantName, + false); } @Override @@ -1180,7 +1188,8 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { return createTenantVDCNatPolicyRef( getDnForDNatPolicyRef(tenantName, identifier), getNameForDNatPolicy(tenantName, identifier), - tenantName); + tenantName, + false); } @Override diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java index 470c4e88217..33cc40a67da 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java @@ -70,6 +70,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.DetailVO; import com.cloud.host.Host; @@ -113,6 +114,7 @@ import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; import com.cloud.user.Account; +import com.cloud.user.UserContext; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; @@ -338,10 +340,31 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro publicGateways.add(vlanVO.getVlanGateway()); } + // due to VNMC limitation of not allowing source NAT ip as the outside ip of firewall, + // an additional public ip needs to acquired for assigning as firewall outside ip + IpAddress outsideIp = null; + try { + Account caller = UserContext.current().getCaller(); + long callerUserId = UserContext.current().getCallerUserId(); + outsideIp = _networkMgr.allocateIp(owner, false, caller, callerUserId, zone); + } catch (ResourceAllocationException e) { + s_logger.error("Unable to allocate additional public Ip address. Exception details " + e); + return false; + } + + try { + outsideIp = _networkMgr.associateIPToGuestNetwork(outsideIp.getId(), network.getId(), true); + } catch (ResourceAllocationException e) { + s_logger.error("Unable to assign allocated additional public Ip " + outsideIp.getAddress().addr() + " to network with vlan " + vlanId + ". Exception details " + e); + return false; + } + // create logical edge firewall in VNMC String gatewayNetmask = NetUtils.getCidrNetmask(network.getCidr()); + // due to ASA limitation of allowing single subnet to be assigned to firewall interfaces, + // all public ip addresses must be from same subnet, this essentially means single public subnet in zone if (!createLogicalEdgeFirewall(vlanId, network.getGateway(), gatewayNetmask, - sourceNatIp.getAddress().addr(), sourceNatIp.getNetmask(), publicGateways, ciscoVnmcHost.getId())) { + outsideIp.getAddress().addr(), sourceNatIp.getNetmask(), publicGateways, ciscoVnmcHost.getId())) { s_logger.error("Failed to create logical edge firewall in Cisco VNMC device for network " + network.getName()); return false; } @@ -356,10 +379,10 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro } // configure source NAT - //if (!configureSourceNat(vlanId, network.getCidr(), sourceNatIp, ciscoVnmcHost.getId())) { - // s_logger.error("Failed to configure source NAT in Cisco VNMC device for network " + network.getName()); - // return false; - //} + if (!configureSourceNat(vlanId, network.getCidr(), sourceNatIp, ciscoVnmcHost.getId())) { + s_logger.error("Failed to configure source NAT in Cisco VNMC device for network " + network.getName()); + return false; + } // associate Asa 1000v instance with logical edge firewall if (!associateAsaWithLogicalEdgeFirewall(vlanId, assignedAsa.getManagementIp(), ciscoVnmcHost.getId())) { From edd2fbb266d316fc130520876dfb2f7152223d37 Mon Sep 17 00:00:00 2001 From: Pranav Saxena Date: Fri, 10 May 2013 16:47:09 +0530 Subject: [PATCH 62/71] CLOUDSTACK-760:Allow ACL on all layer 4 protocols --- ui/scripts/vpc.js | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/ui/scripts/vpc.js b/ui/scripts/vpc.js index db964e6ffcd..dc26265c232 100644 --- a/ui/scripts/vpc.js +++ b/ui/scripts/vpc.js @@ -48,6 +48,22 @@ return name != 'icmptype' && name != 'icmpcode' && name != 'cidrlist'; }); + var $protocolinput = args.$form.find('th,td'); + var $protocolFields = $protocolinput.filter(function(){ + var name = $(this).attr('rel'); + + return $.inArray(name,['protocolnumber']) > -1; + }); + + if($(this).val() == 'protocolnumber' ){ + + $protocolFields.show(); + } + else{ + $protocolFields.hide(); + } + + if ($(this).val() == 'icmp') { $icmpFields.show(); $icmpFields.attr('disabled', false); @@ -68,11 +84,16 @@ data: [ { name: 'tcp', description: 'TCP' }, { name: 'udp', description: 'UDP' }, - { name: 'icmp', description: 'ICMP' } + { name: 'icmp', description: 'ICMP' }, + { name: 'all', description: 'ALL'}, + { name: 'protocolnumber', description: 'Protocol Number'} + ] }); } }, + + 'protocolnumber': {label:'Protocol Number',isDisabled:true,isHidden:true,edit:true}, 'startport': { edit: true, label: 'label.start.port' }, 'endport': { edit: true, label: 'label.end.port' }, 'networkid': { @@ -136,7 +157,15 @@ label: 'label.add', action: function(args) { var $multi = args.$multi; - + //Support for Protocol Number between 0 to 255 + if(args.data.protocol == 'protocolnumber'){ + $.extend(args.data,{protocol:args.data.protocolnumber}); + delete args.data.protocolnumber; + } + else + delete args.data.protocolnumber; + + $.ajax({ url: createURL('createNetworkACL'), data: $.extend(args.data, { From b4aff6190f741cffa0bd945cfa9d7d7b11ada47b Mon Sep 17 00:00:00 2001 From: Kishan Kavala Date: Fri, 10 May 2013 17:27:10 +0530 Subject: [PATCH 63/71] CLOUDSTACK-2309: Add fix to handle Vmware 4.0 template upgrade --- .../com/cloud/upgrade/dao/Upgrade302to40.java | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade302to40.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade302to40.java index 753f64ec682..ecda872dfa4 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade302to40.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade302to40.java @@ -63,6 +63,7 @@ public class Upgrade302to40 extends Upgrade30xBase implements DbUpgrade { @Override public void performDataMigration(Connection conn) { + updateVmWareSystemVms(conn); correctVRProviders(conn); correctMultiplePhysicaNetworkSetups(conn); addHostDetailsUniqueKey(conn); @@ -82,7 +83,55 @@ public class Upgrade302to40 extends Upgrade30xBase implements DbUpgrade { return new File[] { new File(script) }; } - + + private void updateVmWareSystemVms(Connection conn){ + PreparedStatement pstmt = null; + ResultSet rs = null; + boolean VMware = false; + try { + pstmt = conn.prepareStatement("select distinct(hypervisor_type) from `cloud`.`cluster` where removed is null"); + rs = pstmt.executeQuery(); + while(rs.next()){ + if("VMware".equals(rs.getString(1))){ + VMware = true; + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while iterating through list of hypervisors in use", e); + } + // Just update the VMware system template. Other hypervisor templates are unchanged from previous 3.0.x versions. + s_logger.debug("Updating VMware System Vms"); + try { + //Get 4.0 VMware system Vm template Id + pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-vmware-4.0' and removed is null"); + rs = pstmt.executeQuery(); + if(rs.next()){ + long templateId = rs.getLong(1); + rs.close(); + pstmt.close(); + // change template type to SYSTEM + pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + // update templete ID of system Vms + pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'VMware'"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + } else { + if (VMware){ + throw new CloudRuntimeException("4.0 VMware SystemVm template not found. Cannot upgrade system Vms"); + } else { + s_logger.warn("4.0 VMware SystemVm template not found. VMware hypervisor is not used, so not failing upgrade"); + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while updating VMware systemVm template", e); + } + s_logger.debug("Updating System Vm Template IDs Complete"); + } + private void correctVRProviders(Connection conn) { PreparedStatement pstmtVR = null; ResultSet rsVR = null; From 530b0beb3c8b172fbfaf89584cd24785b7513998 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Fri, 10 May 2013 17:54:59 +0530 Subject: [PATCH 64/71] CLOUDSTACK-2417: NPE while creating Egress rules with Networking using Cisco ASA firewall provider An input parameter was incorrectly interpreted during egress rule creation and so resulted in NPE. Created a new vnmc xml for handling creation of egress rule with protocol as 'All' --- .../network/cisco/create-egress-acl-rule.xml | 53 ++--------- ...te-generic-egress-acl-no-protocol-rule.xml | 94 +++++++++++++++++++ .../cisco/create-generic-egress-acl-rule.xml | 1 - .../network/cisco/create-ingress-acl-rule.xml | 43 +-------- .../network/cisco/CiscoVnmcConnection.java | 10 +- .../cisco/CiscoVnmcConnectionImpl.java | 30 +++--- .../network/element/CiscoVnmcElement.java | 9 +- .../network/resource/CiscoVnmcResource.java | 12 +-- .../resource/CiscoVnmcResourceTest.java | 4 +- 9 files changed, 144 insertions(+), 112 deletions(-) create mode 100755 plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-egress-acl-no-protocol-rule.xml diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-egress-acl-rule.xml b/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-egress-acl-rule.xml index 930272ed8ee..05c066d6d53 100755 --- a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-egress-acl-rule.xml +++ b/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-egress-acl-rule.xml @@ -118,70 +118,38 @@ under the License. - - - - - - - - - - - - - - + + value="%deststartport%"/> - + + value="%destendport%"/> @@ -195,7 +163,6 @@ under the License. protocolvalue = "TCP" or "UDP" deststartip="destination start ip" destendip="destination end ip" - sourcestartport="start port at source" - sourceendport="end port at source" - sourceip="source ip" + deststartport="start port at destination" + destendport="end port at destination" --!> diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-egress-acl-no-protocol-rule.xml b/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-egress-acl-no-protocol-rule.xml new file mode 100755 index 00000000000..17cfa54a34e --- /dev/null +++ b/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-egress-acl-no-protocol-rule.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-egress-acl-rule.xml b/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-egress-acl-rule.xml index 92c25043dad..436e3eae790 100755 --- a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-egress-acl-rule.xml +++ b/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-egress-acl-rule.xml @@ -118,5 +118,4 @@ under the License. protocolvalue = "TCP" or "UDP" or "ICMP" deststartip="destination start ip" destendip="destination end ip" - sourceip="source ip" --!> diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-ingress-acl-rule.xml b/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-ingress-acl-rule.xml index 1af30b44416..f283ffeb333 100755 --- a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-ingress-acl-rule.xml +++ b/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-ingress-acl-rule.xml @@ -118,7 +118,7 @@ under the License. @@ -127,56 +127,24 @@ under the License. dn="%aclruledn%/rule-cond-4/nw-expr2/nw-attr-qual" status="created"/> - - - - - - - - - - - - - - + - + diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnection.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnection.java index f137148ab48..fed6724418d 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnection.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnection.java @@ -140,23 +140,23 @@ public interface CiscoVnmcConnection { public boolean createTenantVDCIngressAclRule(String tenantName, String identifier, String policyIdentifier, String protocol, String sourceStartIp, String sourceEndIp, - String destStartPort, String destEndPort, String destIp) + String destStartPort, String destEndPort) throws ExecutionException; public boolean createTenantVDCIngressAclRule(String tenantName, String identifier, String policyIdentifier, - String protocol, String sourceStartIp, String sourceEndIp, String destIp) + String protocol, String sourceStartIp, String sourceEndIp) throws ExecutionException; public boolean createTenantVDCEgressAclRule(String tenantName, String identifier, String policyIdentifier, - String protocol, String sourceStartPort, String sourceEndPort, String sourceIp, - String destStartIp, String destEndIp) + String protocol, String destStartIp, String destEndIp, + String destStartPort, String destEndPort) throws ExecutionException; public boolean createTenantVDCEgressAclRule(String tenantName, String identifier, String policyIdentifier, - String protocol, String sourceIp, String destStartIp, String destEndIp) + String protocol, String destStartIp, String destEndIp) throws ExecutionException; public boolean deleteTenantVDCAclRule(String tenantName, diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java index 714eb82a559..c7380ab11d8 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java @@ -95,6 +95,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { CREATE_EGRESS_ACL_RULE("create-egress-acl-rule.xml", "policy-mgr"), CREATE_GENERIC_INGRESS_ACL_RULE("create-generic-ingress-acl-rule.xml", "policy-mgr"), CREATE_GENERIC_EGRESS_ACL_RULE("create-generic-egress-acl-rule.xml", "policy-mgr"), + CREATE_GENERIC_EGRESS_ACL_NO_PROTOCOL_RULE("create-generic-egress-acl-no-protocol-rule.xml", "policy-mgr"), DELETE_RULE("delete-rule.xml", "policy-mgr"), @@ -660,8 +661,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { xml = replaceXmlValue(xml, "descr", "Edge Security Profile for Tenant VDC " + tenantName); xml = replaceXmlValue(xml, "name", getNameForEdgeDeviceSecurityProfile(tenantName)); xml = replaceXmlValue(xml, "espdn", getDnForTenantVDCEdgeSecurityProfile(tenantName)); - //xml = replaceXmlValue(xml, "egresspolicysetname", getNameForAclPolicySet(tenantName, false)); - xml = replaceXmlValue(xml, "egresspolicysetname", "default-egress"); + xml = replaceXmlValue(xml, "egresspolicysetname", getNameForAclPolicySet(tenantName, false)); xml = replaceXmlValue(xml, "ingresspolicysetname", getNameForAclPolicySet(tenantName, true)); xml = replaceXmlValue(xml, "natpolicysetname", getNameForNatPolicySet(tenantName)); @@ -673,7 +673,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { public boolean createTenantVDCIngressAclRule(String tenantName, String identifier, String policyIdentifier, String protocol, String sourceStartIp, String sourceEndIp, - String destStartPort, String destEndPort, String destIp) throws ExecutionException { + String destStartPort, String destEndPort) throws ExecutionException { String xml = VnmcXml.CREATE_INGRESS_ACL_RULE.getXml(); String service = VnmcXml.CREATE_INGRESS_ACL_RULE.getService(); @@ -687,7 +687,6 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { xml = replaceXmlValue(xml, "sourceendip", sourceEndIp); xml = replaceXmlValue(xml, "deststartport", destStartPort); xml = replaceXmlValue(xml, "destendport", destEndPort); - xml = replaceXmlValue(xml, "destip", destIp); List rules = listChildren(getDnForAclPolicy(tenantName, policyIdentifier)); int order = 100; @@ -703,8 +702,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { @Override public boolean createTenantVDCIngressAclRule(String tenantName, String identifier, String policyIdentifier, - String protocol, String sourceStartIp, String sourceEndIp, - String destIp) throws ExecutionException { + String protocol, String sourceStartIp, String sourceEndIp) throws ExecutionException { String xml = VnmcXml.CREATE_GENERIC_INGRESS_ACL_RULE.getXml(); String service = VnmcXml.CREATE_GENERIC_INGRESS_ACL_RULE.getService(); @@ -731,8 +729,8 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { @Override public boolean createTenantVDCEgressAclRule(String tenantName, String identifier, String policyIdentifier, - String protocol, String sourceStartPort, String sourceEndPort, String sourceIp, - String destStartIp, String destEndIp) throws ExecutionException { + String protocol, String destStartIp, String destEndIp, + String destStartPort, String destEndPort) throws ExecutionException { String xml = VnmcXml.CREATE_EGRESS_ACL_RULE.getXml(); String service = VnmcXml.CREATE_EGRESS_ACL_RULE.getService(); @@ -744,9 +742,8 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { xml = replaceXmlValue(xml, "protocolvalue", protocol); xml = replaceXmlValue(xml, "deststartip", destStartIp); xml = replaceXmlValue(xml, "destendip", destEndIp); - xml = replaceXmlValue(xml, "sourcestartport", sourceStartPort); - xml = replaceXmlValue(xml, "sourceendport", sourceEndPort); - xml = replaceXmlValue(xml, "sourceip", sourceIp); + xml = replaceXmlValue(xml, "deststartport", destStartPort); + xml = replaceXmlValue(xml, "destendport", destEndPort); List rules = listChildren(getDnForAclPolicy(tenantName, policyIdentifier)); int order = 100; @@ -762,17 +759,20 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { @Override public boolean createTenantVDCEgressAclRule(String tenantName, String identifier, String policyIdentifier, - String protocol, String sourceIp, - String destStartIp, String destEndIp) throws ExecutionException { + String protocol, String destStartIp, String destEndIp) throws ExecutionException { String xml = VnmcXml.CREATE_GENERIC_EGRESS_ACL_RULE.getXml(); String service = VnmcXml.CREATE_GENERIC_EGRESS_ACL_RULE.getService(); - + if (protocol.equalsIgnoreCase("all")) { // any protocol + xml = VnmcXml.CREATE_GENERIC_EGRESS_ACL_NO_PROTOCOL_RULE.getXml(); + service = VnmcXml.CREATE_GENERIC_EGRESS_ACL_NO_PROTOCOL_RULE.getService(); + } else { // specific protocol + xml = replaceXmlValue(xml, "protocolvalue", protocol); + } xml = replaceXmlValue(xml, "cookie", _cookie); xml = replaceXmlValue(xml, "aclruledn", getDnForAclRule(tenantName, identifier, policyIdentifier)); xml = replaceXmlValue(xml, "aclrulename", getNameForAclRule(tenantName, identifier)); xml = replaceXmlValue(xml, "descr", "Egress ACL rule for Tenant VDC " + tenantName); xml = replaceXmlValue(xml, "actiontype", "permit"); - xml = replaceXmlValue(xml, "protocolvalue", protocol); xml = replaceXmlValue(xml, "deststartip", destStartIp); xml = replaceXmlValue(xml, "destendip", destEndIp); diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java index 33cc40a67da..b335edb9f63 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java @@ -105,6 +105,7 @@ import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; import com.cloud.network.resource.CiscoVnmcResource; import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRule.TrafficType; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.StaticNat; import com.cloud.offering.NetworkOffering; @@ -677,8 +678,12 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro List rulesTO = new ArrayList(); for (FirewallRule rule : rules) { - IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId()); - FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr(), rule.getPurpose(), rule.getTrafficType()); + String address = "0.0.0.0"; + if (rule.getTrafficType() == TrafficType.Ingress) { + IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId()); + address = sourceIp.getAddress().addr(); + } + FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, address, rule.getPurpose(), rule.getTrafficType()); rulesTO.add(ruleTO); } diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java index 91559782304..906e0ae6e85 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java @@ -368,29 +368,29 @@ public class CiscoVnmcResource implements ServerResource { if (!_connection.createTenantVDCIngressAclRule(tenant, Long.toString(rule.getId()), policyIdentifier, rule.getProtocol().toUpperCase(), externalIpRange[0], externalIpRange[1], - Integer.toString(rule.getSrcPortRange()[0]), Integer.toString(rule.getSrcPortRange()[1]), publicIp)) { + Integer.toString(rule.getSrcPortRange()[0]), Integer.toString(rule.getSrcPortRange()[1]))) { throw new Exception("Failed to create ACL ingress rule in VNMC for guest network with vlan " + vlanId); } } else { if (!_connection.createTenantVDCIngressAclRule(tenant, Long.toString(rule.getId()), policyIdentifier, - rule.getProtocol().toUpperCase(), externalIpRange[0], externalIpRange[1], publicIp)) { + rule.getProtocol().toUpperCase(), externalIpRange[0], externalIpRange[1])) { throw new Exception("Failed to create ACL ingress rule in VNMC for guest network with vlan " + vlanId); } } } else { - if (!rule.getProtocol().equalsIgnoreCase("icmp")) { + if (rule.getProtocol().equalsIgnoreCase("tcp") || rule.getProtocol().equalsIgnoreCase("udp")) { if (!_connection.createTenantVDCEgressAclRule(tenant, Long.toString(rule.getId()), policyIdentifier, rule.getProtocol().toUpperCase(), - Integer.toString(rule.getSrcPortRange()[0]), Integer.toString(rule.getSrcPortRange()[1]), publicIp, - externalIpRange[0], externalIpRange[1])) { + externalIpRange[0], externalIpRange[1], + Integer.toString(rule.getSrcPortRange()[0]), Integer.toString(rule.getSrcPortRange()[1]))) { throw new Exception("Failed to create ACL egress rule in VNMC for guest network with vlan " + vlanId); } } else { if (!_connection.createTenantVDCEgressAclRule(tenant, Long.toString(rule.getId()), policyIdentifier, - rule.getProtocol().toUpperCase(), publicIp, externalIpRange[0], externalIpRange[1])) { + rule.getProtocol().toUpperCase(), externalIpRange[0], externalIpRange[1])) { throw new Exception("Failed to create ACL egress rule in VNMC for guest network with vlan " + vlanId); } } diff --git a/plugins/network-elements/cisco-vnmc/test/com/cloud/network/resource/CiscoVnmcResourceTest.java b/plugins/network-elements/cisco-vnmc/test/com/cloud/network/resource/CiscoVnmcResourceTest.java index e814fdcd4d5..acfc5ebaaa7 100755 --- a/plugins/network-elements/cisco-vnmc/test/com/cloud/network/resource/CiscoVnmcResourceTest.java +++ b/plugins/network-elements/cisco-vnmc/test/com/cloud/network/resource/CiscoVnmcResourceTest.java @@ -171,11 +171,11 @@ public class CiscoVnmcResourceTest { when(_connection.createTenantVDCIngressAclRule( anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), - anyString(), anyString(), anyString())).thenReturn(true); + anyString(), anyString())).thenReturn(true); when(_connection.createTenantVDCEgressAclRule( anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), - anyString(), anyString(), anyString())).thenReturn(true); + anyString(), anyString())).thenReturn(true); when(_connection.associateAclPolicySet(anyString())).thenReturn(true); Answer answer = _resource.executeRequest(cmd); From da74554ba1cce53a939d115cab04ce965b68617b Mon Sep 17 00:00:00 2001 From: Radhika PC Date: Fri, 10 May 2013 18:26:10 +0530 Subject: [PATCH 65/71] CLOUDSTACK-893 conceptual info around gslb --- .../external-firewalls-and-load-balancers.xml | 1 + docs/en-US/gslb.xml | 678 +++++++++++------- docs/en-US/images/gslb.png | Bin 184080 -> 60354 bytes docs/en-US/networks.xml | 3 +- 4 files changed, 438 insertions(+), 244 deletions(-) diff --git a/docs/en-US/external-firewalls-and-load-balancers.xml b/docs/en-US/external-firewalls-and-load-balancers.xml index b947daf7361..42ecacf9f75 100644 --- a/docs/en-US/external-firewalls-and-load-balancers.xml +++ b/docs/en-US/external-firewalls-and-load-balancers.xml @@ -29,5 +29,6 @@ xmlns:xi="http://www.w3.org/2001/XInclude"/> +
    diff --git a/docs/en-US/gslb.xml b/docs/en-US/gslb.xml index ac17d61d69c..23033317381 100644 --- a/docs/en-US/gslb.xml +++ b/docs/en-US/gslb.xml @@ -26,7 +26,7 @@ achieve this by extending its functionality of integrating with NetScaler Application Delivery Controller (ADC), which also provides various GSLB capabilities, such as disaster recovery and load balancing. The DNS redirection technique is used to achieve GSLB in &PRODUCT;. - In order to support his functionality, region level services and service provider are + In order to support this functionality, region level services and service provider are introduced. A new service 'GSLB' is introduced as a region level service. The GSLB service provider is introduced that will provider the GSLB service. Currently, NetScaler is the supported GSLB provider in &PRODUCT;. GSLB functionality works in an Active-Active data center @@ -40,264 +40,456 @@ multiple data centers situated at geographically separated locations. GSLB can also provide an alternate location for accessing a resource in the event of a failure, or to provide a means of shifting traffic easily to simplify maintenance, or both. - -
    - Components of GSLB - A typical GSLB environment is comprised of the following components: - - - GSLB Site: In &PRODUCT;terminology, GSLB sites are - represented by zones that are mapped to data centers, each of which has various network - appliances. Each GSLB site is managed by a NetScaler appliance that is local to that site. - Each of these appliances treats its own site as the local site and all other sites, - managed by other appliances, as remote sites. - - - GSLB Services: A GSLB service is typically - represented by a load balancing or content switching virtual server. In a GSLB - environment, you can have a local as well as remote GSLB services. A local GSLB service - represents a local load balancing or content switching virtual server. A remote GSLB - service is the one configured at one of the other sites in the GSLB setup. At each site in - the GSLB setup, you can create one local GSLB service and any number of remote GSLB - services. - - - GSLB Virtual Servers: A GSLB virtual server refers to - one or more GSLB services and balances traffic between traffic across the VMs in multiple - zones by using the &PRODUCT; functionality. It evaluates the configured GSLB methods or - algorithms to select a GSLB service to which to send the client requests. One or more - virtual servers from different zones are bound to the GSLB virtual server. GSLB virtual - server does not have a public IP associated with it, instead it will have a FQDN DNS - name. - - - Load Balancing or Content Switching Virtual Servers: - According to Citrix NetScaler terminology, a load balancing or content switching virtual - server represents one or many servers on the local network. Clients send their requests to - the load balancing or content switching virtual server’s virtual IP (VIP) address, and the - virtual server balances the load across the local servers. After a GSLB virtual server - selects a GSLB service representing either a local or a remote load balancing or content - switching virtual server, the client sends the request to that virtual server’s VIP - address. - - - DNS VIPs: DNS virtual IP represents a load balancing - DNS virtual server on the GSLB service provider. The DNS requests for domains for which - the GSLB service provider is authoritative can be sent to a DNS VIP. - - - ADNS: ADNS (Authoritative Domain Name Server) is a - service that provides actual answer to DNS queries, such as web site IP address. In a GSLB - environment, an ADNS service responds only to DNS requests for domains for which the GSLB - service provider is authoritative. When an ADNS service is configured, the service - provider owns that IP address and advertises it. When you create an ADNS service, the - NetScaler responds to DNS queries on the configured ADNS service IP and port. - - -
    -
    - Prerequisites and Guidelines - - - The GSLB functionality is supported both Basic and Advanced zones. - - - GSLB is added as a new network service. - - - GSLB service provider can be added to a physical network in a zone. - - - The admin is allowed to enable or disable GSLB functionality at region level. - - - The admin is allowed to configure a zone as GSLB capable or enabled. - A zone shall be considered as GSLB capable only if a GSLB service provider is - provisioned in the zone. - - - When users have VMs deployed in multiple availability zones which are GSLB enabled, - they can use the GSLB functionality to load balance traffic across the VMs in multiple - zones. - - - The users can use GSLB to load balance across the VMs across zones in a region only if - the admin has enabled GSLB in that region. - - - The users can load balance traffic across the availability zones in the same region or - different regions. - - - The admin can configure DNS name for the entire cloud. - - - The users can specify an unique name across the cloud for a globally load balanced - service. The provided name is used as the domain name under the DNS name associated with - the cloud. - The user-provided name along with the admin-provided DNS name is used to produce a - globally resolvable FQDN for the globally load balanced service of the user. For example, - if the admin has configured xyztelco.com as the DNS name for the cloud, and user specifies - 'foo' for the GSLB virtual service, then the FQDN name of the GSLB virtual service is - foo.xyztelco.com. - - - While setting up GSLB, users can select a load balancing method, such as round robin, - for using across the zones that are part of GSLB. - - - The user shall be able to set weight to zone-level virtual server. Weight shall be - considered by the load balancing method for distributing the traffic. - - - The GSLB functionality shall support session persistence, where series of client - requests for particular domain name is sent to a virtual server on the same zone. - Statistics is collected from each GSLB virtual server. - - +
    + Components of GSLB + A typical GSLB environment is comprised of the following components: + + + GSLB Site: In &PRODUCT;terminology, GSLB sites are + represented by zones that are mapped to data centers, each of which has various network + appliances. Each GSLB site is managed by a NetScaler appliance that is local to that + site. Each of these appliances treats its own site as the local site and all other + sites, managed by other appliances, as remote sites. It is the central entity in a GSLB + deployment, and is represented by a name and an IP address. + + + GSLB Services: A GSLB service is typically + represented by a load balancing or content switching virtual server. In a GSLB + environment, you can have a local as well as remote GSLB services. A local GSLB service + represents a local load balancing or content switching virtual server. A remote GSLB + service is the one configured at one of the other sites in the GSLB setup. At each site + in the GSLB setup, you can create one local GSLB service and any number of remote GSLB + services. + + + GSLB Virtual Servers: A GSLB virtual server refers + to one or more GSLB services and balances traffic between traffic across the VMs in + multiple zones by using the &PRODUCT; functionality. It evaluates the configured GSLB + methods or algorithms to select a GSLB service to which to send the client requests. One + or more virtual servers from different zones are bound to the GSLB virtual server. GSLB + virtual server does not have a public IP associated with it, instead it will have a FQDN + DNS name. + + + Load Balancing or Content Switching Virtual + Servers: According to Citrix NetScaler terminology, a load balancing or + content switching virtual server represents one or many servers on the local network. + Clients send their requests to the load balancing or content switching virtual server’s + virtual IP (VIP) address, and the virtual server balances the load across the local + servers. After a GSLB virtual server selects a GSLB service representing either a local + or a remote load balancing or content switching virtual server, the client sends the + request to that virtual server’s VIP address. + + + DNS VIPs: DNS virtual IP represents a load + balancing DNS virtual server on the GSLB service provider. The DNS requests for domains + for which the GSLB service provider is authoritative can be sent to a DNS VIP. + + + Authoritative DNS: ADNS (Authoritative Domain Name + Server) is a service that provides actual answer to DNS queries, such as web site IP + address. In a GSLB environment, an ADNS service responds only to DNS requests for + domains for which the GSLB service provider is authoritative. When an ADNS service is + configured, the service provider owns that IP address and advertises it. When you create + an ADNS service, the NetScaler responds to DNS queries on the configured ADNS service IP + and port. + + +
    +
    + How Does GSLB Works in &PRODUCT;? + Global server load balancing is used to manage the traffic flow to a web site hosted on + two separate zones that ideally are in different geographic locations. The following is an + illustration of how GLSB functionality is provided in &PRODUCT;: An organization, xyztelco, + has set up a public cloud that spans two zones, Zone-1 and Zone-2, across geographically + separated data centers that are managed by &PRODUCT;. Tenant-A of the cloud launches a + highly available solution by using xyztelco cloud. For that purpose, they launch two + instances each in both the zones: VM1 and VM2 in Zone-1 and VM5 and VM6 in Zone-2. Tenant-A + acquires a public IP, IP-1 in Zone-1, and configures a load balancer rule to load balance + the traffic between VM1 and VM2 instances. &PRODUCT; orchestrates setting up a virtual + server on the LB service provider in Zone-1. Virtual server 1 that is set up on the LB + service provider in Zone-1 represents a publicly accessible virtual server that client + reaches at IP-1. The client traffic to virtual server 1 at IP-1 will be load balanced across + VM1 and VM2 instances. + Tenant-A acquires another public IP, IP-2 in Zone-2 and sets up a load balancer rule to + load balance the traffic between VM5 and VM6 instances. Similarly in Zone-2, &PRODUCT; + orchestrates setting up a virtual server on the LB service provider. Virtual server 2 that + is setup on the LB service provider in Zone-2 represents a publicly accessible virtual + server that client reaches at IP-2. The client traffic that reaches virtual server 2 at IP-2 + is load balanced across VM5 and VM6 instances. At this point Tenant-A has the service + enabled in both the zones, but has no means to set up a disaster recovery plan if one of the + zone fails. Additionally, there is no way for Tenant-A to load balance the traffic + intelligently to one of the zones based on load, proximity and so on. The cloud + administrator of xyztelco provisions a GSLB service provider to both the zones. A GSLB + provider is typically an ADC that has the ability to act as an ADNS (Authoritative Domain + Name Server) and has the mechanism to monitor health of virtual servers both at local and + remote sites. The cloud admin enables GSLB as a service to the tenants that use zones 1 and + 2. + + + + + + gslb.png: GSLB architecture + + + Tenant-A wishes to leverage the GSLB service provided by the xyztelco cloud. Tenant-A + configures a GSLB rule to load balance traffic across virtual server 1 at Zone-1 and virtual + server 2 at Zone-2. The domain name is provided as A.xyztelco.com. &PRODUCT; orchestrates + setting up GSLB virtual server 1 on the GSLB service provider at Zone-1. &PRODUCT; binds + virtual server 1 of Zone-1 and virtual server 2 of Zone-2 to GLSB virtual server 1. GSLB + virtual server 1 is configured to start monitoring the health of virtual server 1 and 2 in + Zone-1. &PRODUCT; will also orchestrate setting up GSLB virtual server 2 on GSLB service + provider at Zone-2. &PRODUCT; will bind virtual server 1 of Zone-1 and virtual server 2 of + Zone-2 to GLSB virtual server 2. GSLB virtual server 2 is configured to start monitoring the + health of virtual server 1 and 2. &PRODUCT; will bind the domain A.xyztelco.com to both the + GSLB virtual server 1 and 2. At this point, Tenant-A service will be globally reachable at + A.xyztelco.com. The private DNS server for the domain xyztelcom.com is configured by the + admin out-of-band to resolve the domain A.xyztelco.com to the GSLB providers at both the + zones, which are configured as ADNS for the domain A.xyztelco.com. A client when sends a DNS + request to resolve A.xyztelcom.com, will eventually get DNS delegation to the address of + GSLB providers at zone 1 and 2. A client DNS request will be received by the GSLB provider. + The GSLB provider, depending on the domain for which it needs to resolve, will pick up the + GSLB virtual server associated with the domain. Depending on the health of the virtual + servers being load balanced, DNS request for the domain will be resolved to the public IP + associated with the selected virtual server. +
    Configuring GSLB + A GSLB deployment is the logical collection of GSLB virtual server, GSLB service, LB + virtual server, service, domain, and ADNS service. To create a GSLB site, you must configure + load balancing in the zone. You must create GSLB vservers and GSLB services for each site. You + must bind GSLB services to GSLB vservers. You must then create an ADNS service that provides + the IP address of the best performing site to the client's request. A GSLB vserver is an + entity that performs load balancing for the domains bound to it by returning the IP address of + the best GSLB service. A GSLB service is a representation of the load balancing/content + switching vserver. An LB vserver load balances incoming traffic by identifying the best + server, then directs traffic to the corresponding service. It can also load-balance external + DNS name servers. Services are entities that represent the servers. The domain is the domain + name for which the system is the authoritative DNS server. By creating an ADNS service, the + system can be configured as an authoritative DNS server. To configure GSLB in your cloud environment, as a cloud administrator you must perform the following. To configure such a GSLB setup, you must first configure a standard load balancing setup - for each server farm or data center. This enables you to balance load across the different - servers in each server farm. Then, configure both NetScaler appliances as authoritative DNS - (ADNS) servers. Next, create a GSLB site for each server farm, configure GSLB virtual servers - for each site, create GLSB services, and bind the GSLB services to the GSLB virtual servers. - Finally, bind the domain to the GSLB virtual servers. The GSLB configurations on the two - appliances at the two different sites are identical, although each sites load-balancing - configuration is specific to that site. + for each zone. This enables you to balance load across the different servers in each zone in + the region. Then, configure both NetScaler appliances that you plan to add to each zone as + authoritative DNS (ADNS) servers. Next, create a GSLB site for each zone, configure GSLB + virtual servers for each site, create GLSB services, and bind the GSLB services to the GSLB + virtual servers. Finally, bind the domain to the GSLB virtual servers. The GSLB configurations + on the two appliances at the two different sites are identical, although each sites + load-balancing configuration is specific to that site. + Perform the following as a cloud administrator. As per the above example, the + administrator of xyztelco is the one who sets up GSLB: - + In the cloud.dns.name global parameter, specify the DNS name of your tenant's cloud + that make use of the GSLB service. + + + On the NetScaler side, configure GSLB as given in Configuring Global Server Load Balancing (GSLB): + + + Configuring a standard load balancing setup. + + + Configure Authoritative DNS, as explained in Configuring an Authoritative DNS Service. + + + Configure a GSLB site with site name formed from the domain name details. + For more information, see Configuring a Basic GSLB Site. + + + Configure a GSLB virtual server. + For more information, see Configuring a GSLB Virtual Server. + + + Configure a GSLB service for each virtual server. + For more information, see Configuring a GSLB Service. + + + Bind the GSLB services to the GSLB virtual server. + For more information, see Binding GSLB Services to a GSLB Virtual Server. + + + Bind domain name to GSLB virtual server. Domain name is obtained from the domain + details. + For more information, see Binding a Domain to a GSLB Virtual Server. + + + + + In each zone that are participating in GSLB, add GSLB-enabled NetScaler device. + For more information, see . -
    -
    - Adding a GSLB Rule + As a domain administrator/ user perform the following: - Log in to the &PRODUCT; UI as administrator. + Add a GSLB rule on both the sites. + See . - In the left navigation pane, click Region. - - - Select the region for which you want to create a GSLB rule. - - - In the Details tab, click View GSLB. - - - Click Add GSLB. - The Add GSLB page is displayed as follows: - - - - - - gslb-add.png: adding a gslb rule - - - - - Specify the following: - - - Name: Name for the GSLB rule. - - - Description: (Optional) A short description of - the GSLB rule that can be displayed to users. - - - GSLB Domain Name: A preferred domain name for the - service. - - - Algorithm: (Optional) The algorithm to use to - load balance the traffic across the zones. The options are Round Robin, Least - Connection, and Proximity. - - - Service Type: The transport protocol to use for - GSLB. The options are TCP and UDP. - - - Domain: (Optional) The domain for which you want - to create the GSLB rule. - - - Account: (Optional) The account on which you want - to apply the GSLB rule. - - - - - Click OK to confirm. + Assign load balancer rules. + See . -
    -
    - Assigning Load Balancing Rules to GSLB - -
    -
    - How Does GSLB Works in &PRODUCT;? - Global server load balancing is used to manage traffic flow to a web site hosted on two - separate zones that ideally are in different geographic locations. The following is an - illustration of how GLSB functionality is provided in &PRODUCT;: An organization, xyztelco, - has set up a public cloud that spans two zones, Zone-1 and Zone-2, across geographically - separated data centers that are managed by &PRODUCT;. Tenant-A of the cloud launches a highly - available solution by using xyztelco cloud. For that purpose, they launch two instances each - in both the zones: VM1 and VM2 in Zone-1 and VM5 and VM6 in Zone-2. Tenant-A acquires a public - IP, IP-1 in Zone-1, and configures a load balancer rule to load balance the traffic between - VM1 and VM2 instances. &PRODUCT; orchestrates setting up a virtual server on the LB service - provider in Zone-1. Virtual server 1 that is set up on the LB service provider in Zone-1 - represents a publicly accessible virtual server that client reaches at IP-1. The client - traffic to virtual server 1 at IP-1 will be load balanced across VM1 and VM2 instances. - Tenant-A acquires another public IP, IP-2 in Zone-2 and sets up a load balancer rule to - load balance the traffic between VM5 and VM6 instances. Similarly in Zone-2, &PRODUCT; - orchestrates setting up a virtual server on the LB service provider. Virtual server 2 that is - setup on the LB service provider in Zone-2 represents a publicly accessible virtual server - that client reaches at IP-2. The client traffic that reaches virtual server 2 at IP-2 is load - balanced across VM5 and VM6 instances. At this point Tenant-A has the service enabled in both - the zones, but has no means to set up a disaster recovery plan if one of the zone fails. - Additionally, there is no way for Tenant-A to load balance the traffic intelligently to one of - the zones based on load, proximity and so on. The cloud administrator of xyztelco provisions a - GSLB service provider to both the zones. A GSLB provider is typically an ADC that has the - ability to act as an ADNS (Authoritative Domain Name Server) and has the mechanism to monitor - health of virtual servers both at local and remote sites. The cloud admin enables GSLB as a - service to the tenants that use zones 1 and 2. - - - - - - gslb.png: GSLB architecture - - - Tenant-A wishes to leverage the GSLB service provided by the xyztelco cloud. Tenant-A - configures a GSLB rule to load balance traffic across virtual server 1 at Zone-1 and virtual - server 2 at Zone-2. The domain name is provided as A.xyztelco.com. &PRODUCT; orchestrates - setting up GSLB virtual server 1 on the GSLB service provider at Zone-1. &PRODUCT; binds - virtual server 1 of Zone-1 and virtual server 2 of Zone-2 to GLSB virtual server 1. GSLB - virtual server 1 is configured to start monitoring the health of virtual server 1 and 2 in - Zone-1. &PRODUCT; will also orchestrate setting up GSLB virtual server 2 on GSLB service - provider at Zone-2. &PRODUCT; will bind virtual server 1 of Zone-1 and virtual server 2 of - Zone-2 to GLSB virtual server 2. GSLB virtual server 2 is configured to start monitoring the - health of virtual server 1 and 2. &PRODUCT; will bind the domain A.xyztelco.com to both the - GSLB virtual server 1 and 2. At this point, Tenant-A service will be globally reachable at - A.xyztelco.com. The private DNS server for the domain xyztelcom.com is configured by the admin - out-of-band to resolve the domain A.xyztelco.com to the GSLB providers at both the zones, - which are configured as ADNS for the domain A.xyztelco.com. A client when sends a DNS request - to resolve A.xyztelcom.com, will eventually get DNS delegation to the address of GSLB - providers at Zone 1 and 2. A client DNS request will be received by the GSLB provider. The - GSLB provider, depending on the domain for which it needs to resolve, will pick up the GSLB - virtual server associated with the domain. Depending on the health of the virtual servers - being load balanced, DNS request for the domain will be resolved to the public IP associated - with the selected virtual server. +
    + Prerequisites and Guidelines + + + The GSLB functionality is supported both Basic and Advanced zones. + + + GSLB is added as a new network service. + + + GSLB service provider can be added to a physical network in a zone. + + + The admin is allowed to enable or disable GSLB functionality at region level. + + + The admin is allowed to configure a zone as GSLB capable or enabled. + A zone shall be considered as GSLB capable only if a GSLB service provider is + provisioned in the zone. + + + When users have VMs deployed in multiple availability zones which are GSLB enabled, + they can use the GSLB functionality to load balance traffic across the VMs in multiple + zones. + + + The users can use GSLB to load balance across the VMs across zones in a region only + if the admin has enabled GSLB in that region. + + + The users can load balance traffic across the availability zones in the same region + or different regions. + + + The admin can configure DNS name for the entire cloud. + + + The users can specify an unique name across the cloud for a globally load balanced + service. The provided name is used as the domain name under the DNS name associated with + the cloud. + The user-provided name along with the admin-provided DNS name is used to produce a + globally resolvable FQDN for the globally load balanced service of the user. For + example, if the admin has configured xyztelco.com as the DNS name for the cloud, and + user specifies 'foo' for the GSLB virtual service, then the FQDN name of the GSLB + virtual service is foo.xyztelco.com. + + + While setting up GSLB, users can select a load balancing method, such as round + robin, for using across the zones that are part of GSLB. + + + The user shall be able to set weight to zone-level virtual server. Weight shall be + considered by the load balancing method for distributing the traffic. + + + The GSLB functionality shall support session persistence, where series of client + requests for particular domain name is sent to a virtual server on the same zone. + Statistics is collected from each GSLB virtual server. + + +
    +
    + Enabling GSLB in NetScaler + In each zone, add GSLB-enabled NetScaler device for load balancing. + + + Log in as administrator to the &PRODUCT; UI. + + + In the left navigation bar, click Infrastructure. + + + In Zones, click View More. + + + Choose the zone you want to work with. + + + Click the Physical Network tab, then click the name of the physical network. + + + In the Network Service Providers node of the diagram, click Configure. + You might have to scroll down to see this. + + + Click NetScaler. + + + Click Add NetScaler device and provide the following: + For NetScaler: + + + IP Address: The IP address of the SRX. + + + Username/Password: The authentication + credentials to access the device. &PRODUCT; uses these credentials to access the + device. + + + Type: The type of device that is being added. + It could be F5 Big Ip Load Balancer, NetScaler VPX, NetScaler MPX, or NetScaler SDX. + For a comparison of the NetScaler types, see the &PRODUCT; Administration + Guide. + + + Public interface: Interface of device that is + configured to be part of the public network. + + + Private interface: Interface of device that is + configured to be part of the private network. + + + GSLB service: Select this option. + + + GSLB service Public IP: The public IP address + of the NAT translator for a GSLB service that is on a private network. + + + GSLB service Private IP: The private IP of the + GSLB service. + + + Number of Retries. Number of times to attempt a + command on the device before considering the operation failed. Default is 2. + + + Capacity: The number of networks the device can + handle. + + + Dedicated: When marked as dedicated, this + device will be dedicated to a single account. When Dedicated is checked, the value + in the Capacity field has no significance implicitly, its value is 1. + + + + + Click OK. + + +
    +
    + Adding a GSLB Rule + + + Log in to the &PRODUCT; UI as a domain administrator or user. + + + In the left navigation pane, click Region. + + + Select the region for which you want to create a GSLB rule. + + + In the Details tab, click View GSLB. + + + Click Add GSLB. + The Add GSLB page is displayed as follows: + + + + + + gslb-add.png: adding a gslb rule + + + + + Specify the following: + + + Name: Name for the GSLB rule. + + + Description: (Optional) A short description of + the GSLB rule that can be displayed to users. + + + GSLB Domain Name: A preferred domain name for + the service. + + + Algorithm: (Optional) The algorithm to use to + load balance the traffic across the zones. The options are Round Robin, Least + Connection, and Proximity. + + + Service Type: The transport protocol to use for + GSLB. The options are TCP and UDP. + + + Domain: (Optional) The domain for which you + want to create the GSLB rule. + + + Account: (Optional) The account on which you + want to apply the GSLB rule. + + + + + Click OK to confirm. + + +
    +
    + Assigning Load Balancing Rules to GSLB + + + + Log in to the &PRODUCT; UI as a domain administrator or user. + + + In the left navigation pane, click Region. + + + Select the region for which you want to create a GSLB rule. + + + In the Details tab, click View GSLB. + + + Select the desired GSLB. + + + Click view assigned load balancing. + + + Click assign more load balancing. + + + Select the load balancing rule you have created for the zone. + + + Click OK to confirm. + + +
    Known Limitation diff --git a/docs/en-US/images/gslb.png b/docs/en-US/images/gslb.png index 8d1a389936c31e3ed46c24f7a6787fd21a873c65..9f13580c56095985891f09e9c33bc363567eb57e 100644 GIT binary patch literal 60354 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
    \ No newline at end of file + diff --git a/docs/en-US/hypervisor-host-install-libvirt.xml b/docs/en-US/hypervisor-host-install-libvirt.xml index f3ff090463c..d3d6b9b4e80 100644 --- a/docs/en-US/hypervisor-host-install-libvirt.xml +++ b/docs/en-US/hypervisor-host-install-libvirt.xml @@ -24,7 +24,7 @@
    Install and Configure libvirt - &PRODUCT; uses libvirt for managing virtual machines. Therefore it is vital that libvirt is configured correctly. Libvirt is a dependency of cloud-agent and should already be installed. + &PRODUCT; uses libvirt for managing virtual machines. Therefore it is vital that libvirt is configured correctly. Libvirt is a dependency of cloudstack-agent and should already be installed. In order to have live migration working libvirt has to listen for unsecured TCP connections. We also need to turn off libvirts attempt to use Multicast DNS advertising. Both of these settings are in /etc/libvirt/libvirtd.conf diff --git a/docs/en-US/increase-management-server-max-memory.xml b/docs/en-US/increase-management-server-max-memory.xml index 16d18e75830..51c8724a020 100644 --- a/docs/en-US/increase-management-server-max-memory.xml +++ b/docs/en-US/increase-management-server-max-memory.xml @@ -28,7 +28,7 @@ Edit the Tomcat configuration file:/etc/cloud/management/tomcat6.conf Change the command-line parameter -XmxNNNm to a higher value of N.For example, if the current value is -Xmx128m, change it to -Xmx1024m or higher. - To put the new setting into effect, restart the Management Server.# service cloud-management restart + To put the new setting into effect, restart the Management Server.# service cloudstack-management restart For more information about memory issues, see "FAQ: Memory" at Tomcat Wiki.
    diff --git a/docs/en-US/install-usage-server.xml b/docs/en-US/install-usage-server.xml index 9dde5523f5e..ffd748d758e 100644 --- a/docs/en-US/install-usage-server.xml +++ b/docs/en-US/install-usage-server.xml @@ -52,7 +52,7 @@ Once installed, start the Usage Server with the following command. -# service cloud-usage start +# service cloudstack-usage start diff --git a/docs/en-US/lxc-install.xml b/docs/en-US/lxc-install.xml index a80c18afdd6..40f6a0aaa69 100644 --- a/docs/en-US/lxc-install.xml +++ b/docs/en-US/lxc-install.xml @@ -74,9 +74,9 @@ To manage LXC instances on the host &PRODUCT; uses a Agent. This Agent communicates with the Management server and controls all the instances on the host. First we start by installing the agent: In RHEL or CentOS: - $ yum install cloud-agent + $ yum install cloudstack-agent In Ubuntu: - $ apt-get install cloud-agent + $ apt-get install cloudstack-agent Next step is to update the Agent configuration setttings. The settings are in /etc/cloudstack/agent/agent.properties diff --git a/docs/en-US/set-global-project-resource-limits.xml b/docs/en-US/set-global-project-resource-limits.xml index d91942ad8db..8ec13259051 100644 --- a/docs/en-US/set-global-project-resource-limits.xml +++ b/docs/en-US/set-global-project-resource-limits.xml @@ -76,7 +76,7 @@ Restart the Management Server. - # service cloud-management restart + # service cloudstack-management restart diff --git a/docs/en-US/set-projects-creator-permissions.xml b/docs/en-US/set-projects-creator-permissions.xml index 9b272f6bc7e..dd9cfe95d56 100644 --- a/docs/en-US/set-projects-creator-permissions.xml +++ b/docs/en-US/set-projects-creator-permissions.xml @@ -56,7 +56,7 @@ Restart the Management Server. - # service cloud-management restart + # service cloudstack-management restart diff --git a/docs/en-US/set-up-invitations.xml b/docs/en-US/set-up-invitations.xml index c1303cf5e92..180c041e87e 100644 --- a/docs/en-US/set-up-invitations.xml +++ b/docs/en-US/set-up-invitations.xml @@ -89,7 +89,7 @@ Restart the Management Server: - service cloud-management restart + service cloudstack-management restart diff --git a/docs/en-US/stop-restart-management-server.xml b/docs/en-US/stop-restart-management-server.xml index 5c1bcecbc00..74a687c23a1 100644 --- a/docs/en-US/stop-restart-management-server.xml +++ b/docs/en-US/stop-restart-management-server.xml @@ -26,9 +26,9 @@ The root administrator will need to stop and restart the Management Server from time to time. For example, after changing a global configuration parameter, a restart is required. If you have multiple Management Server nodes, restart all of them to put the new parameter value into effect consistently throughout the cloud.. To stop the Management Server, issue the following command at the operating system prompt on the Management Server node: - # service cloud-management stop + # service cloudstack-management stop To start the Management Server: - # service cloud-management start + # service cloudstack-management start To stop the Management Server: - # service cloud-management stop + # service cloudstack-management stop diff --git a/docs/en-US/sys-offering-sysvm.xml b/docs/en-US/sys-offering-sysvm.xml index cccf3e04796..563dd6f5ebf 100644 --- a/docs/en-US/sys-offering-sysvm.xml +++ b/docs/en-US/sys-offering-sysvm.xml @@ -65,7 +65,7 @@ Restart &PRODUCT; Management Server. Restarting is required because the default offerings are loaded into the memory at startup. - service cloud-management restart + service cloudstack-management restart Destroy the existing CPVM or SSVM offerings and wait for them to be recreated. The new diff --git a/docs/en-US/zone-add.xml b/docs/en-US/zone-add.xml index 4f6606fce03..3ca5789cd99 100644 --- a/docs/en-US/zone-add.xml +++ b/docs/en-US/zone-add.xml @@ -42,7 +42,7 @@ Restart the Management Server. - # service cloud-management restart + # service cloudstack-management restart Refresh the &PRODUCT; UI browser tab and log back in. From f12ac95a56983267fd66c215461fa7e17a43525f Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Fri, 10 May 2013 11:03:34 -0700 Subject: [PATCH 69/71] VPC: When Netscaler is LB provider for the VPC, the VpcVirtualRouter can't provide LB services --- server/src/com/cloud/network/vpc/VpcManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 09776ae48eb..e6d71faad35 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -228,7 +228,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis if (svc == Service.Lb) { Set lbProviders = new HashSet(); lbProviders.add(Provider.Netscaler); - lbProviders.add(Provider.VPCVirtualRouter); + lbProviders.add(Provider.InternalLbVm); svcProviderMap.put(svc, lbProviders); } else { svcProviderMap.put(svc, defaultProviders); From 791c68fc11976a0bb9bc46e3a18c9778008bf444 Mon Sep 17 00:00:00 2001 From: Milamber Date: Fri, 10 May 2013 19:56:57 +0100 Subject: [PATCH 70/71] Fix doc: MySQL not Tomcat --- docs/en-US/set-database-buffer-pool-size.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en-US/set-database-buffer-pool-size.xml b/docs/en-US/set-database-buffer-pool-size.xml index 1c7503101ca..8265ae544f2 100644 --- a/docs/en-US/set-database-buffer-pool-size.xml +++ b/docs/en-US/set-database-buffer-pool-size.xml @@ -26,7 +26,7 @@ Set Database Buffer Pool Size It is important to provide enough memory space for the MySQL database to cache data and indexes: - Edit the Tomcat configuration file:/etc/my.cnf + Edit the MySQL configuration file:/etc/my.cnf Insert the following line in the [mysqld] section, below the datadir line. Use a value that is appropriate for your situation. We recommend setting the buffer pool at 40% of RAM if MySQL is on the same server as the management server or 70% of RAM if MySQL has a dedicated server. The following example assumes a dedicated server with 1024M of RAM. innodb_buffer_pool_size=700M Restart the MySQL service.# service mysqld restart From b7f10bffaedc5d346c90dca70810de11225d61d0 Mon Sep 17 00:00:00 2001 From: Pranav Saxena Date: Sat, 11 May 2013 01:21:50 +0530 Subject: [PATCH 71/71] Removing the @Test annotation for building master successfully for one of the test cases for InternalLb element as discussed with Alena --- .../internallbelement/InternalLbElementServiceTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementServiceTest.java b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementServiceTest.java index f0e951cdc7a..bdc50cafb8c 100644 --- a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementServiceTest.java +++ b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementServiceTest.java @@ -175,7 +175,6 @@ public class InternalLbElementServiceTest { } - @Test (expected = InvalidParameterValueException.class) public void addToInvalidProvider() { _lbElSvc.addInternalLoadBalancerElement(invalidProviderId); }