--- /tmp/tmpq8M0yE-meld/libcloud/compute/drivers/openstack.py
+++ /home/user/libcloud/libcloud/libcloud/compute/drivers/openstack.py
@@ -921,6 +921,56 @@
                self.name, self.cidr,)
 
 
+class OpenStackSecurityGroup(object):
+    """
+    A Security Group.
+    """
+
+    def __init__(self, id, tenant_id, name, description, driver, rules=None,
+                 extra=None):
+        self.id = id
+        self.tenant_id = tenant_id
+        self.name = name
+        self.description = description
+        self.driver = driver
+        self.rules = rules or []
+        self.extra = extra or {}
+
+    def __repr__(self):
+        return '<OpenStackSecurityGroup id="%s" tenant_id="%s" name="%s" \
+        description="%s">' % (self.id, self.tenant_id, self.name,
+                              self.description)
+
+
+class OpenStackSecurityGroupRule(object):
+    """
+    A Rule of a Security Group.
+    """
+
+    def __init__(self, id, parent_group_id, ip_protocol, from_port, to_port,
+                 driver, ip_range=None, group=None, tenant_id=None,
+                 extra=None):
+        self.id = id
+        self.parent_group_id = parent_group_id
+        self.ip_protocol = ip_protocol
+        self.from_port = from_port
+        self.to_port = to_port
+        self.driver = driver
+        self.ip_range = ''
+        self.group = {}
+        if group is None:
+            self.ip_range = ip_range
+        else:
+            self.group = {'name': group, 'tenant_id': tenant_id}
+        self.extra = extra or {}
+
+    def __repr__(self):
+        return '<OpenStackSecurityGroupRule id="%s" parent_group_id="%s" \
+        ip_protocol="%s" from_port="%s" to_port="%s">' % (self.id,
+               self.parent_group_id, self.ip_protocol, self.from_port,
+               self.to_port)
+
+
 class OpenStack_1_1_Connection(OpenStackComputeConnection):
     responseCls = OpenStack_1_1_Response
     accept_format = 'application/json'
@@ -967,6 +1017,11 @@
 
         @keyword    networks: The server is launched into a set of Networks.
         @type       networks: L{OpenStackNetwork}
+
+        @keyword    ex_security_groups: List of security groups to assign to
+                                        the node
+        @type       ex_security_groups: C{list} of L{OpenStackSecurityGroup} or
+                                        C{list} of C{str}
         """
 
         server_params = self._create_args_to_params(None, **kwargs)
@@ -1038,6 +1093,16 @@
             networks = [{'uuid': network.id} for network in networks]
             server_params['networks'] = networks
 
+        if 'ex_security_groups' in kwargs:
+            server_params['security_groups'] = list()
+            for security_group in kwargs['ex_security_groups']:
+                name = str()
+                if type(security_group) == OpenStackSecurityGroup:
+                    name = security_group.name
+                else:
+                    name = security_group
+                server_params['security_groups'].append({'name': name})
+
         if 'name' in kwargs:
             server_params['name'] = kwargs.get('name')
         else:
@@ -1273,6 +1338,151 @@
         """
         resp = self.connection.request('/os-networksv2/%s' % (network.id),
                                        method='DELETE')
