Coder Social home page Coder Social logo

cloudaux's Introduction

cloudaux

Join the chat at https://gitter.im/Netflix-Skunkworks/cloudaux

Version

Build Status

Coverage Status

Cloud Auxiliary is a python wrapper and orchestration module for interacting with cloud providers.

NOTE: What are we supporting?

CloudAux was initially developed to provide convenience wrappers for common patterns when working with cloud infrastructures (like role assumption, and multi-regionality). It also contained some convenience functions to describe entire resources with the wrappers to fetch the full resource configuration details.

However, over time, we have stopped relying on the resource configuration wrapper capabilities and instead are only supporting the AWS convenience decorators, such as sts_conn, and paginated to name a few. If you wish to make use of CloudAux, simply wrap your boto calls in a function with the decorators applied to them.

NOTE: Python 2 Deprecation

Python 2 support has been dropped as of version 1.9.0. For projects that still require Python 2 support, please use the latest 1.8.x builds.

Documentation

Features

AWS:

  • intelligent connection caching.
  • handles pagination for certain client methods.
  • rate limit handling, with exponential backoff.
  • multi-account sts:assumerole abstraction.
  • orchestrates all the calls required to fully describe an item.
  • control which attributes are returned with flags.

GCP:

  • choosing the best client based on service
  • client caching
  • general caching and stats decorators available
  • basic support for non-specified discovery-API services
  • control which attributes are returned with flags.

OpenStack:

  • intelligent connection caching.
  • generalized OpenStack SDK generator usage.
  • orchestrates all the calls required to fully describe an item.
  • control which attributes are returned flags.

Orchestration Supported Technologies

AWS:

GCP: (DEPRECATED - NO LONGER SUPPORTED)

  • IAM Service Accounts
  • Network/Subnetworks
  • Storage Buckets

OpenStack: (DEPRECATED - NO LONGER SUPPORTED)

  • Network/Subnet
  • Floating IP/Router/Port
  • User
  • Instance/Image
  • Load Balancer
  • Object Storage Container

Install

pip install cloudaux

For GCP support run:

pip install cloudaux\[gcp\]

For OpenStack support run:

pip install cloudaux\[openstack\]

Examples

AWS Example

# Using wrapper methods:
from cloudaux.aws.sqs import get_queue, get_messages
conn_details = {
    'account_number': '111111111111',
    'assume_role': 'MyRole',
    'session_name': 'MySession',
    'region': 'us-east-1'
}
queue = get_queue(queue_name='MyQueue', **conn_details)
messages = get_messages(queue=queue)


# Using the CloudAux class
from cloudaux import CloudAux
CloudAux.go('kms.client.list_aliases', **conn_details)

ca = CloudAux(**conn_details)
ca.call('kms.client.list_aliases')


# directly asking for a boto3 connection:
from cloudaux.aws.sts import boto3_cached_conn
conn = boto3_cached_conn('ec2', **conn_details)


# Over your entire environment:
from cloudaux.decorators import iter_account_region

accounts = ['000000000000', '111111111111']

conn_details = {
    'assume_role': 'MyRole',
    'session_name': 'MySession',
    'conn_type': 'boto3'
}

@iter_account_region('kms', accounts=accounts, regions=['us-east-1'], **conn_details)
def list_keys(conn=None):
    return conn.list_keys()['Keys']

# If you want your role to be read-only, you can assume your role and add the read_only flag to connection details
# to inherit the AWS ReadOnlyAccess policy. This flag defaults to False
# The permissions from the role being assumed will be limited to Read and List only
conn_details = {
    'account_number': '111111111111',
    'assume_role': 'MyRole',
    'session_name': 'MySession',
    'region': 'us-east-1',
    'read_only': True
}

GCP Example -- DEPRECATED - NO LONGER SUPPORTED

# directly asking for a client:
from cloudaux.aws.gcp.auth import get_client
client = get_client('gce', **conn_details)

# Over your entire environment:
from cloudaux.gcp.decorators import iter_project

projects = ['my-project-one', 'my-project-two']

# To specify per-project key_files, you can do thie following:
# projects = [
#  {'project': 'my-project-one', key_file='/path/to/project-one.json'},
#  {'project': 'my-project-two', key_file='/path/to/project-two.json'}
# ]
#
# To specify a single key_file for all projects, use the key_file argument
# to the decorator
# @iter_project(projects=projects, key_file='/path/to/key.json')
#
# To use default credentials, omit the key_file argument
# @iter_project(projects=projects)

from cloudaux.gcp.iam import list_serviceaccounts
from cloudaux.orchestration.gcp.iam.serviceaccount import get_serviceaccount_complete

