You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by fr...@apache.org on 2013/10/09 19:52:56 UTC
[2/2] git commit: updated refs/heads/4.2 to 30a680e
Add missing Baremetal security_group_agent java part
Change security_group_agent python side in line with default security
group rules change in 4.2
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/d31dcdfd
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/d31dcdfd
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/d31dcdfd
Branch: refs/heads/4.2
Commit: d31dcdfd92a47635315a7296b14ce855015045a5
Parents: e256794
Author: Frank.Zhang <fr...@citrix.com>
Authored: Mon Oct 7 18:03:12 2013 -0700
Committer: Frank.Zhang <fr...@citrix.com>
Committed: Wed Oct 9 10:52:42 2013 -0700
----------------------------------------------------------------------
.../security_group_agent/cs_sg_agent.py | 585 ++++++++++++-------
.../security_group_agent/sglib.py | 115 ++--
.../networkservice/BareMetalResourceBase.java | 43 +-
.../networkservice/SecurityGroupHttpClient.java | 259 ++++++--
.../networkservice/schema/ObjectFactory.java | 55 ++
.../schema/SecurityGroupRule.java | 146 +++++
.../schema/SecurityGroupVmRuleSet.java | 263 +++++++++
pom.xml | 2 +
8 files changed, 1150 insertions(+), 318 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d31dcdfd/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py
----------------------------------------------------------------------
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 a292c0b..f940264 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
@@ -16,222 +16,369 @@
# under the License.
#
# Automatically generated by addcopyright.py at 01/29/2013
-'''
-Created on Jan 2, 2013
-
-@author: frank
-'''
-import cherrypy
-import sglib
-import xmlobject
-import types
-import uuid
-import os.path
-import sys
-import os
-
-class SGRule(object):
- def __init__(self):
- self.protocol = None
- self.start_port = None
- self.end_port = None
- self.allowed_ips = []
-
-class IPSet(object):
- IPSET_TYPE = 'hash:ip'
- def __init__(self, setname, ips):
- self.ips = ips
- self.name = setname
-
- def create(self):
- tmpname = str(uuid.uuid4()).replace('-', '')[0:30]
- sglib.ShellCmd('ipset -N %s %s' % (tmpname, self.IPSET_TYPE))()
- try:
- for ip in self.ips:
- sglib.ShellCmd('ipset -A %s %s' % (tmpname, ip))()
-
- try:
- sglib.ShellCmd('ipset -N %s %s' % (self.name, self.IPSET_TYPE))()
- cherrypy.log('created new ipset: %s' % self.name)
- except Exception:
- cherrypy.log('%s already exists, no need to create new' % self.name)
- finally:
- sglib.ShellCmd('ipset -W %s %s' % (tmpname, self.name))()
- sglib.ShellCmd('ipset -F %s' % tmpname)()
- sglib.ShellCmd('ipset -X %s' % tmpname)()
-
- @staticmethod
- def destroy_sets(sets_to_keep):
- sets = sglib.ShellCmd('ipset list')()
- for s in sets.split('\n'):
- if 'Name:' in s:
- set_name = s.split(':', 1)[1].strip()
- if not set_name in sets_to_keep:
- sglib.ShellCmd('ipset destroy %s' % set_name)()
- cherrypy.log('destroyed unused ipset: %s' % set_name)
-
-class SGAgent(object):
- def __init__(self):
- pass
-
- def _self_list(self, obj):
- if isinstance(obj, types.ListType):
- return obj
- else:
- return [obj]
-
- def set_rules(self, req):
- body = req.body
- doc = xmlobject.loads(body)
- vm_name = doc.vmName.text_
- vm_id = doc.vmId.text_
- vm_ip = doc.vmIp.text_
- vm_mac = doc.vmMac.text_
- sig = doc.signature.text_
- seq = doc.sequenceNumber.text_
-
- def parse_rules(rules, lst):
- for i in self._self_list(rules):
- r = SGRule()
- r.protocol = i.protocol.text_
- r.start_port = i.startPort.text_
- r.end_port = i.endPort.text_
- if hasattr(i, 'ip'):
- for ip in self._self_list(i.ip):
- r.allowed_ips.append(ip.text_)
- lst.append(r)
-
- i_rules = []
- if hasattr(doc, 'ingressRules'):
- parse_rules(doc.ingressRules, i_rules)
-
- e_rules = []
- if hasattr(doc, 'egressRules'):
- parse_rules(doc.egressRules, e_rules)
-
- def create_chain(name):
- try:
- sglib.ShellCmd('iptables -F %s' % name)()
- except Exception:
- sglib.ShellCmd('iptables -N %s' % name)()
-
- def apply_rules(rules, chainname, direction, action, current_set_names):
- create_chain(chainname)
- for r in i_rules:
- allow_any = False
- if '0.0.0.0/0' in r.allowed_ips:
- allow_any = True
- r.allowed_ips.remove('0.0.0.0/0')
-
- if r.allowed_ips:
- setname = '_'.join([chainname, r.protocol, r.start_port, r.end_port])
- ipset = IPSet(setname, r.allowed_ips)
- ipset.create()
- current_set_names.append(setname)
-
- if r.protocol == 'all':
- cmd = ['iptables -I', chainname, '-m state --state NEW -m set --set', setname, direction, '-j', action]
- sglib.ShellCmd(' '.join(cmd))()
- elif r.protocol != 'icmp':
- port_range = ":".join([r.start_port, r.end_port])
- cmd = ['iptables', '-I', chainname, '-p', r.protocol, '-m', r.protocol, '--dport', port_range, '-m state --state NEW -m set --set', setname, direction, '-j', action]
- sglib.ShellCmd(' '.join(cmd))()
- else:
- port_range = "/".join([r.start_port, r.end_port])
- if r.start_port == "-1":
- port_range = "any"
- cmd = ['iptables', '-I', i_chain_name, '-p', 'icmp', '--icmp-type', port_range, '-m set --set', setname, direction, '-j', action]
- sglib.ShellCmd(' '.join(cmd))()
-
-
- if allow_any and r.protocol != 'all':
- if r.protocol != 'icmp':
- port_range = ":".join([r.start_port, r.end_port])
- cmd = ['iptables', '-I', chainname, '-p', r.protocol, '-m', r.protocol, '--dport', port_range, '-m', 'state', '--state', 'NEW', '-j', action]
- sglib.ShellCmd(' '.join(cmd))()
- else:
- port_range = "/".join([r.start_port, r.end_port])
- if r.start_port == "-1":
- port_range = "any"
- cmd = ['iptables', '-I', i_chain_name, '-p', 'icmp', '--icmp-type', port_range, '-j', action]
- sglib.ShellCmd(' '.join(cmd))()
-
- current_sets = []
- i_chain_name = vm_name + '-in'
- apply_rules(i_rules, i_chain_name, 'src', 'ACCEPT', current_sets)
- e_chain_name = vm_name + '-eg'
- apply_rules(e_rules, e_chain_name, 'dst', 'RETURN', current_sets)
-
- if e_rules:
- sglib.ShellCmd('iptables -A %s -j RETURN' % e_chain_name)
- else:
- sglib.ShellCmd('iptables -A %s -j DROP' % e_chain_name)
-
- sglib.ShellCmd('iptables -A %s -j DROP' % i_chain_name)
- IPSet.destroy_sets(current_sets)
-
-
- def echo(self, req):
- cherrypy.log("echo: I am alive")
-
- def index(self):
- req = sglib.Request.from_cherrypy_request(cherrypy.request)
- cmd_name = req.headers['command']
-
- if not hasattr(self, cmd_name):
- raise ValueError("SecurityGroupAgent doesn't have a method called '%s'" % cmd_name)
- method = getattr(self, cmd_name)
-
- return method(req)
- index.exposed = True
-
- @staticmethod
- def start():
- cherrypy.log.access_file = '/var/log/cs-securitygroup.log'
- cherrypy.log.error_file = '/var/log/cs-securitygroup.log'
- cherrypy.server.socket_host = '0.0.0.0'
- cherrypy.server.socket_port = 9988
- cherrypy.quickstart(SGAgent())
-
- @staticmethod
- def stop():
- cherrypy.engine.exit()
-
-PID_FILE = '/var/run/cssgagent.pid'
-class SGAgentDaemon(sglib.Daemon):
- def __init__(self):
- super(SGAgentDaemon, self).__init__(PID_FILE)
- self.is_stopped = False
- self.agent = SGAgent()
- sglib.Daemon.register_atexit_hook(self._do_stop)
-
- def _do_stop(self):
- if self.is_stopped:
- return
- self.is_stopped = True
- self.agent.stop()
-
- def run(self):
- self.agent.start()
-
- def stop(self):
- self.agent.stop()
- super(SGAgentDaemon, self).stop()
-
-def main():
- usage = 'usage: python -c "from security_group_agent import cs_sg_agent; cs_sg_agent.main()" start|stop|restart'
- if len(sys.argv) != 2 or not sys.argv[1] in ['start', 'stop', 'restart']:
- print usage
- sys.exit(1)
-
- cmd = sys.argv[1]
- agentdaemon = SGAgentDaemon()
- if cmd == 'start':
- agentdaemon.start()
- elif cmd == 'stop':
- agentdaemon.stop()
- else:
- agentdaemon.restart()
-
- sys.exit(0)
-
\ No newline at end of file
+
+'''
+Created on Jan 2, 2013
+
+@author: frank
+'''
+import cherrypy
+import sglib
+import xmlobject
+import types
+import uuid
+import os.path
+import sys
+import os
+
+class SGRule(object):
+ def __init__(self):
+ self.protocol = None
+ self.start_port = None
+ self.end_port = None
+ self.allowed_ips = []
+
+# iptables -D cannot handle rules having ipset match
+# we have to delete these rules by line number that's why I introduce
+# this class that maintains rules with their line number
+class IptableChain(object):
+ def __init__(self):
+ self.name = None
+ self.rules = {}
+
+ def delete_rule_by_line_number(self, num):
+ if str(num) not in self.rules.values():
+ return
+
+ sglib.ShellCmd('iptables -D %s %s' % (self.name, num))()
+
+ @staticmethod
+ def from_iptable_lists():
+ txt= sglib.ShellCmd('iptables --list --line-number')()
+ blocks = txt.split('\n')
+
+ def is_rule_line(rule):
+ def is_number(n):
+ try:
+ int(n)
+ return True
+ except Exception:
+ return False
+
+ words = rule.split()
+ return is_number(words[0])
+
+ current_chain = None
+ chains = []
+ for line in blocks:
+ line = line.strip()
+ if line == '':
+ continue
+
+ if line.startswith('Chain'):
+ current_chain = IptableChain()
+ current_chain.name = line.split()[1]
+ chains.append(current_chain)
+ continue
+
+ if not is_rule_line(line):
+ continue
+
+ specs = line.split(None, 6)
+ if len(specs) == 7:
+ # e.g '1 RETURN tcp -- anywhere anywhere tcp dpt:https state NEW match-set i-4-32-VM-eg_tcp_443_443 dst'
+ # the last part is spec, using spec as key
+ current_chain.rules[specs[-1]] = specs[0]
+ else:
+ # e.g '3 DROP all -- anywhere anywhere'
+ # no spec, using target as key
+ current_chain.rules[specs[1]] = specs[0]
+
+ return chains
+
+
+
+class IPSet(object):
+ IPSET_TYPE = 'hash:net'
+ def __init__(self, setname, ips):
+ self.ips = ips
+ self.name = setname
+
+ def create(self):
+ tmpname = str(uuid.uuid4()).replace('-', '')[0:30]
+ sglib.ShellCmd('ipset -N %s %s' % (tmpname, self.IPSET_TYPE))()
+ try:
+ for ip in self.ips:
+ sglib.ShellCmd('ipset -A %s %s' % (tmpname, ip))()
+
+ try:
+ sglib.ShellCmd('ipset -N %s %s' % (self.name, self.IPSET_TYPE))()
+ cherrypy.log('created ip set as: \nname: %s\nips: %s\n' % (self.name, self.ips))
+ except Exception:
+ cherrypy.log('%s already exists, no need to create new' % self.name)
+ finally:
+ sglib.ShellCmd('ipset -W %s %s' % (tmpname, self.name))()
+ sglib.ShellCmd('ipset -F %s' % tmpname)()
+ sglib.ShellCmd('ipset -X %s' % tmpname)()
+
+ @staticmethod
+ def destroy_sets_not_in(sets_to_keep):
+ def remove_iptable_rules_having_set_name(setname):
+ chains = IptableChain.from_iptable_lists()
+ for c in chains:
+ for spec, linenum in c.rules.items():
+ if setname in spec:
+ c.delete_rule_by_line_number(linenum)
+ # as line number will change each time after deleting a rule,
+ # we have to retrieve all chains again
+ # this shows that old solid tools also have old bad user experience
+ remove_iptable_rules_having_set_name(setname)
+ return
+
+ sets = sglib.ShellCmd('ipset list')()
+ for s in sets.split('\n'):
+ if 'Name:' in s:
+ set_name = s.split(':', 1)[1].strip()
+ if not set_name in sets_to_keep:
+ remove_iptable_rules_having_set_name(set_name)
+ sglib.ShellCmd('ipset destroy %s' % set_name)()
+ cherrypy.log('destroyed unused ipset: %s' % set_name)
+
+class SGAgent(object):
+ RULE_HISTORY_PTH = '/var/lib/cloudstack/cs-agent.history'
+
+ def __init__(self):
+ history_dir = os.path.dirname(self.RULE_HISTORY_PTH)
+ if not os.path.exists(history_dir):
+ os.makedirs(history_dir, 0755)
+
+ def _self_list(self, obj):
+ if isinstance(obj, types.ListType):
+ return obj
+ else:
+ return [obj]
+
+ def sync(self, req):
+ if not os.path.exists(self.RULE_HISTORY_PTH):
+ return ''
+
+ with open(self.RULE_HISTORY_PTH, 'r') as fd:
+ history = fd.read()
+
+ cherrypy.log('sync: %s' % history)
+ return history
+
+ def create_rule_if_not_exists(self, rule):
+ out = sglib.ShellCmd('iptables-save')()
+ if rule in out:
+ return
+
+ sglib.ShellCmd('iptables %s' % rule)()
+
+ @sglib.lock('set_rules')
+ def set_rules(self, req):
+ body = req.body
+ cherrypy.log('received security group rules as:\n%s\n' % body)
+ doc = xmlobject.loads(body)
+ vm_name = doc.vmName.text_
+ vm_id = doc.vmId.text_
+ vm_ip = doc.vmIp.text_
+ vm_mac = doc.vmMac.text_
+ sig = doc.signature.text_
+ seq = doc.sequenceNumber.text_
+
+ def parse_rules(rules, lst):
+ for i in self._self_list(rules):
+ r = SGRule()
+ r.protocol = i.protocol.text_
+ r.start_port = i.startPort.text_
+ r.end_port = i.endPort.text_
+ if hasattr(i, 'ip'):
+ for ip in self._self_list(i.ip):
+ r.allowed_ips.append(ip.text_)
+ lst.append(r)
+
+ i_rules = []
+ if hasattr(doc, 'ingressRules'):
+ parse_rules(doc.ingressRules, i_rules)
+
+ e_rules = []
+ if hasattr(doc, 'egressRules'):
+ parse_rules(doc.egressRules, e_rules)
+
+ def create_chain(name):
+ try:
+ sglib.ShellCmd('iptables -F %s' % name)()
+ except Exception:
+ sglib.ShellCmd('iptables -N %s' % name)()
+
+ def delete_chain(name):
+ try:
+ sglib.ShellCmd('iptables -F %s' % name)()
+
+ try:
+ sglib.ShellCmd('iptables -D INPUT -j %s' % name)()
+ except:
+ pass
+
+ try:
+ sglib.ShellCmd('iptables -D OUTPUT -j %s' % name)()
+ except:
+ pass
+
+ try:
+ sglib.ShellCmd('iptables -D %s -p tcp --dport 9988 -j ACCEPT' % name)()
+ except:
+ pass
+
+ sglib.ShellCmd('iptables -X %s' % name)()
+
+ cherrypy.log('deleted chain %s' % name)
+ except:
+ # safely ignore error
+ pass
+
+ def apply_rules(rules, chainname, direction, action, current_set_names):
+ for r in rules:
+ allow_any = False
+ if '0.0.0.0/0' in r.allowed_ips:
+ allow_any = True
+ r.allowed_ips.remove('0.0.0.0/0')
+
+ if r.allowed_ips:
+ setname = '_'.join([chainname, r.protocol, r.start_port, r.end_port])
+ ipset = IPSet(setname, r.allowed_ips)
+ ipset.create()
+ current_set_names.append(setname)
+
+ if r.protocol == 'all':
+ cmd = ['iptables -I', chainname, '-m state --state NEW -m set --set', setname, direction, '-j', action]
+ sglib.ShellCmd(' '.join(cmd))()
+ elif r.protocol != 'icmp':
+ port_range = ":".join([r.start_port, r.end_port])
+ cmd = ['iptables', '-I', chainname, '-p', r.protocol, '-m', r.protocol, '--dport', port_range, '-m state --state NEW -m set --set', setname, direction, '-j', action]
+ sglib.ShellCmd(' '.join(cmd))()
+ else:
+ port_range = "/".join([r.start_port, r.end_port])
+ if r.start_port == "-1":
+ port_range = "any"
+ cmd = ['iptables', '-I', chainname, '-p', 'icmp', '--icmp-type', port_range, '-m set --set', setname, direction, '-j', action]
+ sglib.ShellCmd(' '.join(cmd))()
+
+
+ if allow_any and r.protocol != 'all':
+ if r.protocol != 'icmp':
+ port_range = ":".join([r.start_port, r.end_port])
+ cmd = ['iptables', '-I', chainname, '-p', r.protocol, '-m', r.protocol, '--dport', port_range, '-m', 'state', '--state', 'NEW', '-j', action]
+ sglib.ShellCmd(' '.join(cmd))()
+ else:
+ port_range = "/".join([r.start_port, r.end_port])
+ if r.start_port == "-1":
+ port_range = "any"
+ cmd = ['iptables', '-I', chainname, '-p', 'icmp', '--icmp-type', port_range, '-j', action]
+ sglib.ShellCmd(' '.join(cmd))()
+
+ current_sets = []
+ i_chain_name = vm_name + '-in'
+ if i_rules:
+ create_chain(i_chain_name)
+ self.create_rule_if_not_exists('-A INPUT -j %s' % i_chain_name)
+ sglib.ShellCmd('iptables -A %s -p tcp --dport 9988 -j ACCEPT' % i_chain_name)()
+ sglib.ShellCmd('iptables -A %s -m state --state RELATED,ESTABLISHED -j ACCEPT' % i_chain_name)()
+ apply_rules(i_rules, i_chain_name, 'src', 'ACCEPT', current_sets)
+ sglib.ShellCmd('iptables -A %s -j DROP' % i_chain_name)()
+ else:
+ delete_chain(i_chain_name)
+
+ e_chain_name = vm_name + '-eg'
+ if e_rules:
+ create_chain(e_chain_name)
+ self.create_rule_if_not_exists('-A OUTPUT -j %s' % e_chain_name)
+ sglib.ShellCmd('iptables -A %s -m state --state RELATED,ESTABLISHED -j RETURN' % e_chain_name)()
+ apply_rules(e_rules, e_chain_name, 'dst', 'RETURN', current_sets)
+ sglib.ShellCmd('iptables -A %s -j DROP' % e_chain_name)
+ else:
+ delete_chain(e_chain_name)
+
+ IPSet.destroy_sets_not_in(current_sets)
+
+ history = ','.join([vm_name, vm_id, vm_ip, '_', sig, seq])
+ with open(self.RULE_HISTORY_PTH, 'w') as fd:
+ fd.write(history)
+
+
+ def echo(self, req):
+ cherrypy.log("echo: I am alive")
+
+ def index(self):
+ req = sglib.Request.from_cherrypy_request(cherrypy.request)
+ cmd_name = req.headers['command']
+
+ if not hasattr(self, cmd_name):
+ raise ValueError("SecurityGroupAgent doesn't have a method called '%s'" % cmd_name)
+ method = getattr(self, cmd_name)
+
+ return method(req)
+ index.exposed = True
+
+ @staticmethod
+ def start():
+ def prepare_default_rules():
+ sglib.ShellCmd('iptables --policy INPUT DROP')()
+ name = 'default-chain'
+ try:
+ sglib.ShellCmd('iptables -F %s' % name)()
+ except Exception:
+ sglib.ShellCmd('iptables -N %s' % name)()
+ sglib.ShellCmd('iptables -I INPUT -p tcp --dport 9988 -j ACCEPT')()
+
+
+ prepare_default_rules()
+ cherrypy.log.access_file = '/var/log/cs-securitygroup.log'
+ cherrypy.log.error_file = '/var/log/cs-securitygroup.log'
+ cherrypy.server.socket_host = '0.0.0.0'
+ cherrypy.server.socket_port = 9988
+ cherrypy.quickstart(SGAgent())
+
+ @staticmethod
+ def stop():
+ cherrypy.engine.exit()
+
+PID_FILE = '/var/run/cssgagent.pid'
+class SGAgentDaemon(sglib.Daemon):
+ def __init__(self):
+ super(SGAgentDaemon, self).__init__(PID_FILE)
+ self.is_stopped = False
+ self.agent = SGAgent()
+ sglib.Daemon.register_atexit_hook(self._do_stop)
+
+ def _do_stop(self):
+ if self.is_stopped:
+ return
+ self.is_stopped = True
+ self.agent.stop()
+
+ def run(self):
+ self.agent.start()
+
+ def stop(self):
+ self.agent.stop()
+ super(SGAgentDaemon, self).stop()
+
+def main():
+ usage = 'usage: python -c "from security_group_agent import cs_sg_agent; cs_sg_agent.main()" start|stop|restart'
+ if len(sys.argv) != 2 or not sys.argv[1] in ['start', 'stop', 'restart']:
+ print usage
+ sys.exit(1)
+
+ cmd = sys.argv[1]
+ agentdaemon = SGAgentDaemon()
+ if cmd == 'start':
+ agentdaemon.start()
+ elif cmd == 'stop':
+ agentdaemon.stop()
+ else:
+ agentdaemon.restart()
+
+ sys.exit(0)
+
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d31dcdfd/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py
----------------------------------------------------------------------
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 bf64eff..b4a39eb 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
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
@@ -18,13 +17,55 @@
#
# Automatically generated by addcopyright.py at 01/29/2013
-import sys, os, time, atexit
-import traceback
+#!/usr/bin/env python
+
+import sys, os, time, atexit
+import traceback
import subprocess
-from signal import SIGTERM
+from signal import SIGTERM,SIGKILL
import cherrypy
import copy
+import weakref
+import threading
+import functools
+
+_internal_lock = threading.RLock()
+_locks = weakref.WeakValueDictionary()
+
+def _get_lock(name):
+ with _internal_lock:
+ lock = _locks.get(name, threading.RLock())
+ if not name in _locks:
+ _locks[name] = lock
+ return lock
+
+class NamedLock(object):
+ def __init__(self, name):
+ self.name = name
+ self.lock = None
+
+ def __enter__(self):
+ self.lock = _get_lock(self.name)
+ self.lock.acquire()
+ #logger.debug('%s got lock %s' % (threading.current_thread().name, self.name))
+
+ def __exit__(self, type, value, traceback):
+ self.lock.release()
+ #logger.debug('%s released lock %s' % (threading.current_thread().name, self.name))
+
+
+def lock(name='defaultLock'):
+ def wrap(f):
+ @functools.wraps(f)
+ def inner(*args, **kwargs):
+ with NamedLock(name):
+ retval = f(*args, **kwargs)
+ return retval
+ return inner
+ return wrap
+
+
class Request(object):
def __init__(self):
self.headers = None
@@ -80,28 +121,28 @@ class Daemon(object):
A generic daemon class.
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'):
self.stdin = stdin
self.stdout = stdout
self.stderr = stderr
self.pidfile = pidfile
-
- @staticmethod
- def register_atexit_hook(hook):
- Daemon.atexit_hooks.append(hook)
-
+
@staticmethod
- def _atexit():
- for hook in Daemon.atexit_hooks:
- try:
+ def register_atexit_hook(hook):
+ Daemon.atexit_hooks.append(hook)
+
+ @staticmethod
+ def _atexit():
+ for hook in Daemon.atexit_hooks:
+ try:
hook()
- except Exception:
+ except Exception:
content = traceback.format_exc()
- err = 'Exception when calling atexit hook[%s]\n%s' % (hook.__name__, content)
- #logger.error(err)
+ err = 'Exception when calling atexit hook[%s]\n%s' % (hook.__name__, content)
+ #logger.error(err)
def daemonize(self):
"""
@@ -145,7 +186,7 @@ class Daemon(object):
# write pidfile
Daemon.register_atexit_hook(self.delpid)
- atexit.register(Daemon._atexit)
+ atexit.register(Daemon._atexit)
pid = str(os.getpid())
file(self.pidfile,'w').write("%s\n" % pid)
@@ -173,12 +214,12 @@ class Daemon(object):
sys.exit(0)
# Start the daemon
- self.daemonize()
+ self.daemonize()
try:
- self.run()
- except Exception:
- content = traceback.format_exc()
- #logger.error(content)
+ self.run()
+ except Exception:
+ content = traceback.format_exc()
+ #logger.error(content)
sys.exit(1)
def stop(self):
@@ -192,25 +233,29 @@ 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:
- while 1:
- os.kill(pid, SIGTERM)
- time.sleep(0.1)
- except OSError, err:
- err = str(err)
- if err.find("No such process") > 0:
- if os.path.exists(self.pidfile):
- os.remove(self.pidfile)
+ wait_stop = 5
+ start_time = time.time()
+ while 1:
+ if os.path.exists('/proc/' + str(pid)):
+ curr_time = time.time()
+ if (curr_time - start_time) > wait_stop:
+ os.kill(pid, SIGKILL)
+ else:
+ os.kill(pid, SIGTERM)
+ time.sleep(0.3)
else:
- print str(err)
- sys.exit(1)
+ if os.path.exists(self.pidfile):
+ self.delpid()
+ break
+
+ print "Stop Daemon Successfully"
def restart(self):
"""
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d31dcdfd/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java
----------------------------------------------------------------------
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 d46048e..f4e4463 100755
--- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java
@@ -29,35 +29,12 @@ import java.util.Map;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
+import com.cloud.agent.api.*;
+import com.cloud.utils.Pair;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.log4j.Logger;
import com.cloud.agent.IAgentControl;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CheckNetworkAnswer;
-import com.cloud.agent.api.CheckNetworkCommand;
-import com.cloud.agent.api.CheckVirtualMachineAnswer;
-import com.cloud.agent.api.CheckVirtualMachineCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.MaintainAnswer;
-import com.cloud.agent.api.MaintainCommand;
-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.PrepareForMigrationAnswer;
-import com.cloud.agent.api.PrepareForMigrationCommand;
-import com.cloud.agent.api.ReadyAnswer;
-import com.cloud.agent.api.ReadyCommand;
-import com.cloud.agent.api.RebootAnswer;
-import com.cloud.agent.api.RebootCommand;
-import com.cloud.agent.api.SecurityGroupRulesCmd;
-import com.cloud.agent.api.StartAnswer;
-import com.cloud.agent.api.StartCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.api.StopAnswer;
-import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.baremetal.IpmISetBootDevCommand;
import com.cloud.agent.api.baremetal.IpmISetBootDevCommand.BootDev;
import com.cloud.agent.api.baremetal.IpmiBootorResetCommand;
@@ -373,7 +350,21 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource
return null;
}
- return new PingRoutingCommand(getType(), id, deltaSync());
+
+ if (hostId != null) {
+ vmDao = ComponentContext.getComponent(VMInstanceDao.class);
+ final List<? extends VMInstanceVO> vms = vmDao.listByHostId(hostId);
+ if (vms.isEmpty()) {
+ return new PingRoutingCommand(getType(), id, deltaSync());
+ } 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, nwGrpStates);
+ }
+ } else {
+ return new PingRoutingCommand(getType(), id, deltaSync());
+ }
}
protected Answer execute(IpmISetBootDevCommand cmd) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d31dcdfd/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java
----------------------------------------------------------------------
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 b9c2e84..8e27a44 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,221 @@
-// 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 java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.SocketTimeoutException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.zip.DeflaterOutputStream;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+
+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 com.cloud.utils.net.NetUtils;
+
+import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
+
+import org.apache.commons.codec.binary.Base64;
+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.http.params.BasicHttpParams;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+import org.apache.log4j.Logger;
+
+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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d31dcdfd/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java
----------------------------------------------------------------------
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 0000000..d0944ce
--- /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 <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();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d31dcdfd/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java
----------------------------------------------------------------------
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 0000000..a8958dd
--- /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 <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>
+ * <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>
+ * </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;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d31dcdfd/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java
----------------------------------------------------------------------
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 0000000..7ad13ce
--- /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 <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>
+ * <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>
+ * </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;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d31dcdfd/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 7da0751..567bd60 100644
--- a/pom.xml
+++ b/pom.xml
@@ -510,7 +510,9 @@
</properties>
<modules>
<module>developer</module>
+ <!--
<module>tools</module>
+-->
</modules>
</profile>
<profile>