+        return resp.status == httplib.ACCEPTED
+
+    def _to_security_group_rules(self, obj):
+        return [self._to_security_group_rule(security_group_rule) for
+                security_group_rule in obj]
+
+    def _to_security_group_rule(self, obj):
+        ip_range = group = tenant_id = None
+        if obj['group'] == {}:
+            ip_range = obj['ip_range'].get('cidr', None)
+        else:
+            group = obj['group'].get('name', None)
+            tenant_id = obj['group'].get('tenant_id', None)
+        return OpenStackSecurityGroupRule(id=obj['id'],
+                                          parent_group_id=
+                                          obj['parent_group_id'],
+                                          ip_protocol=obj['ip_protocol'],
+                                          from_port=obj['from_port'],
+                                          to_port=obj['to_port'],
+                                          driver=self,
+                                          ip_range=ip_range,
+                                          group=group,
+                                          tenant_id=tenant_id)
+
+    def _to_security_groups(self, obj):
+        security_groups = obj['security_groups']
+        return [self._to_security_group(security_group) for security_group in
+                security_groups]
+
+    def _to_security_group(self, obj):
+        return OpenStackSecurityGroup(id=obj['id'],
+                                      tenant_id=obj['tenant_id'],
+                                      name=obj['name'],
+                                      description=obj.get('description', ''),
+                                      rules=self._to_security_group_rules(
+                                      obj.get('rules', [])),
+                                      driver=self)
+
+    def ex_list_security_groups(self):
+        """
+        Get a list of Security Groups that are available.
+
+        @rtype: C{list} of L{OpenStackSecurityGroup}
+        """
+        return self._to_security_groups(
+            self.connection.request('/os-security-groups').object)
+
+    def ex_get_node_security_groups(self, node):
+        """
+        Get Security Groups of the specified server.
+
+        @rtype: C{list} of L{OpenStackSecurityGroup}
+        """
+        return self._to_security_groups(
+            self.connection.request('/servers/%s/os-security-groups' %
+                                    (node.id)).object)
+
+    def ex_create_security_group(self, name, description, rules=[]):
+        """
+        Create a new Security Group
+
+        @param name: Name of the new Security Group
+        @type  name: C{str}
+
+        @param description: Description of the new Security Group
+        @type  description: C{str}
+
+        @param rules: List of rules to add to this security group
+        @type  rules: C{list} of L{OpenStackSecurityGroupRule}
+
+        @rtype: L{OpenStackSecurityGroup}
+        """
+        return self._to_security_group(self.connection.request(
+            '/os-security-groups', method='POST',
+            data={'security_group': {'name': name, 'description': description}}
+        ).object['security_group'])
+
+    def ex_delete_security_group(self, security_group):
+        """
+        Delete a Security Group.
+
+        @param security_group: Security Group should be deleted
+        @type  security_group: L{OpenStackSecurityGroup}
+
+        @rtype: C{bool}
+        """
+        resp = self.connection.request('/os-security-groups/%s' %
+                                       (security_group.id),
+                                       method='DELETE')
+        return resp.status == httplib.ACCEPTED
+
+    def ex_create_security_group_rule(self, security_group, ip_protocol,
+                                      from_port, to_port, cidr=None,
+                                      source_security_group=None):
+        """
+        Create a new Rule in a Security Group
+
+        @param security_group: Security Group in which to add the rule
+        @type  security_group: L{OpenStackSecurityGroup}
+
+        @param ip_protocol: Protocol to which this rule applies
+                            Examples: tcp, udp, ...
+        @type  ip_protocol: C{str}
+
+        @param from_port: First port of the port range
+        @type  from_port: C{int}
+
+        @param to_port: Last port of the port range
+        @type  to_port: C{int}
+
+        @param cidr: CIDR notation of the source IP range for this rule
+        @type  cidr: C{str}
+
+        @param source_security_group: Existing Security Group to use as the
+                                      source (instead of CIDR)
+        @type  source_security_group: L{OpenStackSecurityGroup
+
+        @rtype: L{OpenStackSecurityGroupRule}
+        """
+        source_security_group_id = None
+        if type(source_security_group) == OpenStackSecurityGroup:
+            source_security_group_id = source_security_group.id
+
+        return self._to_security_group_rule(self.connection.request(
+            '/os-security-group-rules', method='POST',
+            data={'security_group_rule': {
+            'ip_protocol': ip_protocol,
+            'from_port': from_port,
+            'to_port': to_port,
+            'cidr': cidr,
+            'group_id': source_security_group_id,
+            'parent_group_id': security_group.id}}
+        ).object['security_group_rule'])
+
+    def ex_delete_security_group_rule(self, rule):
+        """
+        Delete a Rule from a Security Group.
+
+        @param rule: Rule should be deleted
+        @type  rule: L{OpenStackSecurityGroupRule}
+
+        @rtype: C{bool}
+        """
+        resp = self.connection.request('/os-security-group-rules/%s' %
+                                       (rule.id), method='DELETE')
         return resp.status == httplib.ACCEPTED
 
     def ex_get_size(self, size_id):
@@ -1352,7 +1562,7 @@
                 imageId=api_node['image']['id'],
                 flavorId=api_node['flavor']['id'],
                 uri=next(link['href'] for link in api_node['links'] if
-                    link['rel'] == 'self'),
+                         link['rel'] == 'self'),
                 metadata=api_node['metadata'],
                 password=api_node.get('adminPass'),
                 created=api_node['created'],
