cloudless
Cloudless is a python library to provide a basic set of easy to use primitive operations that can work with many different cloud providers.
These primitives are:
- Create a "Network" (also known as VPC, Network, Environment). e.g. "dev".
- Create a "Service" within that network. e.g. "apache-public".
- Easily control network connections and firewalls using "Paths".
The goal is to provide an intuitive abstraction that is powerful enough to build on, so that building other layers on top is easy and anything built on it is automatically cross cloud.
The main entry point to this module is through the cloudless.Client
object, and all calls that
interact with a backing cloud provider go through this object.
Client
Client(self, profile=None, provider=None, credentials=None)
Top Level Cloudless Client.
This is the object through which all calls to the backing service provider are made.
Most functionality is stored in the subclasses that are attached to this client. Currently they
are cloudless.NetworkClient
, cloudless.ServiceClient
, and cloudless.PathsClient
. See the
documentation on those sub-components for more usage details.
To use:
import cloudless
client = cloudless.Client(provider, credentials)
client.network?
client.service?
client.paths?
Where "provider" is the backing service provider, and "credentials" is a hash containing whatever credentials are required by the chosen provider. See the supported providers list for details.
graph
Client.graph(self)
Return a DOT formatted graph string containing all resources on the current provider.
This string can be passed to a program like graphviz to generate a graph visualization.
NetworkClient
NetworkClient(self, provider, credentials)
Cloudless Network Client.
This is the object through which all network related calls are made. The objects returned by
these commands are of type cloudless.types.common.Network
.
Usage:
import cloudless
client = cloudless.Client(provider, credentials)
client.network.create("network", blueprint="tests/blueprints/network.yml")
client.network.get("network")
client.network.list()
client.network.destroy(client.network.get("network"))
The above commands will create and destroy a network named "network".
create
NetworkClient.create(self, name, blueprint=None)
Create new network named "name" with blueprint file at "blueprint".
Example:
client.network.create("mynetwork", "network-blueprint.yml")
get
NetworkClient.get(self, name)
Get a network named "name" and return some data about it.
Example:
client.network.get("mynetwork")
destroy
NetworkClient.destroy(self, network)
Destroy the given network.
Example:
client.network.destroy(client.network.get("mynetwork"))
list
NetworkClient.list(self)
List all networks.
Example:
client.network.list()
ServiceClient
ServiceClient(self, provider, credentials)
Cloudless Service Client.
This is the object through which all service related calls are made. The objects returned by
these commands are of type cloudless.types.common.Service
which contain objects of type
cloudless.types.common.Subnetwork
, which themselves contain lists of
cloudless.types.common.Instance
. This is because the service is the logical grouping, but
behind the scenes they are groups of instances deployed in private subnetworks.
Usage:
import cloudless
client = cloudless.Client(provider, credentials)
network = client.network.create("network", blueprint="tests/blueprints/network.yml")
client.service.create(network, "public", blueprint="tests/blueprints/service.yml")
myservice = client.service.get(mynetwork, "public")
client.service.list()
client.service.destroy(myservice)
The above commands will create and destroy a service named "public" in the network "network".
create
ServiceClient.create(self, network, service_name, blueprint, template_vars=None, count=None)
Create a service in "network" named "service_name" with blueprint file at "blueprint".
"template_vars" are passed to the initialization scripts as jinja2 variables.
Example:
example_network = client.network.create("example")
example_service = client.service.create(network=example_network,
name="example_service",
blueprint="example-blueprint.yml")
get
ServiceClient.get(self, network, service_name)
Get a service in "network" named "service_name".
Example:
example_service = client.service.get(network=client.network.get("example"),
name="example_service")
get_instances
ServiceClient.get_instances(self, service)
Helper to return the list of instances given a service object.
Example:
example_service = client.service.get(network=client.network.get("example"),
name="example_service")
instances = client.service.get_instances(example_service)
destroy
ServiceClient.destroy(self, service)
Destroy a service described by the "service" object.
Example:
example_service = client.service.get(network=client.network.get("example"),
name="example_service")
client.service.destroy(example_service)
list
ServiceClient.list(self)
List all services.
Example:
client.service.list()
node_types
ServiceClient.node_types(self)
Get mapping of node types to the resources.
Example:
client.service.node_types()
PathsClient
PathsClient(self, provider, credentials)
Cloudless Paths Client.
This is the object through which all path related calls are made. The objects returned by these
commands are of type cloudless.types.common.Path
which contain objects of type
cloudless.types.common.Service
and cloudless.types.networking.CidrBlock
depending on whether
the path is internally or externally facing.
Usage:
import cloudless
client = cloudless.Client(provider, credentials)
internal_service = client.service.get(network, "internal_service")
load_balancer = client.service.get(network, "load_balancer")
internet = cloudless.types.networking.CidrBlock("0.0.0.0/0")
client.paths.add(load_balancer, internal_service, 80)
client.paths.add(internet, load_balancer, 443)
client.paths.list()
client.graph()
The above commands will result in the public internet having access to "load_balancer" on port 443 and "load_balancer" having access to "internal_service" on port 80.
add
PathsClient.add(self, source, destination, port)
Make the service or cidr block described by "destination" accessible from the service or cidr block described by "source" on the given port.
Either "source" or "destination" must be a service object.
Example:
service1 = client.service.get(network=client.network.get("example"), name="service1")
service2 = client.service.get(network=client.network.get("example"), name="service2")
internet = cloudless.types.networking.CidrBlock("0.0.0.0/0")
client.paths.add(service1, service2, 443)
client.paths.add(internet, service1, 80)
remove
PathsClient.remove(self, source, destination, port)
Ensure the service or cidr block described by "destination" is not accessible from the service or cidr block described by "source" on the given port.
Either "source" or "destination" must be a service object.
Example:
service1 = client.service.get(network=client.network.get("example"), name="service1")
service2 = client.service.get(network=client.network.get("example"), name="service2")
internet = cloudless.types.networking.CidrBlock("0.0.0.0/0")
client.paths.remove(service1, service2, 443)
client.paths.remove(internet, service1, 80)
list
PathsClient.list(self)
List all paths and return a dictionary structure representing a graph.
Example:
client.paths.list()
internet_accessible
PathsClient.internet_accessible(self, service, port)
Returns true if the service described by "service" is internet accessible on the given port.
Example:
service1 = client.service.get(network=client.network.get("example"), name="service1")
client.paths.internet_accessible(service1, 443)
has_access
PathsClient.has_access(self, source, destination, port)
Returns true if the service or cidr block described by "destination" is accessible from the service or cidr block described by "source" on the given port.
Either "source" or "destination" must be a service object.
Example:
service1 = client.service.get(network=client.network.get("example"), name="service1")
service2 = client.service.get(network=client.network.get("example"), name="service2")
internet = cloudless.types.networking.CidrBlock("0.0.0.0/0")
client.paths.has_access(service1, service2, 443)
client.paths.has_access(internet, service1, 80)