CLOUDSTACK-6278

Baremetal Advanced Networking support
This commit is contained in:
Frank.Zhang 2014-07-07 11:37:38 -07:00
parent 4be369c94c
commit 7b444183db
30 changed files with 1273 additions and 200 deletions

View File

@ -21,17 +21,17 @@
<parent> <parent>
<groupId>org.apache.cloudstack</groupId> <groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId> <artifactId>cloudstack-plugins</artifactId>
<version>4.5.0-SNAPSHOT</version> <version>4.4.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<artifactId>cloud-plugin-hypervisor-baremetal</artifactId> <artifactId>cloud-plugin-hypervisor-baremetal</artifactId>
<name>Apache CloudStack Plugin - Hypervisor Baremetal</name> <name>Apache CloudStack Plugin - Hypervisor Baremetal</name>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>commons-lang</groupId> <groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId> <artifactId>commons-lang</artifactId>
<version>2.6</version> <version>2.6</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -31,5 +31,5 @@
<property name="name" value="BaremetalGuru" /> <property name="name" value="BaremetalGuru" />
</bean> </bean>
</beans> </beans>

View File

@ -30,5 +30,5 @@
<bean id="BareMetalDiscoverer" class="com.cloud.baremetal.manager.BareMetalDiscoverer"> <bean id="BareMetalDiscoverer" class="com.cloud.baremetal.manager.BareMetalDiscoverer">
<property name="name" value="Bare Metal Agent" /> <property name="name" value="Bare Metal Agent" />
</bean> </bean>
</beans> </beans>

View File

@ -42,5 +42,5 @@
<bean id="BaremetalDhcpManager" <bean id="BaremetalDhcpManager"
class="com.cloud.baremetal.networkservice.BaremetalDhcpManagerImpl" /> class="com.cloud.baremetal.networkservice.BaremetalDhcpManagerImpl" />
</beans> </beans>

View File

@ -30,5 +30,5 @@
<bean id="BareMetalPlanner" class="com.cloud.baremetal.manager.BareMetalPlanner"> <bean id="BareMetalPlanner" class="com.cloud.baremetal.manager.BareMetalPlanner">
<property name="name" value="BareMetalPlanner" /> <property name="name" value="BareMetalPlanner" />
</bean> </bean>
</beans> </beans>

View File

@ -28,6 +28,7 @@
> >
<bean id="BaremetalManager" class="com.cloud.baremetal.manager.BaremetalManagerImpl" /> <bean id="BaremetalManager" class="com.cloud.baremetal.manager.BaremetalManagerImpl" />
<bean id="BaremetalVlanManager" class="com.cloud.baremetal.manager.BaremetalVlanManagerImpl" />
<bean id="BaremetalKickStartPxeService" <bean id="BaremetalKickStartPxeService"
class="com.cloud.baremetal.networkservice.BaremetalKickStartServiceImpl" /> class="com.cloud.baremetal.networkservice.BaremetalKickStartServiceImpl" />
@ -38,5 +39,6 @@
<bean id="baremetalDhcpDaoImpl" class="com.cloud.baremetal.database.BaremetalDhcpDaoImpl" /> <bean id="baremetalDhcpDaoImpl" class="com.cloud.baremetal.database.BaremetalDhcpDaoImpl" />
<bean id="baremetalPxeDaoImpl" class="com.cloud.baremetal.database.BaremetalPxeDaoImpl" /> <bean id="baremetalPxeDaoImpl" class="com.cloud.baremetal.database.BaremetalPxeDaoImpl" />
<bean id="BaremetalRctDaoImpl" class="com.cloud.baremetal.database.BaremetalRctDaoImpl" />
</beans> </beans>

View File

@ -18,9 +18,9 @@
# to you under the Apache License, Version 2.0 (the # to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@ -29,31 +29,31 @@
# under the License. # under the License.
check_status() { check_status() {
pidfile='/var/run/cssgagent.pid' pidfile='/var/run/cssgagent.pid'
if [ ! -f $pidfile ]; then if [ ! -f $pidfile ]; then
echo "cloudstack baremetal security group agent is stopped" echo "cloudstack baremetal security group agent is stopped"
exit 1 exit 1
else else
pid=`cat $pidfile` pid=`cat $pidfile`
ps -p $pid > /dev/null ps -p $pid > /dev/null
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo "cloudstack baremetal security group agent is running, pid is $pid" echo "cloudstack baremetal security group agent is running, pid is $pid"
exit 0 exit 0
else 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" 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 exit 1
fi fi
fi fi
} }
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
echo "usage: $0 echo "usage: $0
[start|stop|restart|status]" [start|stop|restart|status]"
exit 1 exit 1
fi fi
if [ "$@" = "status" ]; then if [ "$@" = "status" ]; then
check_status check_status
else else
python -c "from security_group_agent import cs_sg_agent; cs_sg_agent.main()" $@ python -c "from security_group_agent import cs_sg_agent; cs_sg_agent.main()" $@
fi fi

View File

@ -5,14 +5,14 @@
# to you under the Apache License, Version 2.0 (the # to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
# #
# Automatically generated by addcopyright.py at 01/29/2013 # Automatically generated by addcopyright.py at 01/29/2013

View File

@ -5,16 +5,16 @@
# to you under the Apache License, Version 2.0 (the # to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
# #
# Automatically generated by addcopyright.py at 01/29/2013 # Automatically generated by addcopyright.py at 01/29/2013
''' '''
Created on Jan 2, 2013 Created on Jan 2, 2013
@ -234,4 +234,3 @@ def main():
agentdaemon.restart() agentdaemon.restart()
sys.exit(0) sys.exit(0)

