From 7b444183db7e84616a377f76737237e704785df0 Mon Sep 17 00:00:00 2001 From: "Frank.Zhang" Date: Mon, 7 Jul 2014 11:37:38 -0700 Subject: [PATCH] CLOUDSTACK-6278 Baremetal Advanced Networking support --- plugins/hypervisors/baremetal/pom.xml | 12 +- .../spring-baremetal-compute-context.xml | 2 +- .../spring-baremetal-discoverer-context.xml | 2 +- .../spring-baremetal-network-context.xml | 2 +- .../spring-baremetal-planner-context.xml | 2 +- .../core/spring-baremetal-core-context.xml | 4 +- .../resources/security_group_agent/cs-sgagent | 40 +-- .../security_group_agent/__init__.py | 6 +- .../security_group_agent/cs_sg_agent.py | 7 +- .../security_group_agent/sglib.py | 68 ++--- .../security_group_agent/xmlobject.py | 6 +- .../resources/security_group_agent/setup.py | 6 +- .../baremetal/database/BaremetalRctDao.java | 9 + .../database/BaremetalRctDaoImpl.java | 9 + .../baremetal/database/BaremetalRctVO.java | 62 +++++ .../manager/BareMetalDiscoverer.java | 34 ++- .../cloud/baremetal/manager/BaremetalRct.java | 108 +++++++ .../manager/BaremetalVlanManager.java | 13 + .../manager/BaremetalVlanManagerImpl.java | 71 +++++ .../networkservice/BareMetalResourceBase.java | 171 ++++++++---- .../networkservice/BaremetaNetworkGuru.java | 6 +- .../BaremetalDhcpdResource.java | 2 +- .../networkservice/BaremetalPxeElement.java | 19 +- .../BaremetalPxeManagerImpl.java | 2 +- .../networkservice/BaremetalRctResponse.java | 35 +++ .../SecurityGroupHttpClient.java | 243 +++++++++++++--- .../networkservice/schema/ObjectFactory.java | 55 ++++ .../schema/SecurityGroupRule.java | 146 ++++++++++ .../schema/SecurityGroupVmRuleSet.java | 263 ++++++++++++++++++ .../cloudstack/api/AddBaremetalRctCmd.java | 68 +++++ 30 files changed, 1273 insertions(+), 200 deletions(-) create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java create mode 100755 plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java create mode 100644 plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java create mode 100644 plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java create mode 100644 plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java create mode 100755 plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml index b75619557c2..8f1237e4802 100755 --- a/plugins/hypervisors/baremetal/pom.xml +++ b/plugins/hypervisors/baremetal/pom.xml @@ -21,17 +21,17 @@ org.apache.cloudstack cloudstack-plugins - 4.5.0-SNAPSHOT + 4.4.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-baremetal Apache CloudStack Plugin - Hypervisor Baremetal - - commons-lang - commons-lang - 2.6 - + + commons-lang + commons-lang + 2.6 + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml index cce68051239..d0b52a1bb0f 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml @@ -31,5 +31,5 @@ - + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml index 8792909ffed..c01d9c62afa 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml @@ -30,5 +30,5 @@ - + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml index 40d9f505775..c5068e7b149 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml @@ -42,5 +42,5 @@ - + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml index 8c14c3e2903..046aca67e88 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml @@ -30,5 +30,5 @@ - + diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml index 11cc6c89e3f..e1a21bc0597 100644 --- a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml +++ b/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml @@ -28,6 +28,7 @@ > + @@ -38,5 +39,6 @@ - + + diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent b/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent index 02426d0aa10..f8a5d7d2c9d 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent @@ -18,9 +18,9 @@ # 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 @@ -29,31 +29,31 @@ # under the License. check_status() { - pidfile='/var/run/cssgagent.pid' - if [ ! -f $pidfile ]; then - echo "cloudstack baremetal security group agent is stopped" - exit 1 - else - pid=`cat $pidfile` - ps -p $pid > /dev/null - if [ $? -eq 0 ]; then - echo "cloudstack baremetal security group agent is running, pid is $pid" - exit 0 - else - echo "cloudstack baremetal security group agent is stopped, but pidfile at $pidfile is not cleaned. It may be caused by the agent crashed at last time, manually cleaning it would be ok" - exit 1 - fi - fi + pidfile='/var/run/cssgagent.pid' + if [ ! -f $pidfile ]; then + echo "cloudstack baremetal security group agent is stopped" + exit 1 + else + pid=`cat $pidfile` + ps -p $pid > /dev/null + if [ $? -eq 0 ]; then + echo "cloudstack baremetal security group agent is running, pid is $pid" + exit 0 + else + echo "cloudstack baremetal security group agent is stopped, but pidfile at $pidfile is not cleaned. It may be caused by the agent crashed at last time, manually cleaning it would be ok" + exit 1 + fi + fi } if [ $# -eq 0 ]; then - echo "usage: $0 + echo "usage: $0 [start|stop|restart|status]" - exit 1 + exit 1 fi if [ "$@" = "status" ]; then - check_status + check_status else python -c "from security_group_agent import cs_sg_agent; cs_sg_agent.main()" $@ fi diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py index f7f5f60ff05..76bd5c1b216 100644 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py @@ -5,14 +5,14 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py index a292c0bcfb8..0c49a3f7862 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py @@ -5,16 +5,16 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 ''' Created on Jan 2, 2013 @@ -234,4 +234,3 @@ def main(): agentdaemon.restart() sys.exit(0) - \ No newline at end of file diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py index bf64effa190..bc675b540ad 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py @@ -6,16 +6,16 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 import sys, os, time, atexit @@ -31,7 +31,7 @@ class Request(object): self.body = None self.method = None self.query_string = None - + @staticmethod def from_cherrypy_request(creq): req = Request() @@ -40,10 +40,10 @@ class Request(object): req.method = copy.copy(creq.method) req.query_string = copy.copy(creq.query_string) if creq.query_string else None return req - + class ShellError(Exception): '''shell error''' - + class ShellCmd(object): ''' classdocs @@ -57,11 +57,11 @@ class ShellCmd(object): self.process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, executable='/bin/sh', cwd=workdir) else: self.process = subprocess.Popen(cmd, shell=True, executable='/bin/sh', cwd=workdir) - + self.stdout = None self.stderr = None self.return_code = None - + def __call__(self, is_exception=True): (self.stdout, self.stderr) = self.process.communicate() if is_exception and self.process.returncode != 0: @@ -71,18 +71,18 @@ class ShellCmd(object): err.append('stdout: %s' % self.stdout) err.append('stderr: %s' % self.stderr) raise ShellError('\n'.join(err)) - + self.return_code = self.process.returncode return self.stdout class Daemon(object): """ A generic daemon class. - + Usage: subclass the Daemon class and override the run() method """ atexit_hooks = [] - + def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): self.stdin = stdin self.stdout = stdout @@ -102,37 +102,37 @@ class Daemon(object): content = traceback.format_exc() err = 'Exception when calling atexit hook[%s]\n%s' % (hook.__name__, content) #logger.error(err) - + def daemonize(self): """ - do the UNIX double-fork magic, see Stevens' "Advanced + do the UNIX double-fork magic, see Stevens' "Advanced Programming in the UNIX Environment" for details (ISBN 0201563177) http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 """ - try: - pid = os.fork() + try: + pid = os.fork() if pid > 0: # exit first parent - sys.exit(0) - except OSError, e: + sys.exit(0) + except OSError, e: sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) - + # decouple from parent environment - os.chdir("/") - os.setsid() - os.umask(0) - + os.chdir("/") + os.setsid() + os.umask(0) + # do second fork - try: - pid = os.fork() + try: + pid = os.fork() if pid > 0: # exit from second parent - sys.exit(0) - except OSError, e: + sys.exit(0) + except OSError, e: sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) - sys.exit(1) - + sys.exit(1) + # redirect standard file descriptors sys.stdout.flush() sys.stderr.flush() @@ -142,13 +142,13 @@ class Daemon(object): os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) - + # write pidfile Daemon.register_atexit_hook(self.delpid) atexit.register(Daemon._atexit) pid = str(os.getpid()) file(self.pidfile,'w').write("%s\n" % pid) - + def delpid(self): os.remove(self.pidfile) @@ -163,7 +163,7 @@ class Daemon(object): pf.close() except IOError: pid = None - + if pid: pscmd = ShellCmd('ps -p %s > /dev/null' % pid) pscmd(is_exception=False) @@ -171,7 +171,7 @@ class Daemon(object): message = "Daemon already running, pid is %s\n" sys.stderr.write(message % pid) sys.exit(0) - + # Start the daemon self.daemonize() try: @@ -192,13 +192,13 @@ class Daemon(object): pf.close() except IOError: pid = None - + if not pid: message = "pidfile %s does not exist. Daemon not running?\n" sys.stderr.write(message % self.pidfile) return # not an error in a restart - # Try killing the daemon process + # Try killing the daemon process try: while 1: os.kill(pid, SIGTERM) diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py index cb66d265a5a..175349958ce 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py @@ -5,16 +5,16 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 ''' Created on Dec 25, 2012 diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py b/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py index 384e04d6a96..ed106313ffb 100755 --- a/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py +++ b/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py @@ -5,16 +5,16 @@ # 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. -# +# # Automatically generated by addcopyright.py at 01/29/2013 from setuptools import setup, find_packages import sys, os diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java new file mode 100755 index 00000000000..fee2d71724c --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java @@ -0,0 +1,9 @@ +package com.cloud.baremetal.database; + +import com.cloud.utils.db.GenericDao; + +/** + * Created by frank on 5/8/14. + */ +public interface BaremetalRctDao extends GenericDao { +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java new file mode 100755 index 00000000000..89df902e6cf --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java @@ -0,0 +1,9 @@ +package com.cloud.baremetal.database; + +import com.cloud.utils.db.GenericDaoBase; + +/** + * Created by frank on 5/8/14. + */ +public class BaremetalRctDaoImpl extends GenericDaoBase implements BaremetalRctDao { +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java new file mode 100755 index 00000000000..ae1f794aab8 --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java @@ -0,0 +1,62 @@ +package com.cloud.baremetal.database; + +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 java.util.UUID; + +/** + * Created by frank on 5/8/14. + */ +@Entity +@Table(name = "baremetal_rct") +public class BaremetalRctVO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "uuid") + private String uuid = UUID.randomUUID().toString(); + + @Column(name = "url") + private String url; + + @Column(name = "rct") + private String rct; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getRct() { + return rct; + } + + public void setRct(String rct) { + this.rct = rct; + } +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java index c312df7b79e..8b4b45348fd 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java @@ -80,8 +80,8 @@ public class BareMetalDiscoverer extends DiscovererBase implements Discoverer, R } @Override - public Map> - find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List hostTags) throws DiscoveryException { + public Map> find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List hostTags) + throws DiscoveryException { /* Enable this after we decide to use addBaremetalHostCmd instead of addHostCmd String discoverName = _params.get(ApiConstants.BAREMETAL_DISCOVER_NAME); @@ -130,18 +130,18 @@ public class BareMetalDiscoverer extends DiscovererBase implements Discoverer, R String injectScript = "scripts/util/ipmi.py"; String scriptPath = Script.findScript("", injectScript); if (scriptPath == null) { - throw new CloudRuntimeException("Unable to find key ipmi script " + injectScript); + throw new CloudRuntimeException("Unable to find key ipmi script " + + injectScript); } final Script2 command = new Script2(scriptPath, s_logger); command.add("ping"); - command.add("hostname=" + ipmiIp); - command.add("usrname=" + username); - command.add("password=" + password, ParamType.PASSWORD); + command.add("hostname="+ipmiIp); + command.add("usrname="+username); + command.add("password="+password, ParamType.PASSWORD); final String result = command.execute(); if (result != null) { - s_logger.warn(String.format("Can not set up ipmi connection(ip=%1$s, username=%2$s, password=%3$s, args) because %4$s", ipmiIp, username, "******", - result)); + s_logger.warn(String.format("Can not set up ipmi connection(ip=%1$s, username=%2$s, password=%3$s, args) because %4$s", ipmiIp, username, "******", result)); return null; } @@ -155,21 +155,22 @@ public class BareMetalDiscoverer extends DiscovererBase implements Discoverer, R params.putAll(_params); params.put("zone", Long.toString(dcId)); params.put("pod", Long.toString(podId)); - params.put("cluster", Long.toString(clusterId)); + params.put("cluster", Long.toString(clusterId)); params.put("guid", guid); params.put(ApiConstants.PRIVATE_IP, ipmiIp); params.put(ApiConstants.USERNAME, username); params.put(ApiConstants.PASSWORD, password); + params.put("vmDao", _vmDao); + params.put("configDao", _configDao); String resourceClassName = _configDao.getValue(Config.ExternalBaremetalResourceClassName.key()); BareMetalResourceBase resource = null; if (resourceClassName != null) { Class clazz = Class.forName(resourceClassName); - resource = (BareMetalResourceBase)clazz.newInstance(); + resource = (BareMetalResourceBase) clazz.newInstance(); String externalUrl = _configDao.getValue(Config.ExternalBaremetalSystemUrl.key()); if (externalUrl == null) { - throw new IllegalArgumentException( - String.format("You must specify ExternalBaremetalSystemUrl in global config page as ExternalBaremetalResourceClassName is not null")); + throw new IllegalArgumentException(String.format("You must specify ExternalBaremetalSystemUrl in global config page as ExternalBaremetalResourceClassName is not null")); } details.put(BaremetalManager.ExternalBaremetalSystemUrl, externalUrl); } else { @@ -206,8 +207,8 @@ public class BareMetalDiscoverer extends DiscovererBase implements Discoverer, R zone.setDhcpProvider(Network.Provider.ExternalDhcpServer.getName()); _dcDao.update(zone.getId(), zone); - s_logger.debug(String.format("Discover Bare Metal host successfully(ip=%1$s, username=%2$s, password=%3%s," - + "cpuNum=%4$s, cpuCapacity-%5$s, memCapacity=%6$s)", ipmiIp, username, "******", cpuNum, cpuCapacity, memCapacity)); + s_logger.debug(String.format("Discover Bare Metal host successfully(ip=%1$s, username=%2$s, password=%3%s," + + "cpuNum=%4$s, cpuCapacity-%5$s, memCapacity=%6$s)", ipmiIp, username, "******", cpuNum, cpuCapacity, memCapacity)); return resources; } catch (Exception e) { s_logger.warn("Can not set up bare metal agent", e); @@ -217,7 +218,8 @@ public class BareMetalDiscoverer extends DiscovererBase implements Discoverer, R } @Override - public void postDiscovery(List hosts, long msId) throws DiscoveryException { + public void postDiscovery(List hosts, long msId) + throws DiscoveryException { } @Override @@ -273,6 +275,8 @@ public class BareMetalDiscoverer extends DiscovererBase implements Discoverer, R HashMap params = super.buildConfigParams(host); params.put("hostId", host.getId()); params.put("ipaddress", host.getPrivateIpAddress()); + params.put("vmDao", _vmDao); + params.put("configDao", _configDao); return params; } diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java new file mode 100755 index 00000000000..796023e7ff1 --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java @@ -0,0 +1,108 @@ +package com.cloud.baremetal.manager; + +import java.util.List; + +/** + * Created by frank on 5/8/14. + */ +public class BaremetalRct { + public static class SwitchEntry { + private String ip; + private String username; + private String password; + private String type; + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + } + + public static class HostEntry { + private String uuid; + private String mac; + private int port; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + } + + public static class Rack { + private SwitchEntry l2Switch; + private List hosts; + + public SwitchEntry getL2Switch() { + return l2Switch; + } + + public void setL2Switch(SwitchEntry l2Switch) { + this.l2Switch = l2Switch; + } + + public List getHosts() { + return hosts; + } + + public void setHosts(List hosts) { + this.hosts = hosts; + } + } + + private List racks; + + public List getRacks() { + return racks; + } + + public void setRacks(List racks) { + this.racks = racks; + } +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java new file mode 100755 index 00000000000..8b57eb40323 --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java @@ -0,0 +1,13 @@ +package com.cloud.baremetal.manager; + +import com.cloud.baremetal.networkservice.BaremetalRctResponse; +import com.cloud.utils.component.Manager; +import com.cloud.utils.component.PluggableService; +import org.apache.cloudstack.api.AddBaremetalRctCmd; + +/** + * Created by frank on 4/30/14. + */ +public interface BaremetalVlanManager extends Manager, PluggableService { + BaremetalRctResponse addRct(AddBaremetalRctCmd cmd); +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java new file mode 100755 index 00000000000..5bb59a2edb1 --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java @@ -0,0 +1,71 @@ +package com.cloud.baremetal.manager; + +import com.cloud.baremetal.database.BaremetalRctDao; +import com.cloud.baremetal.database.BaremetalRctVO; +import com.cloud.baremetal.networkservice.BaremetalRctResponse; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.db.QueryBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.google.gson.Gson; +import org.apache.cloudstack.api.AddBaremetalRctCmd; +import org.springframework.web.client.RestTemplate; + +import javax.inject.Inject; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by frank on 5/8/14. + */ +public class BaremetalVlanManagerImpl extends ManagerBase implements BaremetalVlanManager { + private Gson gson = new Gson(); + + @Inject + private BaremetalRctDao rctDao; + + @Override + public BaremetalRctResponse addRct(AddBaremetalRctCmd cmd) { + try { + URL url = new URL(cmd.getRctUrl()); + RestTemplate rest = new RestTemplate(); + String rctStr = rest.getForObject(url.toString(), String.class); + + // validate it's right format + BaremetalRct rct = gson.fromJson(rctStr, BaremetalRct.class); + QueryBuilder sc = QueryBuilder.create(BaremetalRctVO.class); + sc.and(sc.entity().getUrl(), SearchCriteria.Op.EQ, cmd.getRctUrl()); + BaremetalRctVO vo = sc.find(); + if (vo == null) { + vo = new BaremetalRctVO(); + vo.setRct(gson.toJson(rct)); + vo.setUrl(cmd.getRctUrl()); + vo = rctDao.persist(vo); + } else { + vo.setRct(gson.toJson(rct)); + rctDao.update(vo.getId(), vo); + } + + BaremetalRctResponse rsp = new BaremetalRctResponse(); + rsp.setUrl(vo.getUrl()); + rsp.setId(vo.getUuid()); + return rsp; + } catch (MalformedURLException e) { + throw new IllegalArgumentException(String.format("%s is not a legal http url", cmd.getRctUrl())); + } + } + + @Override + public String getName() { + return "Baremetal Vlan Manager"; + } + + + @Override + public List> getCommands() { + List> cmds = new ArrayList>(); + cmds.add(AddBaremetalRctCmd.class); + return cmds; + } +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java index b729d9bb3eb..828533708ef 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java @@ -22,18 +22,6 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.baremetal.networkservice; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - -import org.apache.cloudstack.api.ApiConstants; - import com.cloud.agent.IAgentControl; import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckNetworkAnswer; @@ -48,6 +36,7 @@ import com.cloud.agent.api.MigrateAnswer; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; +import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; import com.cloud.agent.api.PrepareForMigrationAnswer; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyAnswer; @@ -66,10 +55,11 @@ import com.cloud.agent.api.baremetal.IpmISetBootDevCommand.BootDev; import com.cloud.agent.api.baremetal.IpmiBootorResetCommand; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.baremetal.manager.BaremetalManager; +import com.cloud.configuration.Config; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor; import com.cloud.resource.ServerResource; -import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.Pair; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.OutputInterpreter; @@ -81,6 +71,16 @@ import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.PowerState; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.VMInstanceDao; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; @Local(value = ServerResource.class) public class BareMetalResourceBase extends ManagerBase implements ServerResource { @@ -111,6 +111,9 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource protected Script2 _forcePowerOffCommand; protected Script2 _bootOrRebootCommand; protected String _vmName; + protected int ipmiRetryTimes = 5; + + protected ConfigurationDao configDao; protected VMInstanceDao vmDao; private void changeVmState(String vmName, VirtualMachine.State state) { @@ -128,27 +131,29 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource @Override public boolean configure(String name, Map params) throws ConfigurationException { _name = name; - _uuid = (String)params.get("guid"); + _uuid = (String) params.get("guid"); try { - _memCapacity = Long.parseLong((String)params.get(ApiConstants.MEMORY)) * 1024L * 1024L; - _cpuCapacity = Long.parseLong((String)params.get(ApiConstants.CPU_SPEED)); - _cpuNum = Long.parseLong((String)params.get(ApiConstants.CPU_NUMBER)); + _memCapacity = Long.parseLong((String) params.get(ApiConstants.MEMORY)) * 1024L * 1024L; + _cpuCapacity = Long.parseLong((String) params.get(ApiConstants.CPU_SPEED)); + _cpuNum = Long.parseLong((String) params.get(ApiConstants.CPU_NUMBER)); } catch (NumberFormatException e) { throw new ConfigurationException(String.format("Unable to parse number of CPU or memory capacity " - + "or cpu capacity(cpu number = %1$s memCapacity=%2$s, cpuCapacity=%3$s", params.get(ApiConstants.CPU_NUMBER), params.get(ApiConstants.MEMORY), - params.get(ApiConstants.CPU_SPEED))); + + "or cpu capacity(cpu number = %1$s memCapacity=%2$s, cpuCapacity=%3$s", params.get(ApiConstants.CPU_NUMBER), + params.get(ApiConstants.MEMORY), params.get(ApiConstants.CPU_SPEED))); } - _zone = (String)params.get("zone"); - _pod = (String)params.get("pod"); - _cluster = (String)params.get("cluster"); - hostId = (Long)params.get("hostId"); - _ip = (String)params.get(ApiConstants.PRIVATE_IP); - _mac = (String)params.get(ApiConstants.HOST_MAC); - _username = (String)params.get(ApiConstants.USERNAME); - _password = (String)params.get(ApiConstants.PASSWORD); - _vmName = (String)params.get("vmName"); - String echoScAgent = (String)params.get(BaremetalManager.EchoSecurityGroupAgent); + _zone = (String) params.get("zone"); + _pod = (String) params.get("pod"); + _cluster = (String) params.get("cluster"); + hostId = (Long) params.get("hostId"); + _ip = (String) params.get(ApiConstants.PRIVATE_IP); + _mac = (String) params.get(ApiConstants.HOST_MAC); + _username = (String) params.get(ApiConstants.USERNAME); + _password = (String) params.get(ApiConstants.PASSWORD); + _vmName = (String) params.get("vmName"); + String echoScAgent = (String) params.get(BaremetalManager.EchoSecurityGroupAgent); + vmDao = (VMInstanceDao) params.get("vmDao"); + configDao = (ConfigurationDao) params.get("configDao"); if (_pod == null) { throw new ConfigurationException("Unable to get the pod"); @@ -167,7 +172,8 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource } if (_mac.split(":").length != 6) { - throw new ConfigurationException("Wrong MAC format(" + _mac + "). It must be in format of for example 00:11:ba:33:aa:dd which is not case sensitive"); + throw new ConfigurationException("Wrong MAC format(" + _mac + + "). It must be in format of for example 00:11:ba:33:aa:dd which is not case sensitive"); } if (_uuid == null) { @@ -178,6 +184,19 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource _isEchoScAgent = Boolean.valueOf(echoScAgent); } + String ipmiIface = "default"; + try { + ipmiIface = configDao.getValue(Config.BaremetalIpmiLanInterface.key()); + } catch (Exception e) { + s_logger.debug(e.getMessage(), e); + } + + try { + ipmiRetryTimes = Integer.valueOf(configDao.getValue(Config.BaremetalIpmiRetryTimes.key())); + } catch (Exception e) { + s_logger.debug(e.getMessage(), e); + } + String injectScript = "scripts/util/ipmi.py"; String scriptPath = Script.findScript("", injectScript); if (scriptPath == null) { @@ -187,6 +206,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource _pingCommand = new Script2(pythonPath, s_logger); _pingCommand.add(scriptPath); _pingCommand.add("ping"); + _pingCommand.add("interface=" + ipmiIface); _pingCommand.add("hostname=" + _ip); _pingCommand.add("usrname=" + _username); _pingCommand.add("password=" + _password, ParamType.PASSWORD); @@ -194,6 +214,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource _setPxeBootCommand = new Script2(pythonPath, s_logger); _setPxeBootCommand.add(scriptPath); _setPxeBootCommand.add("boot_dev"); + _setPxeBootCommand.add("interface=" + ipmiIface); _setPxeBootCommand.add("hostname=" + _ip); _setPxeBootCommand.add("usrname=" + _username); _setPxeBootCommand.add("password=" + _password, ParamType.PASSWORD); @@ -202,6 +223,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource _setDiskBootCommand = new Script2(pythonPath, s_logger); _setDiskBootCommand.add(scriptPath); _setDiskBootCommand.add("boot_dev"); + _setDiskBootCommand.add("interface=" + ipmiIface); _setDiskBootCommand.add("hostname=" + _ip); _setDiskBootCommand.add("usrname=" + _username); _setDiskBootCommand.add("password=" + _password, ParamType.PASSWORD); @@ -210,6 +232,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource _rebootCommand = new Script2(pythonPath, s_logger); _rebootCommand.add(scriptPath); _rebootCommand.add("reboot"); + _rebootCommand.add("interface=" + ipmiIface); _rebootCommand.add("hostname=" + _ip); _rebootCommand.add("usrname=" + _username); _rebootCommand.add("password=" + _password, ParamType.PASSWORD); @@ -217,6 +240,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource _getStatusCommand = new Script2(pythonPath, s_logger); _getStatusCommand.add(scriptPath); _getStatusCommand.add("ping"); + _getStatusCommand.add("interface=" + ipmiIface); _getStatusCommand.add("hostname=" + _ip); _getStatusCommand.add("usrname=" + _username); _getStatusCommand.add("password=" + _password, ParamType.PASSWORD); @@ -224,6 +248,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource _powerOnCommand = new Script2(pythonPath, s_logger); _powerOnCommand.add(scriptPath); _powerOnCommand.add("power"); + _powerOnCommand.add("interface=" + ipmiIface); _powerOnCommand.add("hostname=" + _ip); _powerOnCommand.add("usrname=" + _username); _powerOnCommand.add("password=" + _password, ParamType.PASSWORD); @@ -232,6 +257,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource _powerOffCommand = new Script2(pythonPath, s_logger); _powerOffCommand.add(scriptPath); _powerOffCommand.add("power"); + _powerOffCommand.add("interface=" + ipmiIface); _powerOffCommand.add("hostname=" + _ip); _powerOffCommand.add("usrname=" + _username); _powerOffCommand.add("password=" + _password, ParamType.PASSWORD); @@ -240,6 +266,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource _forcePowerOffCommand = new Script2(pythonPath, s_logger); _forcePowerOffCommand.add(scriptPath); _forcePowerOffCommand.add("power"); + _forcePowerOffCommand.add("interface=" + ipmiIface); _forcePowerOffCommand.add("hostname=" + _ip); _forcePowerOffCommand.add("usrname=" + _username); _forcePowerOffCommand.add("password=" + _password, ParamType.PASSWORD); @@ -248,6 +275,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource _bootOrRebootCommand = new Script2(pythonPath, s_logger); _bootOrRebootCommand.add(scriptPath); _bootOrRebootCommand.add("boot_or_reboot"); + _bootOrRebootCommand.add("interface=" + ipmiIface); _bootOrRebootCommand.add("hostname=" + _ip); _bootOrRebootCommand.add("usrname=" + _username); _bootOrRebootCommand.add("password=" + _password, ParamType.PASSWORD); @@ -259,8 +287,15 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource return doScript(cmd, null); } + protected boolean doScript(Script cmd, int retry) { + return doScript(cmd, null, retry); + } + protected boolean doScript(Script cmd, OutputInterpreter interpreter) { - int retry = 5; + return doScript(cmd, interpreter, ipmiRetryTimes); + } + + protected boolean doScript(Script cmd, OutputInterpreter interpreter, int retry) { String res = null; while (retry-- > 0) { if (interpreter == null) { @@ -270,6 +305,10 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource } if (res != null && res.startsWith("Error: Unable to establish LAN")) { s_logger.warn("IPMI script timeout(" + cmd.toString() + "), will retry " + retry + " times"); + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + } continue; } else if (res == null) { return true; @@ -318,7 +357,6 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource protected Map fullSync() { Map states = new HashMap(); if (hostId != null) { - vmDao = ComponentContext.getComponent(VMInstanceDao.class); final List vms = vmDao.listByHostId(hostId); for (VMInstanceVO vm : vms) { states.put(vm.getInstanceName(), vm.getState()); @@ -337,10 +375,14 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource protected Map getHostVmStateReport() { Map states = new HashMap(); if (hostId != null) { - vmDao = ComponentContext.getComponent(VMInstanceDao.class); final List vms = vmDao.listByHostId(hostId); for (VMInstanceVO vm : vms) { - states.put(vm.getInstanceName(), new HostVmStateReportEntry(vm.getState() == State.Running ? PowerState.PowerOn : PowerState.PowerOff, "host-" + hostId)); + states.put( + vm.getInstanceName(), + new HostVmStateReportEntry( + vm.getState() == State.Running ? PowerState.PowerOn : PowerState.PowerOff, "host-" + hostId + ) + ); } } /* @@ -355,7 +397,8 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource @Override public StartupCommand[] initialize() { - StartupRoutingCommand cmd = new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.HypervisorType.BareMetal, new HashMap(), null, null); + StartupRoutingCommand cmd = new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.HypervisorType.BareMetal, + new HashMap(), null, null); cmd.setDataCenter(_zone); cmd.setPod(_pod); @@ -365,13 +408,13 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource cmd.setPrivateIpAddress(_ip); cmd.setStorageIpAddress(_ip); cmd.setVersion(BareMetalResourceBase.class.getPackage().getImplementationVersion()); - cmd.setCpus((int)_cpuNum); + cmd.setCpus((int) _cpuNum); cmd.setSpeed(_cpuCapacity); cmd.setMemory(_memCapacity); cmd.setPrivateMacAddress(_mac); cmd.setPublicMacAddress(_mac); cmd.setStateChanges(fullSync()); - return new StartupCommand[] {cmd}; + return new StartupCommand[] { cmd }; } private boolean ipmiPing() { @@ -393,7 +436,19 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource return null; } - return new PingRoutingCommand(getType(), id, deltaSync(), getHostVmStateReport()); + if (hostId != null) { + final List vms = vmDao.listByHostId(hostId); + if (vms.isEmpty()) { + return new PingRoutingCommand(getType(), id, deltaSync(), getHostVmStateReport()); + } else { + VMInstanceVO vm = vms.get(0); + SecurityGroupHttpClient client = new SecurityGroupHttpClient(); + HashMap> nwGrpStates = client.sync(vm.getInstanceName(), vm.getId(), vm.getPrivateIpAddress()); + return new PingRoutingWithNwGroupsCommand(getType(), id, null, getHostVmStateReport(), nwGrpStates); + } + } else { + return new PingRoutingCommand(getType(), id, deltaSync(), getHostVmStateReport()); + } } protected Answer execute(IpmISetBootDevCommand cmd) { @@ -456,29 +511,29 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource public Answer executeRequest(Command cmd) { try { if (cmd instanceof ReadyCommand) { - return execute((ReadyCommand)cmd); + return execute((ReadyCommand) cmd); } else if (cmd instanceof StartCommand) { - return execute((StartCommand)cmd); + return execute((StartCommand) cmd); } else if (cmd instanceof StopCommand) { - return execute((StopCommand)cmd); + return execute((StopCommand) cmd); } else if (cmd instanceof RebootCommand) { - return execute((RebootCommand)cmd); + return execute((RebootCommand) cmd); } else if (cmd instanceof IpmISetBootDevCommand) { - return execute((IpmISetBootDevCommand)cmd); + return execute((IpmISetBootDevCommand) cmd); } else if (cmd instanceof MaintainCommand) { - return execute((MaintainCommand)cmd); + return execute((MaintainCommand) cmd); } else if (cmd instanceof PrepareForMigrationCommand) { - return execute((PrepareForMigrationCommand)cmd); + return execute((PrepareForMigrationCommand) cmd); } else if (cmd instanceof MigrateCommand) { - return execute((MigrateCommand)cmd); + return execute((MigrateCommand) cmd); } else if (cmd instanceof CheckVirtualMachineCommand) { - return execute((CheckVirtualMachineCommand)cmd); + return execute((CheckVirtualMachineCommand) cmd); } else if (cmd instanceof IpmiBootorResetCommand) { - return execute((IpmiBootorResetCommand)cmd); + return execute((IpmiBootorResetCommand) cmd); } else if (cmd instanceof SecurityGroupRulesCmd) { - return execute((SecurityGroupRulesCmd)cmd); + return execute((SecurityGroupRulesCmd) cmd); } else if (cmd instanceof CheckNetworkCommand) { - return execute((CheckNetworkCommand)cmd); + return execute((CheckNetworkCommand) cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } @@ -499,8 +554,17 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource } protected RebootAnswer execute(final RebootCommand cmd) { - if (!doScript(_rebootCommand)) { - return new RebootAnswer(cmd, "IPMI reboot failed", false); + String infoStr = "Command not supported in present state"; + OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser(); + if (!doScript(_rebootCommand, interpreter, 10)) { + if (interpreter.getLines().contains(infoStr)) { + // try again, this error should be temporary + if (!doScript(_rebootCommand, interpreter, 10)) { + return new RebootAnswer(cmd, "IPMI reboot failed", false); + } + } else { + return new RebootAnswer(cmd, "IPMI reboot failed", false); + } } return new RebootAnswer(cmd, "reboot succeeded", true); @@ -524,7 +588,8 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser(); if (!doScript(_getStatusCommand, interpreter)) { - s_logger.warn("Cannot get power status of " + _name + ", assume VM state was not changed"); + success = true; + s_logger.warn("Cannot get power status of " + _name + ", assume VM state changed successfully"); break; } diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java index 596b84ead20..808c61ecb66 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java @@ -37,7 +37,7 @@ import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; -import com.cloud.exception.InsufficientVirtualNetworkCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -81,7 +81,7 @@ public class BaremetaNetworkGuru extends DirectPodBasedNetworkGuru { @Override public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException { + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { if (dest.getHost().getHypervisorType() != HypervisorType.BareMetal) { super.reserve(nic, network, vm, dest, context); return; @@ -153,7 +153,7 @@ public class BaremetaNetworkGuru extends DirectPodBasedNetworkGuru { s_logger.debug("Allocated a nic " + nic + " for " + vm); } - private void getBaremetalIp(NicProfile nic, Pod pod, VirtualMachineProfile vm, Network network, String requiredIp) throws InsufficientVirtualNetworkCapacityException, + private void getBaremetalIp(NicProfile nic, Pod pod, VirtualMachineProfile vm, Network network, String requiredIp) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { DataCenter dc = _dcDao.findById(pod.getDataCenterId()); if (nic.getIp4Address() == null) { diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java index 8e43d0c3c5e..aab936ce205 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java @@ -93,7 +93,7 @@ public class BaremetalDhcpdResource extends BaremetalDhcpResourceBase { s_logger.debug("Dhcpd resource configure successfully"); return true; } catch (Exception e) { - s_logger.debug("Dhcpd resorce configure failed", e); + s_logger.debug("Dhcpd resource configure failed", e); throw new ConfigurationException(e.getMessage()); } finally { SSHCmdHelper.releaseSshConnection(sshConnection); diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java index 5da52a5c73e..d5a7188cc9e 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java @@ -18,17 +18,7 @@ // Automatically generated by addcopyright.py at 01/29/2013 package com.cloud.baremetal.networkservice; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import javax.ejb.Local; -import javax.inject.Inject; - -import org.apache.log4j.Logger; - import com.cloud.baremetal.database.BaremetalPxeVO; -import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.Pod; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; @@ -57,6 +47,13 @@ import com.cloud.vm.VirtualMachine.Type; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.VMInstanceDao; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.inject.Inject; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; @Local(value = NetworkElement.class) public class BaremetalPxeElement extends AdapterBase implements NetworkElement { @@ -90,7 +87,7 @@ public class BaremetalPxeElement extends AdapterBase implements NetworkElement { private boolean canHandle(DeployDestination dest, TrafficType trafficType, GuestType networkType) { Pod pod = dest.getPod(); - if (pod != null && dest.getDataCenter().getNetworkType() == NetworkType.Basic && trafficType == TrafficType.Guest) { + if (pod != null && trafficType == TrafficType.Guest) { QueryBuilder sc = QueryBuilder.create(BaremetalPxeVO.class); sc.and(sc.entity().getPodId(), Op.EQ, pod.getId()); return sc.find() != null; diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java index ca2f8fe7032..261534a3dd9 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java @@ -193,7 +193,7 @@ public class BaremetalPxeManagerImpl extends ManagerBase implements BaremetalPxe @Override public boolean addUserData(NicProfile nic, VirtualMachineProfile profile) { - UserVmVO vm = (UserVmVO)profile.getVirtualMachine(); + UserVmVO vm = _vmDao.findById(profile.getVirtualMachine().getId()); _vmDao.loadDetails(vm); String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText(); diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java new file mode 100755 index 00000000000..837c615292e --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java @@ -0,0 +1,35 @@ +package com.cloud.baremetal.networkservice; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +/** + * Created by frank on 5/8/14. + */ +public class BaremetalRctResponse extends BaseResponse { + @SerializedName(ApiConstants.ID) + @Param(description = "id of rct") + private String id; + + @SerializedName(ApiConstants.URL) + @Param(description = "url") + private String url; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java index a3998a3bc75..b9e48588950 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java @@ -1,38 +1,205 @@ -// 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. -// -// Automatically generated by addcopyright.py at 01/29/2013 -// Apache License, Version 2.0 (the "License"); you may not use this -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -package com.cloud.baremetal.networkservice; - -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.SecurityGroupRulesCmd; - -public class SecurityGroupHttpClient { - - public Answer call(String guestIp, SecurityGroupRulesCmd cmd) { - // TODO Auto-generated method stub - return null; - } - - public boolean echo(String ip, long millis, long millis2) { - // TODO Auto-generated method stub - return false; - } - -} +// 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. +// +// Automatically generated by addcopyright.py at 01/29/2013 +// Apache License, Version 2.0 (the "License"); you may not use this +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// Automatically generated by addcopyright.py at 04/03/2012 + +package com.cloud.baremetal.networkservice; + +import com.cloud.agent.api.SecurityGroupRuleAnswer; +import com.cloud.agent.api.SecurityGroupRulesCmd; +import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto; +import com.cloud.baremetal.networkservice.schema.SecurityGroupRule; +import com.cloud.baremetal.networkservice.schema.SecurityGroupVmRuleSet; +import com.cloud.utils.Pair; +import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.log4j.Logger; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import java.io.StringWriter; +import java.net.SocketTimeoutException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class SecurityGroupHttpClient { + private static final Logger logger = Logger.getLogger(SecurityGroupHttpClient.class); + private static final String ARG_NAME = "args"; + private static final String COMMAND = "command"; + private JAXBContext context; + private int port; + private static HttpClient httpClient; + static { + MultiThreadedHttpConnectionManager connman = new MultiThreadedHttpConnectionManager(); + httpClient = new HttpClient(connman); + httpClient.setConnectionTimeout(5000); + } + + private enum OpConstant { + setRules, echo, + } + + public SecurityGroupHttpClient() { + try { + context = JAXBContext.newInstance(SecurityGroupRule.class, SecurityGroupVmRuleSet.class); + port = 9988; + } catch (Exception e) { + throw new CloudRuntimeException( + "Unable to create JAXBContext for security group", e); + } + } + + private List generateRules(IpPortAndProto[] ipps) { + List rules = new ArrayList( + ipps.length); + for (SecurityGroupRulesCmd.IpPortAndProto ipp : ipps) { + SecurityGroupRule r = new SecurityGroupRule(); + r.setProtocol(ipp.getProto()); + r.setStartPort(ipp.getStartPort()); + r.setEndPort(ipp.getEndPort()); + for (String cidr : ipp.getAllowedCidrs()) { + r.getIp().add(cidr); + } + rules.add(r); + } + return rules; + } + + public HashMap> sync(String vmName, Long vmId, String agentIp) { + HashMap> states = new HashMap>(); + PostMethod post = new PostMethod(String.format("http://%s:%s/", agentIp, getPort())); + try { + post.addRequestHeader("command", "sync"); + if (httpClient.executeMethod(post) != 200) { + logger.debug(String.format("echoing baremetal security group agent on %s got error: %s", agentIp, post.getResponseBodyAsString())); + } else { + String res = post.getResponseBodyAsString(); + // res = ';'.join([vmName, vmId, seqno]) + String[] rulelogs = res.split(","); + if (rulelogs.length != 6) { + logger.debug(String.format("host[%s] returns invalid security group sync document[%s], reset rules", agentIp, res)); + states.put(vmName, new Pair(vmId, -1L)); + return states; + } + Pair p = new Pair(Long.valueOf(rulelogs[1]), Long.valueOf(rulelogs[5])); + states.put(rulelogs[0], p); + return states; + } + } catch (SocketTimeoutException se) { + logger.warn(String.format("unable to sync security group rules on host[%s], %s", agentIp, se.getMessage())); + } catch (Exception e) { + logger.warn(String.format("unable to sync security group rules on host[%s]", agentIp), e); + } finally { + if (post != null) { + post.releaseConnection(); + } + } + return states; + } + + + public boolean echo(String agentIp, long l, long m) { + boolean ret = false; + int count = 1; + while (true) { + try { + Thread.sleep(m); + count++; + } catch (InterruptedException e1) { + logger.warn("", e1); + break; + } + PostMethod post = new PostMethod(String.format("http://%s:%s/", agentIp, getPort())); + try { + post.addRequestHeader("command", "echo"); + if (httpClient.executeMethod(post) != 200) { + logger.debug(String.format("echoing baremetal security group agent on %s got error: %s", agentIp, post.getResponseBodyAsString())); + } else { + ret = true; + } + break; + } catch (Exception e) { + if (count*m >= l) { + logger.debug(String.format("ping security group agent on vm[%s] timeout after %s minutes, starting vm failed, count=%s", agentIp, TimeUnit.MILLISECONDS.toSeconds(l), count)); + break; + } else { + logger.debug(String.format("Having pinged security group agent on vm[%s] %s times, continue to wait...", agentIp, count)); + } + } finally { + if (post != null) { + post.releaseConnection(); + } + } + } + return ret; + } + + public SecurityGroupRuleAnswer call(String agentIp, SecurityGroupRulesCmd cmd) { + PostMethod post = new PostMethod(String.format( + "http://%s:%s", agentIp, getPort())); + try { + SecurityGroupVmRuleSet rset = new SecurityGroupVmRuleSet(); + rset.getEgressRules().addAll(generateRules(cmd.getEgressRuleSet())); + rset.getIngressRules().addAll( + generateRules(cmd.getIngressRuleSet())); + rset.setVmName(cmd.getVmName()); + rset.setVmIp(cmd.getGuestIp()); + rset.setVmMac(cmd.getGuestMac()); + rset.setVmId(cmd.getVmId()); + rset.setSignature(cmd.getSignature()); + rset.setSequenceNumber(cmd.getSeqNum()); + Marshaller marshaller = context.createMarshaller(); + StringWriter writer = new StringWriter(); + marshaller.marshal(rset, writer); + String xmlContents = writer.toString(); + logger.debug(xmlContents); + + post.addRequestHeader("command", "set_rules"); + StringRequestEntity entity = new StringRequestEntity(xmlContents); + post.setRequestEntity(entity); + if (httpClient.executeMethod(post) != 200) { + return new SecurityGroupRuleAnswer(cmd, false, + post.getResponseBodyAsString()); + } else { + return new SecurityGroupRuleAnswer(cmd); + } + } catch (Exception e) { + return new SecurityGroupRuleAnswer(cmd, false, e.getMessage()); + } finally { + if (post != null) { + post.releaseConnection(); + } + } + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java new file mode 100644 index 00000000000..b5bc694516c --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java @@ -0,0 +1,55 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.11 at 03:24:15 PM PDT +// + + +package com.cloud.baremetal.networkservice.schema; + +import javax.xml.bind.annotation.XmlRegistry; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the com.cloud.network.security.schema package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.cloud.network.security.schema + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link SecurityGroupRule } + * + */ + public SecurityGroupRule createSecurityGroupRule() { + return new SecurityGroupRule(); + } + + /** + * Create an instance of {@link SecurityGroupVmRuleSet } + * + */ + public SecurityGroupVmRuleSet createSecurityGroupVmRuleSet() { + return new SecurityGroupVmRuleSet(); + } + +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java new file mode 100644 index 00000000000..050c3fdee7d --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java @@ -0,0 +1,146 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.11 at 03:24:15 PM PDT +// + + +package com.cloud.baremetal.networkservice.schema; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for SecurityGroupRule complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="SecurityGroupRule">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="protocol" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="startPort" type="{http://www.w3.org/2001/XMLSchema}unsignedInt"/>
+ *         <element name="endPort" type="{http://www.w3.org/2001/XMLSchema}unsignedInt"/>
+ *         <sequence maxOccurs="unbounded" minOccurs="0">
+ *           <element name="ip" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         </sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "SecurityGroupRule", propOrder = { + "protocol", + "startPort", + "endPort", + "ip" +}) +public class SecurityGroupRule { + + @XmlElement(required = true) + protected String protocol; + @XmlSchemaType(name = "unsignedInt") + protected long startPort; + @XmlSchemaType(name = "unsignedInt") + protected long endPort; + protected List ip; + + /** + * Gets the value of the protocol property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getProtocol() { + return protocol; + } + + /** + * Sets the value of the protocol property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setProtocol(String value) { + this.protocol = value; + } + + /** + * Gets the value of the startPort property. + * + */ + public long getStartPort() { + return startPort; + } + + /** + * Sets the value of the startPort property. + * + */ + public void setStartPort(long value) { + this.startPort = value; + } + + /** + * Gets the value of the endPort property. + * + */ + public long getEndPort() { + return endPort; + } + + /** + * Sets the value of the endPort property. + * + */ + public void setEndPort(long value) { + this.endPort = value; + } + + /** + * Gets the value of the ip property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the ip property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getIp().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getIp() { + if (ip == null) { + ip = new ArrayList(); + } + return this.ip; + } + +} diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java new file mode 100644 index 00000000000..2c50c0e24d8 --- /dev/null +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java @@ -0,0 +1,263 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.11 at 03:24:15 PM PDT +// + + +package com.cloud.baremetal.networkservice.schema; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="vmName" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="vmId" type="{http://www.w3.org/2001/XMLSchema}long"/>
+ *         <element name="vmIp" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="vmMac" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="signature" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="sequenceNumber" type="{http://www.w3.org/2001/XMLSchema}long"/>
+ *         <sequence maxOccurs="unbounded" minOccurs="0">
+ *           <element name="ingressRules" type="{}SecurityGroupRule"/>
+ *         </sequence>
+ *         <sequence maxOccurs="unbounded" minOccurs="0">
+ *           <element name="egressRules" type="{}SecurityGroupRule"/>
+ *         </sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "vmName", + "vmId", + "vmIp", + "vmMac", + "signature", + "sequenceNumber", + "ingressRules", + "egressRules" +}) +@XmlRootElement(name = "SecurityGroupVmRuleSet") +public class SecurityGroupVmRuleSet { + + @XmlElement(required = true) + protected String vmName; + protected long vmId; + @XmlElement(required = true) + protected String vmIp; + @XmlElement(required = true) + protected String vmMac; + @XmlElement(required = true) + protected String signature; + protected long sequenceNumber; + protected List ingressRules; + protected List egressRules; + + /** + * Gets the value of the vmName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVmName() { + return vmName; + } + + /** + * Sets the value of the vmName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVmName(String value) { + this.vmName = value; + } + + /** + * Gets the value of the vmId property. + * + */ + public long getVmId() { + return vmId; + } + + /** + * Sets the value of the vmId property. + * + */ + public void setVmId(long value) { + this.vmId = value; + } + + /** + * Gets the value of the vmIp property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVmIp() { + return vmIp; + } + + /** + * Sets the value of the vmIp property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVmIp(String value) { + this.vmIp = value; + } + + /** + * Gets the value of the vmMac property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVmMac() { + return vmMac; + } + + /** + * Sets the value of the vmMac property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVmMac(String value) { + this.vmMac = value; + } + + /** + * Gets the value of the signature property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSignature() { + return signature; + } + + /** + * Sets the value of the signature property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSignature(String value) { + this.signature = value; + } + + /** + * Gets the value of the sequenceNumber property. + * + */ + public long getSequenceNumber() { + return sequenceNumber; + } + + /** + * Sets the value of the sequenceNumber property. + * + */ + public void setSequenceNumber(long value) { + this.sequenceNumber = value; + } + + /** + * Gets the value of the ingressRules property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the ingressRules property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getIngressRules().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link SecurityGroupRule } + * + * + */ + public List getIngressRules() { + if (ingressRules == null) { + ingressRules = new ArrayList(); + } + return this.ingressRules; + } + + /** + * Gets the value of the egressRules property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the egressRules property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getEgressRules().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link SecurityGroupRule } + * + * + */ + public List getEgressRules() { + if (egressRules == null) { + egressRules = new ArrayList(); + } + return this.egressRules; + } + +} diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java new file mode 100755 index 00000000000..554e2ec378d --- /dev/null +++ b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java @@ -0,0 +1,68 @@ +package org.apache.cloudstack.api; + +import com.cloud.baremetal.manager.BaremetalVlanManager; +import com.cloud.baremetal.networkservice.BaremetalRctResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; + +import javax.inject.Inject; + +/** + * Created by frank on 5/8/14. + */ +@APICommand(name = "addBaremetalRct", description = "adds baremetal rack configuration text", responseObject = BaremetalRctResponse.class, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class AddBaremetalRctCmd extends BaseAsyncCmd { + private static final String s_name = "addbaremetalrctresponse"; + public static final Logger s_logger = Logger.getLogger(AddBaremetalRctCmd.class); + + @Inject + private BaremetalVlanManager vlanMgr; + + @Parameter(name=ApiConstants.BAREMETAL_RCT_URL, required = true, description = "http url to baremetal RCT configuration") + private String rctUrl; + + public String getRctUrl() { + return rctUrl; + } + + public void setRctUrl(String rctUrl) { + this.rctUrl = rctUrl; + } + + public String getEventType() { + return EventTypes.EVENT_BAREMETAL_RCT_ADD; + } + + @Override + public String getEventDescription() { + return "Adding baremetal rct configuration"; + } + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { + try { + BaremetalRctResponse rsp = vlanMgr.addRct(this); + this.setResponseObject(rsp); + } catch (Exception e) { + s_logger.warn(String.format("unable to add baremetal RCT[%s]", getRctUrl()), e); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } +}