Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[packages]
cloudless = {git = "https://github.com/sverch/cloudless", ref = "master", editable = true}
66 changes: 64 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,64 @@
# example-vault
Example of deploying Hashicorp's Vault using Cloudless
# Apache Service Example

This is an example of creating a service running Apache. Note that this
blueprint references an image created by the base image scripts at
[https://github.com/getcloudless/example-base-image](https://github.com/getcloudless/example-base-image),
so this will fail unless you run that first.

## Usage

The file at `blueprint.yml` can be used in any service command:

```
cldls service create blueprint.yml
```

You can run the service's regression tests with:

```
cldls service-test run service_test_configuration.yml
```

Note that these are completely independent of what provider you're using,
assuming you've already built the [Base
Image](https://github.com/getcloudless/example-base-image).

## Workflow

The main value of the test framework is that it is focused on the workflow of
actually developing a service. For example, if you want to deploy a service
(and all its dependencies) that you can work on without running the full test,
you can run:

```
cldls service-test deploy service_test_configuration.yml
```

This command saves the SSH keys locally and will display the SSH command that
you need to run to log into the instance.

Now, say you want to actually check that the service is behaving as expected:

```
cldls service-test check service_test_configuration.yml
```

You can run this as many times as you want until it's working, as you are logged
in. Finally, clean everything up with:

```
cldls service-test cleanup service_test_configuration.yml
```

You're done! The run step will run all these steps in order.

## Files

- `service_test_configuration.yml`: Configuration file for the service test
framework.
- `blueprint.yml`: Blueprint that is actually used to create the service. This
is the thing we are really testing.
- `apache_startup_script.sh`: Script referenced by the blueprint that will set
up Apache.
- `blueprint_fixture.py`: Python test fixture that will set up dependencies and
verify that things are behaving as expected.
16 changes: 16 additions & 0 deletions apache_startup_script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#! /bin/bash

{% if cloudless_test_framework_ssh_key %}
adduser "{{ cloudless_test_framework_ssh_username }}" --disabled-password --gecos "Cloudless Test User"
echo "{{ cloudless_test_framework_ssh_username }} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
mkdir /home/{{ cloudless_test_framework_ssh_username }}/.ssh/
echo "{{ cloudless_test_framework_ssh_key }}" >> /home/{{ cloudless_test_framework_ssh_username }}/.ssh/authorized_keys
{% endif %}

apt-get update
apt-get install -y apache2
cat <<EOF > /var/www/html/index.html
<html><body><h1>Hello World</h1>
<p>This page was created from a simple startup script!</p>
</body></html>
EOF
27 changes: 27 additions & 0 deletions blueprint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
network:
subnetwork_max_instance_count: 768

placement:
availability_zones: 3

instance:
public_ip: True
memory: 1GB
cpus: 1
gpu: false
disks:
- size: 8GB
type: standard
device_name: /dev/sda1

image:
name: "cloudless-example-base-image-v0"

initialization:
- path: "apache_startup_script.sh"
vars:
cloudless_test_framework_ssh_key:
required: false
cloudless_test_framework_ssh_username:
required: false
49 changes: 49 additions & 0 deletions blueprint_fixture.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""
Apache Test Fixture

This fixture doesn't do any setup, but verifies that the created service is
running default apache.
"""
import requests
from cloudless.testutils.blueprint_tester import call_with_retries
from cloudless.testutils.fixture import BlueprintTestInterface, SetupInfo
from cloudless.types.networking import CidrBlock

RETRY_DELAY = float(10.0)
RETRY_COUNT = int(6)

class BlueprintTest(BlueprintTestInterface):
"""
Fixture class that creates the dependent resources.
"""
def setup_before_tested_service(self, network):
"""
Create the dependent services needed to test this service.
"""
# Since this service has no dependencies, do nothing.
return SetupInfo({}, {})

def setup_after_tested_service(self, network, service, setup_info):
"""
Do any setup that must happen after the service under test has been
created.
"""
internet = CidrBlock("0.0.0.0/0")
self.client.paths.add(internet, service, 80)

def verify(self, network, service, setup_info):
"""
Given the network name and the service name of the service under test,
verify that it's behaving as expected.
"""
def check_responsive():
public_ips = [i.public_ip for s in service.subnetworks for i in s.instances]
assert public_ips
for public_ip in public_ips:
response = requests.get("http://%s" % public_ip)
expected_content = "Hello World"
assert response.content, "No content in response"
assert expected_content in str(response.content), (
"Unexpected content in response: %s" % response.content)

call_with_retries(check_responsive, RETRY_COUNT, RETRY_DELAY)
34 changes: 34 additions & 0 deletions service_test_configuration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
# Configuration options for the blueprint testing framework.
#
# This file describes configuration for the blueprint test runner, which can
# create, verify, and cleanup services based on a blueprint, providing a
# deterministic way to test the way instances actually behave in a deployment.
# See https://docs.getcloudless.com/ for more details.

# Configuration for service creation.
create:

# Number of instances needed for the test.
count: 1

# Blueprint file to use to create test service. This is the default.
blueprint: blueprint.yml

# This is a fixture that describes any pre setup (e.g. necessary services that
# this service being tested needs to run) and post setup (e.g. adding the
# right firewall rules) that needs to be done to properly test this blueprint.
# These are the defaults. See blueprint_fixture.py for more details.
fixture_type: python-blueprint-fixture
fixture_options:
module_name: blueprint_fixture

# Configuration for service verification.
verify:

# This happens to be the same fixture, but for verify this is the code that
# tests whether the running service is behaving as expected. These are the
# defaults. See blueprint_fixture.py for more details.
fixture_type: python-blueprint-fixture
fixture_options:
module_name: blueprint_fixture