View File

@ -6,16 +6,16 @@
# to you under the Apache License, Version 2.0 (the # to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
# #
# Automatically generated by addcopyright.py at 01/29/2013 # Automatically generated by addcopyright.py at 01/29/2013
import sys, os, time, atexit import sys, os, time, atexit
@ -31,7 +31,7 @@ class Request(object):
self.body = None self.body = None
self.method = None self.method = None
self.query_string = None self.query_string = None
@staticmethod @staticmethod
def from_cherrypy_request(creq): def from_cherrypy_request(creq):
req = Request() req = Request()
@ -40,10 +40,10 @@ class Request(object):
req.method = copy.copy(creq.method) req.method = copy.copy(creq.method)
req.query_string = copy.copy(creq.query_string) if creq.query_string else None req.query_string = copy.copy(creq.query_string) if creq.query_string else None
return req return req
class ShellError(Exception): class ShellError(Exception):
'''shell error''' '''shell error'''
class ShellCmd(object): class ShellCmd(object):
''' '''
classdocs 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) self.process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, executable='/bin/sh', cwd=workdir)
else: else:
self.process = subprocess.Popen(cmd, shell=True, executable='/bin/sh', cwd=workdir) self.process = subprocess.Popen(cmd, shell=True, executable='/bin/sh', cwd=workdir)
self.stdout = None self.stdout = None
self.stderr = None self.stderr = None
self.return_code = None self.return_code = None
def __call__(self, is_exception=True): def __call__(self, is_exception=True):
(self.stdout, self.stderr) = self.process.communicate() (self.stdout, self.stderr) = self.process.communicate()
if is_exception and self.process.returncode != 0: if is_exception and self.process.returncode != 0:
@ -71,18 +71,18 @@ class ShellCmd(object):
err.append('stdout: %s' % self.stdout) err.append('stdout: %s' % self.stdout)
err.append('stderr: %s' % self.stderr) err.append('stderr: %s' % self.stderr)
raise ShellError('\n'.join(err)) raise ShellError('\n'.join(err))
self.return_code = self.process.returncode self.return_code = self.process.returncode
return self.stdout return self.stdout
class Daemon(object): class Daemon(object):
""" """
A generic daemon class. A generic daemon class.
Usage: subclass the Daemon class and override the run() method Usage: subclass the Daemon class and override the run() method
""" """
atexit_hooks = [] atexit_hooks = []
def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
self.stdin = stdin self.stdin = stdin
self.stdout = stdout self.stdout = stdout
@ -102,37 +102,37 @@ class Daemon(object):
content = traceback.format_exc() content = traceback.format_exc()
err = 'Exception when calling atexit hook[%s]\n%s' % (hook.__name__, content) err = 'Exception when calling atexit hook[%s]\n%s' % (hook.__name__, content)
#logger.error(err) #logger.error(err)
def daemonize(self): 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) Programming in the UNIX Environment" for details (ISBN 0201563177)
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
""" """
try: try:
pid = os.fork() pid = os.fork()
if pid > 0: if pid > 0:
# exit first parent # exit first parent
sys.exit(0) sys.exit(0)
except OSError, e: except OSError, e:
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1) sys.exit(1)
# decouple from parent environment # decouple from parent environment
os.chdir("/") os.chdir("/")
os.setsid() os.setsid()
os.umask(0) os.umask(0)
# do second fork # do second fork
try: try:
pid = os.fork() pid = os.fork()
if pid > 0: if pid > 0:
# exit from second parent # exit from second parent
sys.exit(0) sys.exit(0)
except OSError, e: except OSError, e:
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1) sys.exit(1)
# redirect standard file descriptors # redirect standard file descriptors
sys.stdout.flush() sys.stdout.flush()
sys.stderr.flush() sys.stderr.flush()
@ -142,13 +142,13 @@ class Daemon(object):
os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno()) os.dup2(se.fileno(), sys.stderr.fileno())
# write pidfile # write pidfile
Daemon.register_atexit_hook(self.delpid) Daemon.register_atexit_hook(self.delpid)
atexit.register(Daemon._atexit) atexit.register(Daemon._atexit)
pid = str(os.getpid()) pid = str(os.getpid())
file(self.pidfile,'w').write("%s\n" % pid) file(self.pidfile,'w').write("%s\n" % pid)
def delpid(self): def delpid(self):
os.remove(self.pidfile) os.remove(self.pidfile)
@ -163,7 +163,7 @@ class Daemon(object):
pf.close() pf.close()
except IOError: except IOError:
pid = None pid = None
if pid: if pid:
pscmd = ShellCmd('ps -p %s > /dev/null' % pid) pscmd = ShellCmd('ps -p %s > /dev/null' % pid)
pscmd(is_exception=False) pscmd(is_exception=False)
@ -171,7 +171,7 @@ class Daemon(object):
message = "Daemon already running, pid is %s\n" message = "Daemon already running, pid is %s\n"
sys.stderr.write(message % pid) sys.stderr.write(message % pid)
sys.exit(0) sys.exit(0)
# Start the daemon # Start the daemon
self.daemonize() self.daemonize()
try: try:
@ -192,13 +192,13 @@ class Daemon(object):
pf.close() pf.close()
except IOError: except IOError:
pid = None pid = None
if not pid: if not pid:
message = "pidfile %s does not exist. Daemon not running?\n" message = "pidfile %s does not exist. Daemon not running?\n"
sys.stderr.write(message % self.pidfile) sys.stderr.write(message % self.pidfile)
return # not an error in a restart return # not an error in a restart
# Try killing the daemon process # Try killing the daemon process
try: try:
while 1: while 1:
os.kill(pid, SIGTERM) os.kill(pid, SIGTERM)

View File

@ -5,16 +5,16 @@
# to you under the Apache License, Version 2.0 (the # to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
# #
# Automatically generated by addcopyright.py at 01/29/2013 # Automatically generated by addcopyright.py at 01/29/2013
''' '''
Created on Dec 25, 2012 Created on Dec 25, 2012

View File

@ -5,16 +5,16 @@
# to you under the Apache License, Version 2.0 (the # to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
# #
# Automatically generated by addcopyright.py at 01/29/2013 # Automatically generated by addcopyright.py at 01/29/2013
from setuptools import setup, find_packages from setuptools import setup, find_packages
import sys, os import sys, os

View File

@ -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<BaremetalRctVO, Long> {
}

View File

@ -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<BaremetalRctVO, Long> implements BaremetalRctDao {
}

View File

@ -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;
}
}

View File

@ -80,8 +80,8 @@ public class BareMetalDiscoverer extends DiscovererBase implements Discoverer, R
} }
@Override @Override
public Map<? extends ServerResource, Map<String, String>> public Map<? extends ServerResource, Map<String, String>> find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List<String> hostTags)
find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List<String> hostTags) throws DiscoveryException { throws DiscoveryException {
/* Enable this after we decide to use addBaremetalHostCmd instead of addHostCmd /* Enable this after we decide to use addBaremetalHostCmd instead of addHostCmd
String discoverName = _params.get(ApiConstants.BAREMETAL_DISCOVER_NAME); 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 injectScript = "scripts/util/ipmi.py";
String scriptPath = Script.findScript("", injectScript); String scriptPath = Script.findScript("", injectScript);
if (scriptPath == null) { 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); final Script2 command = new Script2(scriptPath, s_logger);
command.add("ping"); command.add("ping");
command.add("hostname=" + ipmiIp); command.add("hostname="+ipmiIp);
command.add("usrname=" + username); command.add("usrname="+username);
command.add("password=" + password, ParamType.PASSWORD); command.add("password="+password, ParamType.PASSWORD);
final String result = command.execute(); final String result = command.execute();
if (result != null) { 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, "******", 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));
result));
return null; return null;
} }
@ -155,21 +155,22 @@ public class BareMetalDiscoverer extends DiscovererBase implements Discoverer, R
params.putAll(_params); params.putAll(_params);
params.put("zone", Long.toString(dcId)); params.put("zone", Long.toString(dcId));
params.put("pod", Long.toString(podId)); params.put("pod", Long.toString(podId));
params.put("cluster", Long.toString(clusterId)); params.put("cluster", Long.toString(clusterId));
params.put("guid", guid); params.put("guid", guid);
params.put(ApiConstants.PRIVATE_IP, ipmiIp); params.put(ApiConstants.PRIVATE_IP, ipmiIp);
params.put(ApiConstants.USERNAME, username); params.put(ApiConstants.USERNAME, username);
params.put(ApiConstants.PASSWORD, password); params.put(ApiConstants.PASSWORD, password);
params.put("vmDao", _vmDao);
params.put("configDao", _configDao);
String resourceClassName = _configDao.getValue(Config.ExternalBaremetalResourceClassName.key()); String resourceClassName = _configDao.getValue(Config.ExternalBaremetalResourceClassName.key());
BareMetalResourceBase resource = null; BareMetalResourceBase resource = null;
if (resourceClassName != null) { if (resourceClassName != null) {
Class<?> clazz = Class.forName(resourceClassName); Class<?> clazz = Class.forName(resourceClassName);
resource = (BareMetalResourceBase)clazz.newInstance(); resource = (BareMetalResourceBase) clazz.newInstance();
String externalUrl = _configDao.getValue(Config.ExternalBaremetalSystemUrl.key()); String externalUrl = _configDao.getValue(Config.ExternalBaremetalSystemUrl.key());
if (externalUrl == null) { if (externalUrl == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(String.format("You must specify ExternalBaremetalSystemUrl in global config page as ExternalBaremetalResourceClassName is not null"));
String.format("You must specify ExternalBaremetalSystemUrl in global config page as ExternalBaremetalResourceClassName is not null"));
} }
details.put(BaremetalManager.ExternalBaremetalSystemUrl, externalUrl); details.put(BaremetalManager.ExternalBaremetalSystemUrl, externalUrl);
} else { } else {
@ -206,8 +207,8 @@ public class BareMetalDiscoverer extends DiscovererBase implements Discoverer, R
zone.setDhcpProvider(Network.Provider.ExternalDhcpServer.getName()); zone.setDhcpProvider(Network.Provider.ExternalDhcpServer.getName());
_dcDao.update(zone.getId(), zone); _dcDao.update(zone.getId(), zone);
s_logger.debug(String.format("Discover Bare Metal host successfully(ip=%1$s, username=%2$s, password=%3%s," 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)); "cpuNum=%4$s, cpuCapacity-%5$s, memCapacity=%6$s)", ipmiIp, username, "******", cpuNum, cpuCapacity, memCapacity));
return resources; return resources;
} catch (Exception e) { } catch (Exception e) {
s_logger.warn("Can not set up bare metal agent", 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 @Override
public void postDiscovery(List<HostVO> hosts, long msId) throws DiscoveryException { public void postDiscovery(List<HostVO> hosts, long msId)
throws DiscoveryException {
} }
@Override @Override
@ -273,6 +275,8 @@ public class BareMetalDiscoverer extends DiscovererBase implements Discoverer, R
HashMap<String, Object> params = super.buildConfigParams(host); HashMap<String, Object> params = super.buildConfigParams(host);
params.put("hostId", host.getId()); params.put("hostId", host.getId());
params.put("ipaddress", host.getPrivateIpAddress()); params.put("ipaddress", host.getPrivateIpAddress());
params.put("vmDao", _vmDao);
params.put("configDao", _configDao);
return params; return params;
} }

View File

@ -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<HostEntry> hosts;
public SwitchEntry getL2Switch() {
return l2Switch;
}
public void setL2Switch(SwitchEntry l2Switch) {
this.l2Switch = l2Switch;
}
public List<HostEntry> getHosts() {
return hosts;
}
public void setHosts(List<HostEntry> hosts) {
this.hosts = hosts;
}
}
private List<Rack> racks;
public List<Rack> getRacks() {
return racks;
}
public void setRacks(List<Rack> racks) {
this.racks = racks;
}
}

View File

@ -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);
}

View File

@ -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<BaremetalRctVO> 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<Class<?>> getCommands() {
List<Class<?>> cmds = new ArrayList<Class<?>>();
cmds.add(AddBaremetalRctCmd.class);
return cmds;
}
}

View File

@ -22,18 +22,6 @@
// Automatically generated by addcopyright.py at 04/03/2012 // Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.baremetal.networkservice; 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.IAgentControl;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckNetworkAnswer; 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.MigrateCommand;
import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingRoutingCommand;
import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
import com.cloud.agent.api.PrepareForMigrationAnswer; import com.cloud.agent.api.PrepareForMigrationAnswer;
import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.ReadyAnswer; 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.baremetal.IpmiBootorResetCommand;
import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.baremetal.manager.BaremetalManager; import com.cloud.baremetal.manager.BaremetalManager;
import com.cloud.configuration.Config;
import com.cloud.host.Host.Type; import com.cloud.host.Host.Type;
import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.Hypervisor;
import com.cloud.resource.ServerResource; 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.component.ManagerBase;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.OutputInterpreter; 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.PowerState;
import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.VMInstanceDao; 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) @Local(value = ServerResource.class)
public class BareMetalResourceBase extends ManagerBase implements ServerResource { public class BareMetalResourceBase extends ManagerBase implements ServerResource {
@ -111,6 +111,9 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
protected Script2 _forcePowerOffCommand; protected Script2 _forcePowerOffCommand;
protected Script2 _bootOrRebootCommand; protected Script2 _bootOrRebootCommand;
protected String _vmName; protected String _vmName;
protected int ipmiRetryTimes = 5;
protected ConfigurationDao configDao;
protected VMInstanceDao vmDao; protected VMInstanceDao vmDao;
private void changeVmState(String vmName, VirtualMachine.State state) { private void changeVmState(String vmName, VirtualMachine.State state) {
@ -128,27 +131,29 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
@Override @Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
_name = name; _name = name;
_uuid = (String)params.get("guid"); _uuid = (String) params.get("guid");
try { try {
_memCapacity = Long.parseLong((String)params.get(ApiConstants.MEMORY)) * 1024L * 1024L; _memCapacity = Long.parseLong((String) params.get(ApiConstants.MEMORY)) * 1024L * 1024L;
_cpuCapacity = Long.parseLong((String)params.get(ApiConstants.CPU_SPEED)); _cpuCapacity = Long.parseLong((String) params.get(ApiConstants.CPU_SPEED));
_cpuNum = Long.parseLong((String)params.get(ApiConstants.CPU_NUMBER)); _cpuNum = Long.parseLong((String) params.get(ApiConstants.CPU_NUMBER));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new ConfigurationException(String.format("Unable to parse number of CPU or memory capacity " 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), + "or cpu capacity(cpu number = %1$s memCapacity=%2$s, cpuCapacity=%3$s", params.get(ApiConstants.CPU_NUMBER),
params.get(ApiConstants.CPU_SPEED))); params.get(ApiConstants.MEMORY), params.get(ApiConstants.CPU_SPEED)));
} }
_zone = (String)params.get("zone"); _zone = (String) params.get("zone");
_pod = (String)params.get("pod"); _pod = (String) params.get("pod");
_cluster = (String)params.get("cluster"); _cluster = (String) params.get("cluster");
hostId = (Long)params.get("hostId"); hostId = (Long) params.get("hostId");
_ip = (String)params.get(ApiConstants.PRIVATE_IP); _ip = (String) params.get(ApiConstants.PRIVATE_IP);
_mac = (String)params.get(ApiConstants.HOST_MAC); _mac = (String) params.get(ApiConstants.HOST_MAC);
_username = (String)params.get(ApiConstants.USERNAME); _username = (String) params.get(ApiConstants.USERNAME);
_password = (String)params.get(ApiConstants.PASSWORD); _password = (String) params.get(ApiConstants.PASSWORD);
_vmName = (String)params.get("vmName"); _vmName = (String) params.get("vmName");
String echoScAgent = (String)params.get(BaremetalManager.EchoSecurityGroupAgent); String echoScAgent = (String) params.get(BaremetalManager.EchoSecurityGroupAgent);
vmDao = (VMInstanceDao) params.get("vmDao");
configDao = (ConfigurationDao) params.get("configDao");
if (_pod == null) { if (_pod == null) {
throw new ConfigurationException("Unable to get the pod"); throw new ConfigurationException("Unable to get the pod");
@ -167,7 +172,8 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
} }
if (_mac.split(":").length != 6) { 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) { if (_uuid == null) {
@ -178,6 +184,19 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
_isEchoScAgent = Boolean.valueOf(echoScAgent); _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 injectScript = "scripts/util/ipmi.py";
String scriptPath = Script.findScript("", injectScript); String scriptPath = Script.findScript("", injectScript);
if (scriptPath == null) { if (scriptPath == null) {
@ -187,6 +206,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
_pingCommand = new Script2(pythonPath, s_logger); _pingCommand = new Script2(pythonPath, s_logger);
_pingCommand.add(scriptPath); _pingCommand.add(scriptPath);
_pingCommand.add("ping"); _pingCommand.add("ping");
_pingCommand.add("interface=" + ipmiIface);
_pingCommand.add("hostname=" + _ip); _pingCommand.add("hostname=" + _ip);
_pingCommand.add("usrname=" + _username); _pingCommand.add("usrname=" + _username);
_pingCommand.add("password=" + _password, ParamType.PASSWORD); _pingCommand.add("password=" + _password, ParamType.PASSWORD);
@ -194,6 +214,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
_setPxeBootCommand = new Script2(pythonPath, s_logger); _setPxeBootCommand = new Script2(pythonPath, s_logger);
_setPxeBootCommand.add(scriptPath); _setPxeBootCommand.add(scriptPath);
_setPxeBootCommand.add("boot_dev"); _setPxeBootCommand.add("boot_dev");
_setPxeBootCommand.add("interface=" + ipmiIface);
_setPxeBootCommand.add("hostname=" + _ip); _setPxeBootCommand.add("hostname=" + _ip);
_setPxeBootCommand.add("usrname=" + _username); _setPxeBootCommand.add("usrname=" + _username);
_setPxeBootCommand.add("password=" + _password, ParamType.PASSWORD); _setPxeBootCommand.add("password=" + _password, ParamType.PASSWORD);
@ -202,6 +223,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
_setDiskBootCommand = new Script2(pythonPath, s_logger); _setDiskBootCommand = new Script2(pythonPath, s_logger);
_setDiskBootCommand.add(scriptPath); _setDiskBootCommand.add(scriptPath);
_setDiskBootCommand.add("boot_dev"); _setDiskBootCommand.add("boot_dev");
_setDiskBootCommand.add("interface=" + ipmiIface);
_setDiskBootCommand.add("hostname=" + _ip); _setDiskBootCommand.add("hostname=" + _ip);
_setDiskBootCommand.add("usrname=" + _username); _setDiskBootCommand.add("usrname=" + _username);
_setDiskBootCommand.add("password=" + _password, ParamType.PASSWORD); _setDiskBootCommand.add("password=" + _password, ParamType.PASSWORD);
@ -210,6 +232,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
_rebootCommand = new Script2(pythonPath, s_logger); _rebootCommand = new Script2(pythonPath, s_logger);
_rebootCommand.add(scriptPath); _rebootCommand.add(scriptPath);
_rebootCommand.add("reboot"); _rebootCommand.add("reboot");
_rebootCommand.add("interface=" + ipmiIface);
_rebootCommand.add("hostname=" + _ip); _rebootCommand.add("hostname=" + _ip);
_rebootCommand.add("usrname=" + _username); _rebootCommand.add("usrname=" + _username);
_rebootCommand.add("password=" + _password, ParamType.PASSWORD); _rebootCommand.add("password=" + _password, ParamType.PASSWORD);
@ -217,6 +240,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
_getStatusCommand = new Script2(pythonPath, s_logger); _getStatusCommand = new Script2(pythonPath, s_logger);
_getStatusCommand.add(scriptPath); _getStatusCommand.add(scriptPath);
_getStatusCommand.add("ping"); _getStatusCommand.add("ping");
_getStatusCommand.add("interface=" + ipmiIface);
_getStatusCommand.add("hostname=" + _ip); _getStatusCommand.add("hostname=" + _ip);
_getStatusCommand.add("usrname=" + _username); _getStatusCommand.add("usrname=" + _username);
_getStatusCommand.add("password=" + _password, ParamType.PASSWORD); _getStatusCommand.add("password=" + _password, ParamType.PASSWORD);
@ -224,6 +248,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
_powerOnCommand = new Script2(pythonPath, s_logger); _powerOnCommand = new Script2(pythonPath, s_logger);
_powerOnCommand.add(scriptPath); _powerOnCommand.add(scriptPath);
_powerOnCommand.add("power"); _powerOnCommand.add("power");
_powerOnCommand.add("interface=" + ipmiIface);
_powerOnCommand.add("hostname=" + _ip); _powerOnCommand.add("hostname=" + _ip);
_powerOnCommand.add("usrname=" + _username); _powerOnCommand.add("usrname=" + _username);
_powerOnCommand.add("password=" + _password, ParamType.PASSWORD); _powerOnCommand.add("password=" + _password, ParamType.PASSWORD);
@ -232,6 +257,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
_powerOffCommand = new Script2(pythonPath, s_logger); _powerOffCommand = new Script2(pythonPath, s_logger);
_powerOffCommand.add(scriptPath); _powerOffCommand.add(scriptPath);
_powerOffCommand.add("power"); _powerOffCommand.add("power");
_powerOffCommand.add("interface=" + ipmiIface);
_powerOffCommand.add("hostname=" + _ip); _powerOffCommand.add("hostname=" + _ip);
_powerOffCommand.add("usrname=" + _username); _powerOffCommand.add("usrname=" + _username);
_powerOffCommand.add("password=" + _password, ParamType.PASSWORD); _powerOffCommand.add("password=" + _password, ParamType.PASSWORD);
@ -240,6 +266,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
_forcePowerOffCommand = new Script2(pythonPath, s_logger); _forcePowerOffCommand = new Script2(pythonPath, s_logger);
_forcePowerOffCommand.add(scriptPath); _forcePowerOffCommand.add(scriptPath);
_forcePowerOffCommand.add("power"); _forcePowerOffCommand.add("power");
_forcePowerOffCommand.add("interface=" + ipmiIface);
_forcePowerOffCommand.add("hostname=" + _ip); _forcePowerOffCommand.add("hostname=" + _ip);
_forcePowerOffCommand.add("usrname=" + _username); _forcePowerOffCommand.add("usrname=" + _username);
_forcePowerOffCommand.add("password=" + _password, ParamType.PASSWORD); _forcePowerOffCommand.add("password=" + _password, ParamType.PASSWORD);
@ -248,6 +275,7 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
_bootOrRebootCommand = new Script2(pythonPath, s_logger); _bootOrRebootCommand = new Script2(pythonPath, s_logger);
_bootOrRebootCommand.add(scriptPath); _bootOrRebootCommand.add(scriptPath);
_bootOrRebootCommand.add("boot_or_reboot"); _bootOrRebootCommand.add("boot_or_reboot");
_bootOrRebootCommand.add("interface=" + ipmiIface);
_bootOrRebootCommand.add("hostname=" + _ip); _bootOrRebootCommand.add("hostname=" + _ip);
_bootOrRebootCommand.add("usrname=" + _username); _bootOrRebootCommand.add("usrname=" + _username);
_bootOrRebootCommand.add("password=" + _password, ParamType.PASSWORD); _bootOrRebootCommand.add("password=" + _password, ParamType.PASSWORD);
@ -259,8 +287,15 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
return doScript(cmd, null); return doScript(cmd, null);
} }
protected boolean doScript(Script cmd, int retry) {
return doScript(cmd, null, retry);
}
protected boolean doScript(Script cmd, OutputInterpreter interpreter) { 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; String res = null;
while (retry-- > 0) { while (retry-- > 0) {
if (interpreter == null) { if (interpreter == null) {
@ -270,6 +305,10 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
} }
if (res != null && res.startsWith("Error: Unable to establish LAN")) { if (res != null && res.startsWith("Error: Unable to establish LAN")) {
s_logger.warn("IPMI script timeout(" + cmd.toString() + "), will retry " + retry + " times"); s_logger.warn("IPMI script timeout(" + cmd.toString() + "), will retry " + retry + " times");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
continue; continue;
} else if (res == null) { } else if (res == null) {
return true; return true;
@ -318,7 +357,6 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
protected Map<String, State> fullSync() { protected Map<String, State> fullSync() {
Map<String, State> states = new HashMap<String, State>(); Map<String, State> states = new HashMap<String, State>();
if (hostId != null) { if (hostId != null) {
vmDao = ComponentContext.getComponent(VMInstanceDao.class);
final List<? extends VMInstanceVO> vms = vmDao.listByHostId(hostId); final List<? extends VMInstanceVO> vms = vmDao.listByHostId(hostId);
for (VMInstanceVO vm : vms) { for (VMInstanceVO vm : vms) {
states.put(vm.getInstanceName(), vm.getState()); states.put(vm.getInstanceName(), vm.getState());
@ -337,10 +375,14 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
protected Map<String, HostVmStateReportEntry> getHostVmStateReport() { protected Map<String, HostVmStateReportEntry> getHostVmStateReport() {
Map<String, HostVmStateReportEntry> states = new HashMap<String, HostVmStateReportEntry>(); Map<String, HostVmStateReportEntry> states = new HashMap<String, HostVmStateReportEntry>();
if (hostId != null) { if (hostId != null) {
vmDao = ComponentContext.getComponent(VMInstanceDao.class);
final List<? extends VMInstanceVO> vms = vmDao.listByHostId(hostId); final List<? extends VMInstanceVO> vms = vmDao.listByHostId(hostId);
for (VMInstanceVO vm : vms) { 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 @Override
public StartupCommand[] initialize() { public StartupCommand[] initialize() {
StartupRoutingCommand cmd = new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.HypervisorType.BareMetal, new HashMap<String, String>(), null, null); StartupRoutingCommand cmd = new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.HypervisorType.BareMetal,
new HashMap<String, String>(), null, null);
cmd.setDataCenter(_zone); cmd.setDataCenter(_zone);
cmd.setPod(_pod); cmd.setPod(_pod);
@ -365,13 +408,13 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
cmd.setPrivateIpAddress(_ip); cmd.setPrivateIpAddress(_ip);
cmd.setStorageIpAddress(_ip); cmd.setStorageIpAddress(_ip);
cmd.setVersion(BareMetalResourceBase.class.getPackage().getImplementationVersion()); cmd.setVersion(BareMetalResourceBase.class.getPackage().getImplementationVersion());
cmd.setCpus((int)_cpuNum); cmd.setCpus((int) _cpuNum);
cmd.setSpeed(_cpuCapacity); cmd.setSpeed(_cpuCapacity);
cmd.setMemory(_memCapacity); cmd.setMemory(_memCapacity);
cmd.setPrivateMacAddress(_mac); cmd.setPrivateMacAddress(_mac);
cmd.setPublicMacAddress(_mac); cmd.setPublicMacAddress(_mac);
cmd.setStateChanges(fullSync()); cmd.setStateChanges(fullSync());
return new StartupCommand[] {cmd}; return new StartupCommand[] { cmd };
} }
private boolean ipmiPing() { private boolean ipmiPing() {
@ -393,7 +436,19 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
return null; return null;
} }
return new PingRoutingCommand(getType(), id, deltaSync(), getHostVmStateReport()); if (hostId != null) {
final List<? extends VMInstanceVO> 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<String, Pair<Long, Long>> 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) { protected Answer execute(IpmISetBootDevCommand cmd) {
@ -456,29 +511,29 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
public Answer executeRequest(Command cmd) { public Answer executeRequest(Command cmd) {
try { try {
if (cmd instanceof ReadyCommand) { if (cmd instanceof ReadyCommand) {
return execute((ReadyCommand)cmd); return execute((ReadyCommand) cmd);
} else if (cmd instanceof StartCommand) { } else if (cmd instanceof StartCommand) {
return execute((StartCommand)cmd); return execute((StartCommand) cmd);
} else if (cmd instanceof StopCommand) { } else if (cmd instanceof StopCommand) {
return execute((StopCommand)cmd); return execute((StopCommand) cmd);
} else if (cmd instanceof RebootCommand) { } else if (cmd instanceof RebootCommand) {
return execute((RebootCommand)cmd); return execute((RebootCommand) cmd);
} else if (cmd instanceof IpmISetBootDevCommand) { } else if (cmd instanceof IpmISetBootDevCommand) {
return execute((IpmISetBootDevCommand)cmd); return execute((IpmISetBootDevCommand) cmd);
} else if (cmd instanceof MaintainCommand) { } else if (cmd instanceof MaintainCommand) {
return execute((MaintainCommand)cmd); return execute((MaintainCommand) cmd);
} else if (cmd instanceof PrepareForMigrationCommand) { } else if (cmd instanceof PrepareForMigrationCommand) {
return execute((PrepareForMigrationCommand)cmd); return execute((PrepareForMigrationCommand) cmd);
} else if (cmd instanceof MigrateCommand) { } else if (cmd instanceof MigrateCommand) {
return execute((MigrateCommand)cmd); return execute((MigrateCommand) cmd);
} else if (cmd instanceof CheckVirtualMachineCommand) { } else if (cmd instanceof CheckVirtualMachineCommand) {
return execute((CheckVirtualMachineCommand)cmd); return execute((CheckVirtualMachineCommand) cmd);
} else if (cmd instanceof IpmiBootorResetCommand) { } else if (cmd instanceof IpmiBootorResetCommand) {
return execute((IpmiBootorResetCommand)cmd); return execute((IpmiBootorResetCommand) cmd);
} else if (cmd instanceof SecurityGroupRulesCmd) { } else if (cmd instanceof SecurityGroupRulesCmd) {
return execute((SecurityGroupRulesCmd)cmd); return execute((SecurityGroupRulesCmd) cmd);
} else if (cmd instanceof CheckNetworkCommand) { } else if (cmd instanceof CheckNetworkCommand) {
return execute((CheckNetworkCommand)cmd); return execute((CheckNetworkCommand) cmd);
} else { } else {
return Answer.createUnsupportedCommandAnswer(cmd); return Answer.createUnsupportedCommandAnswer(cmd);
} }
@ -499,8 +554,17 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
} }
protected RebootAnswer execute(final RebootCommand cmd) { protected RebootAnswer execute(final RebootCommand cmd) {
if (!doScript(_rebootCommand)) { String infoStr = "Command not supported in present state";
return new RebootAnswer(cmd, "IPMI reboot failed", false); 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); return new RebootAnswer(cmd, "reboot succeeded", true);
@ -524,7 +588,8 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser(); OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser();
if (!doScript(_getStatusCommand, interpreter)) { 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; break;
} }

View File

@ -37,7 +37,7 @@ import com.cloud.dc.dao.VlanDao;
import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeployDestination;
import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.Hypervisor.HypervisorType;
@ -81,7 +81,7 @@ public class BaremetaNetworkGuru extends DirectPodBasedNetworkGuru {
@Override @Override
public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) 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) { if (dest.getHost().getHypervisorType() != HypervisorType.BareMetal) {
super.reserve(nic, network, vm, dest, context); super.reserve(nic, network, vm, dest, context);
return; return;
@ -153,7 +153,7 @@ public class BaremetaNetworkGuru extends DirectPodBasedNetworkGuru {
s_logger.debug("Allocated a nic " + nic + " for " + vm); 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 { InsufficientAddressCapacityException, ConcurrentOperationException {
DataCenter dc = _dcDao.findById(pod.getDataCenterId()); DataCenter dc = _dcDao.findById(pod.getDataCenterId());
if (nic.getIp4Address() == null) { if (nic.getIp4Address() == null) {

View File

@ -93,7 +93,7 @@ public class BaremetalDhcpdResource extends BaremetalDhcpResourceBase {
s_logger.debug("Dhcpd resource configure successfully"); s_logger.debug("Dhcpd resource configure successfully");
return true; return true;
} catch (Exception e) { } catch (Exception e) {
s_logger.debug("Dhcpd resorce configure failed", e); s_logger.debug("Dhcpd resource configure failed", e);
throw new ConfigurationException(e.getMessage()); throw new ConfigurationException(e.getMessage());
} finally { } finally {
SSHCmdHelper.releaseSshConnection(sshConnection); SSHCmdHelper.releaseSshConnection(sshConnection);

View File

@ -18,17 +18,7 @@
// Automatically generated by addcopyright.py at 01/29/2013 // Automatically generated by addcopyright.py at 01/29/2013
package com.cloud.baremetal.networkservice; 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.baremetal.database.BaremetalPxeVO;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.Pod; import com.cloud.dc.Pod;
import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeployDestination;
import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConcurrentOperationException;
@ -57,6 +47,13 @@ import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.VMInstanceDao; 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) @Local(value = NetworkElement.class)
public class BaremetalPxeElement extends AdapterBase implements NetworkElement { 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) { private boolean canHandle(DeployDestination dest, TrafficType trafficType, GuestType networkType) {
Pod pod = dest.getPod(); Pod pod = dest.getPod();
if (pod != null && dest.getDataCenter().getNetworkType() == NetworkType.Basic && trafficType == TrafficType.Guest) { if (pod != null && trafficType == TrafficType.Guest) {
QueryBuilder<BaremetalPxeVO> sc = QueryBuilder.create(BaremetalPxeVO.class); QueryBuilder<BaremetalPxeVO> sc = QueryBuilder.create(BaremetalPxeVO.class);
sc.and(sc.entity().getPodId(), Op.EQ, pod.getId()); sc.and(sc.entity().getPodId(), Op.EQ, pod.getId());
return sc.find() != null; return sc.find() != null;

View File

@ -193,7 +193,7 @@ public class BaremetalPxeManagerImpl extends ManagerBase implements BaremetalPxe
@Override @Override
public boolean addUserData(NicProfile nic, VirtualMachineProfile profile) { public boolean addUserData(NicProfile nic, VirtualMachineProfile profile) {
UserVmVO vm = (UserVmVO)profile.getVirtualMachine(); UserVmVO vm = _vmDao.findById(profile.getVirtualMachine().getId());
_vmDao.loadDetails(vm); _vmDao.loadDetails(vm);
String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText(); String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();

View File

@ -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;
}
}

View File

@ -1,38 +1,205 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file // regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the // to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance // "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at // with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, // Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an // software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the // KIND, either express or implied. See the License for the
// specific language governing permissions and limitations // specific language governing permissions and limitations
// under the License. // under the License.
// //
// Automatically generated by addcopyright.py at 01/29/2013 // Automatically generated by addcopyright.py at 01/29/2013
// Apache License, Version 2.0 (the "License"); you may not use this // Apache License, Version 2.0 (the "License"); you may not use this
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
package com.cloud.baremetal.networkservice; //
// Automatically generated by addcopyright.py at 04/03/2012
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.SecurityGroupRulesCmd; package com.cloud.baremetal.networkservice;
public class SecurityGroupHttpClient { import com.cloud.agent.api.SecurityGroupRuleAnswer;
import com.cloud.agent.api.SecurityGroupRulesCmd;
public Answer call(String guestIp, SecurityGroupRulesCmd cmd) { import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto;
// TODO Auto-generated method stub import com.cloud.baremetal.networkservice.schema.SecurityGroupRule;
return null; import com.cloud.baremetal.networkservice.schema.SecurityGroupVmRuleSet;
} import com.cloud.utils.Pair;
import com.cloud.utils.exception.CloudRuntimeException;
public boolean echo(String ip, long millis, long millis2) { import org.apache.commons.httpclient.HttpClient;
// TODO Auto-generated method stub import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
return false; 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<SecurityGroupRule> generateRules(IpPortAndProto[] ipps) {
List<SecurityGroupRule> rules = new ArrayList<SecurityGroupRule>(
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<String, Pair<Long, Long>> sync(String vmName, Long vmId, String agentIp) {
HashMap<String, Pair<Long, Long>> states = new HashMap<String, Pair<Long, Long>>();
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<Long, Long>(vmId, -1L));
return states;
}
Pair<Long, Long> p = new Pair<Long, Long>(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;
}
}

View File

@ -0,0 +1,55 @@
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// 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.
* <p>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();
}
}

View File

@ -0,0 +1,146 @@
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// 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;
/**
* <p>Java class for SecurityGroupRule complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="SecurityGroupRule">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="protocol" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="startPort" type="{http://www.w3.org/2001/XMLSchema}unsignedInt"/>
* &lt;element name="endPort" type="{http://www.w3.org/2001/XMLSchema}unsignedInt"/>
* &lt;sequence maxOccurs="unbounded" minOccurs="0">
* &lt;element name="ip" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;/sequence>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@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<String> 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.
*
* <p>
* 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 <CODE>set</CODE> method for the ip property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getIp().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link String }
*
*
*/
public List<String> getIp() {
if (ip == null) {
ip = new ArrayList<String>();
}
return this.ip;
}
}

View File

@ -0,0 +1,263 @@
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// 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;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType>
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="vmName" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="vmId" type="{http://www.w3.org/2001/XMLSchema}long"/>
* &lt;element name="vmIp" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="vmMac" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="signature" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="sequenceNumber" type="{http://www.w3.org/2001/XMLSchema}long"/>
* &lt;sequence maxOccurs="unbounded" minOccurs="0">
* &lt;element name="ingressRules" type="{}SecurityGroupRule"/>
* &lt;/sequence>
* &lt;sequence maxOccurs="unbounded" minOccurs="0">
* &lt;element name="egressRules" type="{}SecurityGroupRule"/>
* &lt;/sequence>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@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<SecurityGroupRule> ingressRules;
protected List<SecurityGroupRule> 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.
*
* <p>
* 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 <CODE>set</CODE> method for the ingressRules property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getIngressRules().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link SecurityGroupRule }
*
*
*/
public List<SecurityGroupRule> getIngressRules() {
if (ingressRules == null) {
ingressRules = new ArrayList<SecurityGroupRule>();
}
return this.ingressRules;
}
/**
* Gets the value of the egressRules property.
*
* <p>
* 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 <CODE>set</CODE> method for the egressRules property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getEgressRules().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link SecurityGroupRule }
*
*
*/
public List<SecurityGroupRule> getEgressRules() {
if (egressRules == null) {
egressRules = new ArrayList<SecurityGroupRule>();
}
return this.egressRules;
}
}

View File

@ -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();
}
}