@iter_project(projects=projects, key_file='/path/to/key.json')
def test_iter(**kwargs):
   accounts = list_serviceaccounts(**kwargs)
   ret = []
   for account in accounts:
     ret.append(get_serviceaccount_complete(service_account=account['name']))
   return ret

OpenStack Example -- DEPRECATED - NO LONGER SUPPORTED

from cloudaux.openstack.decorators import _connect
conn = _connect(cloud_name, region, yaml_file):

# Over your entire environment:
from cloudaux.openstack.decorators import iter_account_region, get_regions

@iter_account_region(account_regions=get_regions())
def list_networks(conn=None, service='network', generator='security_groups'):
    from cloudaux.openstack.utils import list_items
    list_items(**kwargs)

Orchestration Example -- DEPRECATED - PLEASE DON'T USE THESE ANYMORE

AWS IAM Role

from cloudaux.orchestration.aws.iam.role import get_role, FLAGS

# account_number may be extracted from the ARN of the role passed to get_role
# if not included in conn.
conn = dict(
    assume_role='SecurityMonkey',  # or whichever role you wish to assume into
    session_name='cloudaux',
    region='us-east-1'
)

role = get_role(
    dict(arn='arn:aws:iam::000000000000:role/myRole', role_name='myRole'),
    output='camelized',  # optional: {camelized underscored}
    flags=FLAGS.ALL,  # optional
    **conn)

# The flags parameter is optional but allows the user to indicate that
# only a subset of the full item description is required.
# IAM Role Flag Options:
#   BASE, MANAGED_POLICIES, INLINE_POLICIES, INSTANCE_PROFILES, TAGS, ALL (default)
# For instance: flags=FLAGS.MANAGED_POLICIES | FLAGS.INSTANCE_PROFILES

# cloudaux makes a number of calls to obtain a full description of the role
print(json.dumps(role, indent=4, sort_keys=True))

{
    "Arn": ...,
    "AssumeRolePolicyDocument": ...,
    "CreateDate": ...,  # str
    "InlinePolicies": ...,
    "InstanceProfiles": ...,
    "ManagedPolicies": ...,
    "Path": ...,
    "RoleId": ...,
    "RoleName": ...,
    "Tags": {},
    "_version": 3    # Orchestration results return a _Version
}

GCP IAM Service Account -- DEPRECATED - PLEASE DON'T USE THESE ANYMORE

from cloudaux.orchestration.gcp.iam.serviceaccount import get_serviceaccount_complete, FLAGS
sa_name = 'projects/my-project-one/serviceAccounts/[email protected]'
sa = get_serviceaccount_complete(sa_name, flags=FLAGS.ALL, **conn_details)
print(json.dumps(sa, indent=4, sort_keys=True))

# Flag options for Service Accounts are BASE, KEYS, POLICY, ALL (default).

{
  "DisplayName": "service-account",
  "Email": "[email protected]",
  "Etag": "BwUzTDvWgHw=",
  "Keys": [
      {
          "KeyAlgorithm": "KEY_ALG_RSA_2048",
          "Name": "projects/my-project-one/serviceAccounts/[email protected]/keys/8be0096886f6ed5cf51abb463d3448c8aee6c6b6",
          "ValidAfterTime": "2016-06-30T18:26:45Z",
          "ValidBeforeTime": "2026-06-28T18:26:45Z"
      },
  ...
  ],
  "Name": "projects/my-project-one/serviceAccounts/[email protected]",
  "Oauth2ClientId": "115386704809902483492",
  "Policy": [
      {
          "Members": [
              "user:[email protected]"
          ],
          "Role": "roles/iam.serviceAccountActor"
      }
  ],
  "ProjectId": "my-project-one",
  "UniqueId": "115386704809902483492"
}

OpenStack Security Group - DEPRECATED - PLEASE DON'T USE THESE ANYMORE

from cloudaux.orchestration.openstack.security_group import get_security_group, FLAGS

secgroup = get_security_group(result, flags=flags, **kwargs)

# The flags parameter is optional but allows the user to indicate that
# only a subset of the full item description is required.
# Security Group Flag Options:
#   RULES, INSTANCES (default)
# For instance: flags=FLAGS.RULES | FLAGS.INSTANCES

print(json.dumps(secgroup, indent=4, sort_keys=True))

{
    "assigned_to": [
        {
           "instance_id": "..."
        }
    ],
    "created_at": "...",
    "description": "...",
    "id": "...",
    "location": "...",
    "name": "...",
    "project_id": "...",
    "revision_number": 3,
    "rules": [
        {
            "rule_type": "...",
            "remote_group_id": "...",
            "from_port": "...",
            "description": "...",
            "tags": [],
            "to_port": "...",
            "ethertype": "...",
            "created_at": "...",
            "updated_at": "...",
            "security_group_id": "...",
            "revision_number": 0,
            "tenant_id": "...",
            "project_id": "..."",
            "id": "...",
            "cidr_ip": "...",
            "ip_protocol": "..."
        },
    ],
    "updated_at": "..."
}

