|
12 | 12 | client as boto3client |
13 | 13 | ) |
14 | 14 |
|
15 | | -from wrapanapi.entities import (Instance, Network, NetworkMixin, Stack, StackMixin, |
16 | | - Template, TemplateMixin, VmMixin, VmState, Volume) |
| 15 | +from wrapanapi.entities import (Instance, Network, NetworkMixin, SecurityGroup, SecurityGroupMixin, |
| 16 | + Stack, StackMixin, Template, TemplateMixin, VmMixin, VmState, |
| 17 | + Volume) |
17 | 18 | from wrapanapi.exceptions import (ActionTimedOutError, MultipleItemsError, NotFoundError) |
18 | 19 | from wrapanapi.systems.base import System |
19 | 20 |
|
@@ -449,7 +450,98 @@ def cleanup(self): |
449 | 450 | return self.delete() |
450 | 451 |
|
451 | 452 |
|
452 | | -class EC2System(System, VmMixin, TemplateMixin, StackMixin, NetworkMixin): |
| 453 | +class SecurityGroup(_TagMixin, _SharedMethodsMixin, SecurityGroup): |
| 454 | + def __init__(self, system, raw=None, **kwargs): |
| 455 | + """ |
| 456 | + Constructor for an SecurityGroup tied to a specific system. |
| 457 | +
|
| 458 | + Args: |
| 459 | + system: an EC2System object |
| 460 | + raw: the boto.ec2.volume.Volume object if already obtained, or None |
| 461 | + uuid: unique ID of the volume |
| 462 | + """ |
| 463 | + self._uuid = raw.id if raw else kwargs.get('uuid') |
| 464 | + if not self._uuid: |
| 465 | + raise ValueError("missing required kwarg: 'uuid'") |
| 466 | + |
| 467 | + super(SecurityGroup, self).__init__(system, raw, **kwargs) |
| 468 | + |
| 469 | + self._api = self.system.ec2_connection |
| 470 | + |
| 471 | + @property |
| 472 | + def name(self): |
| 473 | + tag_value = self.get_tag_value('Name') |
| 474 | + return tag_value if tag_value else self.raw.group_name |
| 475 | + |
| 476 | + def set_rule(self, permission_list, traffic_type='inbound'): |
| 477 | + """ |
| 478 | +
|
| 479 | + Args: |
| 480 | + permission_list= [{ |
| 481 | + 'FromPort': from_port(-1 - all ports), |
| 482 | + 'ToPort': to_port(-1 - all ports), |
| 483 | + 'IpProtocol': 'tcp/udp/icmp/icmpv6/-1(all protocols)', |
| 484 | + 'IpRanges': [{'CidrIp': '0.0.0.0/32'}] |
| 485 | + }] |
| 486 | + traffic_type: inbound/outbound |
| 487 | +
|
| 488 | + Returns: |
| 489 | +
|
| 490 | + """ |
| 491 | + try: |
| 492 | + if traffic_type == 'inbound': |
| 493 | + self.raw.authorize_ingress(IpPermissions=permission_list) |
| 494 | + else: |
| 495 | + self.raw.authorize_egress(IpPermissions=permission_list) |
| 496 | + self.refresh() |
| 497 | + return True |
| 498 | + except Exception: |
| 499 | + return False |
| 500 | + |
| 501 | + def unset_rule(self, permission_list, traffic_type='inbound'): |
| 502 | + """ |
| 503 | +
|
| 504 | + Args: |
| 505 | + permission_list: [ |
| 506 | + FromPort: from_port(-1 - all ports), |
| 507 | + ToPort: to_port(-1 - all ports), |
| 508 | + IpProtocol: 'tcp/udp/icmp/icmpv6/-1(all protocols)', |
| 509 | + IpRanges: [CidrIp: '0.0.0.0/32'] |
| 510 | + ] |
| 511 | + type: inbound/outbound |
| 512 | +
|
| 513 | + Returns: |
| 514 | +
|
| 515 | + """ |
| 516 | + try: |
| 517 | + if traffic_type == 'inbound': |
| 518 | + self.raw.revoke_ingress(IpPermissions=permission_list) |
| 519 | + else: |
| 520 | + self.raw.revoke_egress(IpPermissions=permission_list) |
| 521 | + self.refresh() |
| 522 | + return True |
| 523 | + except Exception: |
| 524 | + return False |
| 525 | + |
| 526 | + def delete(self): |
| 527 | + """ |
| 528 | + Delete SecurityGroup |
| 529 | + """ |
| 530 | + self.logger.info("Deleting SecurityGroup '%s', id: '%s'", self.name, self.uuid) |
| 531 | + try: |
| 532 | + self.raw.delete() |
| 533 | + return True |
| 534 | + except ActionTimedOutError: |
| 535 | + return False |
| 536 | + |
| 537 | + def cleanup(self): |
| 538 | + """ |
| 539 | + Cleanup SecurityGroup |
| 540 | + """ |
| 541 | + return self.delete() |
| 542 | + |
| 543 | + |
| 544 | +class EC2System(System, VmMixin, TemplateMixin, StackMixin, NetworkMixin, SecurityGroupMixin): |
453 | 545 | """EC2 Management System, powered by boto |
454 | 546 |
|
455 | 547 | Wraps the EC2 API |
@@ -1512,3 +1604,44 @@ def get_snapshot_id_if_import_completed(self, task_id): |
1512 | 1604 | return result.get("SnapshotId") |
1513 | 1605 | else: |
1514 | 1606 | return False |
| 1607 | + |
| 1608 | + def create_sec_group(self, group_name, desc="SG created for automated test", vpc_id=None): |
| 1609 | + sg_kwargs = {'Description': desc, 'GroupName': group_name} |
| 1610 | + if vpc_id: |
| 1611 | + sg_kwargs['VpcId'] = vpc_id |
| 1612 | + result = self.ec2_connection.create_security_group(**sg_kwargs) |
| 1613 | + return SecurityGroup(system=self, uuid=result['GroupId'], |
| 1614 | + raw=self.ec2_resource.SecurityGroup(result['GroupId'])) |
| 1615 | + |
| 1616 | + def get_sec_group(self, name=None, id=None): |
| 1617 | + return self._get_resource(SecurityGroup, self.find_sec_groups, name=name, id=id) |
| 1618 | + |
| 1619 | + def list_sec_groups(self): |
| 1620 | + """ |
| 1621 | + Returns a list of SecurityGroup objects |
| 1622 | + """ |
| 1623 | + sec_group_list = [ |
| 1624 | + EBSVolume(system=self, uuid=sec_group['GroupId'], raw=self.ec2_resource.SecurityGroup( |
| 1625 | + sec_group['GroupId'])) |
| 1626 | + for sec_group in self.ec2_connection.describe_security_groups().get('SecurityGroups') |
| 1627 | + ] |
| 1628 | + return sec_group_list |
| 1629 | + |
| 1630 | + def find_sec_groups(self, name=None, id=None): |
| 1631 | + """ |
| 1632 | + Return list of all security groups with given name or id |
| 1633 | + Args: |
| 1634 | + name: name to search |
| 1635 | + id: id to search |
| 1636 | + Returns: |
| 1637 | + List of SecurityFGroup objects |
| 1638 | + """ |
| 1639 | + if not name and not id or name and id: |
| 1640 | + raise ValueError("Either name or id must be set and not both!") |
| 1641 | + if id: |
| 1642 | + sec_groups = self.ec2_connection.describe_security_groups(GroupIds=[id]) |
| 1643 | + else: |
| 1644 | + sec_groups = self.ec2_connection.describe_security_groups(GroupNames=[name]) |
| 1645 | + return [ |
| 1646 | + SecurityGroup(system=self, raw=self.ec2_resource.SecurityGroup(sec_group['GroupId'])) |
| 1647 | + for sec_group in sec_groups.get('SecurityGroups')] |
0 commit comments