Return-Path: X-Original-To: apmail-cloudstack-commits-archive@www.apache.org Delivered-To: apmail-cloudstack-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 0F03610CF2 for ; Thu, 5 Dec 2013 18:50:24 +0000 (UTC) Received: (qmail 49485 invoked by uid 500); 5 Dec 2013 18:50:23 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 49465 invoked by uid 500); 5 Dec 2013 18:50:23 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 49458 invoked by uid 99); 5 Dec 2013 18:50:23 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 05 Dec 2013 18:50:23 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 4C87A82C097; Thu, 5 Dec 2013 18:50:21 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: frankzhang@apache.org To: commits@cloudstack.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: git commit: updated refs/heads/4.3 to fb1f3f0 Date: Thu, 5 Dec 2013 18:50:21 +0000 (UTC) Updated Branches: refs/heads/4.3 c05541758 -> fb1f3f086 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 Conflicts: plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/fb1f3f08 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/fb1f3f08 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/fb1f3f08 Branch: refs/heads/4.3 Commit: fb1f3f0865c254abebfa5a43f66cef116fe36165 Parents: c055417 Author: Frank.Zhang Authored: Mon Oct 7 18:03:12 2013 -0700 Committer: Frank.Zhang Committed: Thu Dec 5 10:50:25 2013 -0800 ---------------------------------------------------------------------- .../security_group_agent/cs_sg_agent.py | 585 ++++++++++++------- .../security_group_agent/sglib.py | 115 ++-- .../networkservice/BareMetalResourceBase.java | 18 +- .../networkservice/SecurityGroupHttpClient.java | 258 ++++++-- .../networkservice/schema/ObjectFactory.java | 55 ++ .../schema/SecurityGroupRule.java | 146 +++++ .../schema/SecurityGroupVmRuleSet.java | 263 +++++++++ pom.xml | 2 + 8 files changed, 1149 insertions(+), 293 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fb1f3f08/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/fb1f3f08/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/fb1f3f08/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 2418a19..edf3d39 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java @@ -30,6 +30,9 @@ import java.util.concurrent.TimeUnit; 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 org.apache.cloudstack.api.ApiConstants; @@ -399,7 +402,20 @@ public class BareMetalResourceBase extends ManagerBase implements ServerResource return null; } - return new PingRoutingCommand(getType(), id, deltaSync(), getHostVmStateReport()); + if (hostId != null) { + vmDao = ComponentContext.getComponent(VMInstanceDao.class); + final List vms = vmDao.listByHostId(hostId); + if (vms.isEmpty()) { + return new PingRoutingCommand(getType(), id, deltaSync(), getHostVmStateReport()); + } else { + VMInstanceVO vm = vms.get(0); + SecurityGroupHttpClient client = new SecurityGroupHttpClient(); + HashMap> nwGrpStates = client.sync(vm.getInstanceName(), vm.getId(), vm.getPrivateIpAddress()); + return new PingRoutingWithNwGroupsCommand(getType(), id, null, getHostVmStateReport(), nwGrpStates); + } + } else { + return new PingRoutingCommand(getType(), id, deltaSync(), getHostVmStateReport()); + } } protected Answer execute(IpmISetBootDevCommand cmd) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fb1f3f08/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..efd4f2b 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,220 @@ -// 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.concurrent.TimeUnit; +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 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 generateRules(IpPortAndProto[] ipps) { + List rules = new ArrayList( + ipps.length); + for (SecurityGroupRulesCmd.IpPortAndProto ipp : ipps) { + SecurityGroupRule r = new SecurityGroupRule(); + r.setProtocol(ipp.getProto()); + r.setStartPort(ipp.getStartPort()); + r.setEndPort(ipp.getEndPort()); + for (String cidr : ipp.getAllowedCidrs()) { + r.getIp().add(cidr); + } + rules.add(r); + } + return rules; + } + + public HashMap> sync(String vmName, Long vmId, String agentIp) { + HashMap> states = new HashMap>(); + + PostMethod post = new PostMethod(String.format("http://%s:%s/", agentIp, getPort())); + try { + post.addRequestHeader("command", "sync"); + if (httpClient.executeMethod(post) != 200) { + logger.debug(String.format("echoing baremetal security group agent on %s got error: %s", agentIp, post.getResponseBodyAsString())); + } else { + String res = post.getResponseBodyAsString(); + // res = ';'.join([vmName, vmId, seqno]) + String[] rulelogs = res.split(","); + if (rulelogs.length != 6) { + logger.debug(String.format("host[%s] returns invalid security group sync document[%s], reset rules", agentIp, res)); + states.put(vmName, new Pair(vmId, -1L)); + return states; + } + + Pair p = new Pair(Long.valueOf(rulelogs[1]), Long.valueOf(rulelogs[5])); + states.put(rulelogs[0], p); + return states; + } + } catch (SocketTimeoutException se) { + logger.warn(String.format("unable to sync security group rules on host[%s], %s", agentIp, se.getMessage())); + } catch (Exception e) { + logger.warn(String.format("unable to sync security group rules on host[%s]", agentIp), e); + } finally { + if (post != null) { + post.releaseConnection(); + } + } + return states; + } + + public boolean echo(String agentIp, long l, long m) { + boolean ret = false; + int count = 1; + while (true) { + try { + Thread.sleep(m); + count++; + } catch (InterruptedException e1) { + logger.warn("", e1); + break; + } + + PostMethod post = new PostMethod(String.format("http://%s:%s/", agentIp, getPort())); + try { + post.addRequestHeader("command", "echo"); + if (httpClient.executeMethod(post) != 200) { + logger.debug(String.format("echoing baremetal security group agent on %s got error: %s", agentIp, post.getResponseBodyAsString())); + } else { + ret = true; + } + break; + } catch (Exception e) { + if (count*m >= l) { + logger.debug(String.format("ping security group agent on vm[%s] timeout after %s minutes, starting vm failed, count=%s", agentIp, TimeUnit.MILLISECONDS.toSeconds(l), count)); + break; + } else { + logger.debug(String.format("Having pinged security group agent on vm[%s] %s times, continue to wait...", agentIp, count)); + } + } finally { + if (post != null) { + post.releaseConnection(); + } + } + } + return ret; + } + + public SecurityGroupRuleAnswer call(String agentIp, + SecurityGroupRulesCmd cmd) { + PostMethod post = new PostMethod(String.format( + "http://%s:%s", agentIp, getPort())); + try { + SecurityGroupVmRuleSet rset = new SecurityGroupVmRuleSet(); + rset.getEgressRules().addAll(generateRules(cmd.getEgressRuleSet())); + rset.getIngressRules().addAll( + generateRules(cmd.getIngressRuleSet())); + rset.setVmName(cmd.getVmName()); + rset.setVmIp(cmd.getGuestIp()); + rset.setVmMac(cmd.getGuestMac()); + rset.setVmId(cmd.getVmId()); + rset.setSignature(cmd.getSignature()); + rset.setSequenceNumber(cmd.getSeqNum()); + Marshaller marshaller = context.createMarshaller(); + StringWriter writer = new StringWriter(); + marshaller.marshal(rset, writer); + String xmlContents = writer.toString(); + logger.debug(xmlContents); + + post.addRequestHeader("command", "set_rules"); + StringRequestEntity entity = new StringRequestEntity(xmlContents); + post.setRequestEntity(entity); + if (httpClient.executeMethod(post) != 200) { + return new SecurityGroupRuleAnswer(cmd, false, + post.getResponseBodyAsString()); + } else { + return new SecurityGroupRuleAnswer(cmd); + } + } catch (Exception e) { + return new SecurityGroupRuleAnswer(cmd, false, e.getMessage()); + } finally { + if (post != null) { + post.releaseConnection(); + } + } + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fb1f3f08/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 http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.11 at 03:24:15 PM PDT +// + + +package com.cloud.baremetal.networkservice.schema; + +import javax.xml.bind.annotation.XmlRegistry; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the com.cloud.network.security.schema package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.cloud.network.security.schema + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link SecurityGroupRule } + * + */ + public SecurityGroupRule createSecurityGroupRule() { + return new SecurityGroupRule(); + } + + /** + * Create an instance of {@link SecurityGroupVmRuleSet } + * + */ + public SecurityGroupVmRuleSet createSecurityGroupVmRuleSet() { + return new SecurityGroupVmRuleSet(); + } + +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fb1f3f08/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 http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.11 at 03:24:15 PM PDT +// + + +package com.cloud.baremetal.networkservice.schema; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for SecurityGroupRule complex type. + * + *

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

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

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

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

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

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getIp() { + if (ip == null) { + ip = new ArrayList(); + } + return this.ip; + } + +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fb1f3f08/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 http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2012.07.11 at 03:24:15 PM PDT +// + + +package com.cloud.baremetal.networkservice.schema; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

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

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

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

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

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

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

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

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

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

+ * Objects of the following type(s) are allowed in the list + * {@link SecurityGroupRule } + * + * + */ + public List getEgressRules() { + if (egressRules == null) { + egressRules = new ArrayList(); + } + return this.egressRules; + } + +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fb1f3f08/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 2cee084..31946d8 100644 --- a/pom.xml +++ b/pom.xml @@ -747,7 +747,9 @@ developer +