cloudaux's People

Contributors

castrapel avatar darkarnium avatar deepak1100 avatar dgreene-r7 avatar fitbit-greg avatar gitter-badger avatar josagonzalez avatar kevgliss avatar laurajauch avatar mcpeak avatar mikegrima avatar mstair avatar ottogroup-com avatar patricksanders avatar pelegdvir avatar pritamdutt avatar rahulsom avatar reilings avatar rrivera-rmn avatar scriptsrc avatar supertom avatar willbengtson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cloudaux's Issues

S3 ACL Canonical ID not captured correctly

There is a bug in the S3 get_grants() function when capturing canonical IDs. It is incorrectly looking for URI when it's supposed to fetch ID. This creates an incorrect string when the DisplayName isn't captured. The incorrect string looks like this:

Grants": {
    "null": [
        "FULL_CONTROL"
    ]
},

This is also causing downstream issues with Security Monkey where it thinks that there is a new change each time. This is currently the case with "new" regions where the get_bucket_acl API no longer returns the display name (still have not identified why SM thinks a new change keeps occurring, but this only happens on these specific buckets).

Add support for S3 Analytics

Amazon recently announced new S3 features around analytics. There are additional API calls that are required:

- list_bucket_analytics_configurations()
- list_bucket_inventory_configurations()
- list_bucket_metrics_configurations()

This will also require boto's minimum version to be bumped up to 1.4.2.

'pagiated' is an undefined name in ./cloudaux/aws/sns.py

Undefined names may raise NameError at runtime.

$ flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics

./cloudaux/aws/sns.py:132:2: F821 undefined name 'pagiated'
@pagiated('Topics', request_pagination_marker="NextToken", response_pagination_marker="NextToken")
 ^
1     F821 undefined name 'pagiated'

Also see FIXME in .travis.yml

aws/iam.py: get_role_managed_policy_documents fails to pass connection details to internal calls

get_role_managed_policy_documents passes its own kwargs directly to its internal calls to get_role_managed_policies and get_managed_policy_document, but the relevant connection parameters (account_number, assume_role, etc) are stripped by the sts_conn decorator beforehand. The result is that those internal calls receive no explicit connection parameters and fall back to boto3's credential-finding routine -- this may fail completely or pick up credentials that were not intended for this use.

optional fields param in orchestration

I wonder if all the orchestration commands (get_user, get_role, get_bucket) should take an optional fields parameter.

That way you could use CloudAux and specify some subset of the fields. The default would be all.

Each tech could provide an importable field list so that IDE's could auto-complete.

@mikegrima - Thoughts?

CloudAux conn_details should be an instance variable, not a class variable

@willbengtson found a bug in the CloudAux class.

You can't have more than one CloudAux object instantiated because the conn_details is currently stored in a class variable, not an instance variable.

So this test would fail:

from cloudaux import CloudAux


def test_cloudaux():
    conn_one = {
        "account_number": "111111111111",
        "assume_role": "role_one",
        "region": "us-east-1",
        "session_name": "conn_one"
    }

    conn_two = {
        "account_number": "222222222222",
        "assume_role": "role_two",
        "region": "us-east-2",
        "session_name": "conn_two"
    }

    ca_one = CloudAux(**conn_one)
    ca_two = CloudAux(**conn_two)

    assert ca_one.conn_details["account_number"] == "111111111111"
    assert ca_one.conn_details["assume_role"] == "role_one"
    assert ca_one.conn_details["region"] == "us-east-1"
    assert ca_one.conn_details["session_name"] == "conn_one"

    assert ca_two.conn_details["account_number"] == "222222222222"
    assert ca_two.conn_details["assume_role"] == "role_two"
    assert ca_two.conn_details["region"] == "us-east-2"
    assert ca_two.conn_details["session_name"] == "conn_two"

I have a PR coming in just a second to fix the CloudAux class and to add the above unit test.

sts assume role fails

sts assume role fails with following error in GovCloud at

arn = 'arn:aws:iam::{0}:role/{1}'.format(

ClientError: An error occurred (AccessDenied) when calling the AssumeRole operation: Access denied

Can we somehow pass / implement ARN_PARTITION / ARN_PREFIX in the likes of what has been done in security_monkey

https://github.com/Netflix/security_monkey/blob/b174a705124f12aeee612f9ef93820f2b4227e0e/security_monkey/__init__.py#L72

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.