Skip to content

Commit

Permalink
Merge pull request #41 from hellofresh/feature/producer-tags
Browse files Browse the repository at this point in the history
Support producer tags
  • Loading branch information
zeelax authored Feb 9, 2018
2 parents 1ed63ff + f1a5f2d commit 2193ba6
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 8 deletions.
136 changes: 132 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,139 @@ consul_haproxy_stats_uri : "/"
# Ad-hoc commands RUN WITH CARE
consul_adhoc_build_raft_peers : False
```
service definition
## Usage
Service definition
----
https://www.consul.io/docs/agent/checks.html
The role expects all services to be listed in `consul_services` dictionary:

```yaml
consul_services:
hello-app:
name: "hello-app"
tags:
- "env:live"
port: 80
local_port: 8032
check:
script: "curl localhost:80 > /dev/null 2>&1"
interval: "10s"
haproxy:
server_options: "check inter 10s fastinter 5s downinter 8s rise 3 fall 2"
hello-db:
name: "hello-db"
tags:
- "env:live"
port: 3306
check:
script: "netstat -ant | grep 3306 | grep -v grep > /dev/null 2>&1"
interval: "10s"
haproxy:
server_options: "check inter 10s fastinter 5s downinter 8s rise 3 fall 2"
```

Service example
---------------
```yaml
hello-app:
name: "hello-app"
tags:
- "env:live"
port: 80
local_port: 8032
check:
script: "curl localhost:80 > /dev/null 2>&1"
interval: "10s"
haproxy:
server_options: "check inter 10s fastinter 5s downinter 8s rise 3 fall 2"
```
`hello-app`:

`name`: service name to announce

`tags`: list of tags to filter by (see tags section)

`port`: port number server part listens on

`local_port`: port number CSLB agent (haproxy) will listen on, if absent equals `port`

`check`: healthcheck script and interval; most of the times as simple as in this example

`haproxy`: haproxy server check definition (https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.2-check)


### Producer configuration
Define list of services you produce (offer to connect to)
```yaml
consul_producer: True
consul_producer_services:
- hello-app
- other-service
```
Role will install consul agent and configure it to announce specified services.

### Consumer configuration
Define list of services you consume (want to connect to)
```yaml
consul_consumer: True
consul_consumer_services:
- hello-app
- hello-db
```
Role will configure consul agent, consul template and haproxy. Haproxy will listen on specified ports, so you would be able to connect to specific service using `127.0.0.1:port`.

### Extended syntax
If you want to specify additional parameters you should use extended syntax:
```yaml
---
consul_producer: True
consul_producer_services:
# simple syntax
- hello-app
# extended syntax
- name: hello-app
add_tags: ['host-specific-tag']
```


```yaml
---
consul_consumer: True
consul_consumer_services:
# simple syntax
- hello-app
# extended syntax
- name: hello-app
tags_contains: "test"
```


### Using tags

#### Producer
You can specify additional tags for group/host. These tags will be added to a set of tags globally defined to this service.

```yaml
consul_producer: True
consul_producer_services:
- name: hello-app
add_tags: ['host-specific-tag']
```

#### Consumer
On consumer side, you can user additional parameters to filter services/nodes by tags.

```yaml
consul_consumer: True
consul_consumer_services:
- name: hello-app
tags_contains: "test"
tag_regex: "v1.1.*"
```


Road map
-----
Expand Down Expand Up @@ -261,5 +391,3 @@ Some snippets of code was taken from various sources. We will try our best to li
</a><br>
HelloFresh - More Than Food.
</p>
13 changes: 11 additions & 2 deletions tasks/consul-services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,18 @@
chdir: "{{ consul_config_dir }}"
register: registered_consul_services

- name: consul services | Initialize a flat list
set_fact:
consul_producer_services_flat: []

- name: consul services | Populate a flat list
set_fact:
consul_producer_services_flat: "{{ consul_producer_services_flat + [ item.name if item is mapping else item ] }}"
with_items: "{{ consul_producer_services }}"

- name: consul services | Check if any services are old
set_fact:
old_services: "{{ registered_consul_services.stdout_lines | difference(consul_producer_services) }}"
old_services: "{{ registered_consul_services.stdout_lines | difference(consul_producer_services_flat) }}"

- name: consul services | Ensure old consul services JSON (if any) are deregister
file:
Expand All @@ -22,7 +31,7 @@
- name: consul services | Ensure consul services JSON are registered
template:
src="consul-service.j2"
dest="{{ consul_config_dir }}/sv_{{ item }}.json"
dest="{{ consul_config_dir }}/sv_{{ item.name if item is mapping else item }}.json"
with_items: "{{ consul_producer_services }}"
notify:
- reload consul service
37 changes: 37 additions & 0 deletions templates/consul-service.j2
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
{% if item is mapping %}

{% if 'weight' in consul_services[item.name] %}
{% set weight_value = consul_services[item.name].pop('weight') %}
{% if 'tags' in consul_services[item.name] %}
{% set _ = consul_services[item.name]['tags'].append("WEIGHT:" ~ weight_value ) %}
{% else %}
{% set _ = consul_services[item.name].update({'tags': ['WEIGHT:' ~ weight_value]}) %}
{% endif %}
{% endif %}

{% if 'local_port' in consul_services[item.name] %}
{% set local_port = consul_services[item.name].pop('local_port') %}
{% else %}
{% set local_port = consul_services[item.name].get('port') %}
{% endif %}

{% if 'tags' in consul_services[item.name] %}
{% set _ = consul_services[item.name]['tags'].append("local_port:" ~ local_port ) %}
{% else %}
{% set _ = consul_services[item.name].update({'tags': ['local_port:' ~ local_port]}) %}
{% endif %}

{% if 'tags' in consul_services[item.name] %}
{% set _ = consul_services[item.name]['tags'].extend(item.add_tags) %}
{% else %}
{% set _ = consul_services[item.name].update({'tags': item.add_tags}) %}
{% endif %}

{ {{ '' if consul_services[item.name].pop('haproxy', '') else '' }}
"service": {{ consul_services[item.name] | to_nice_json }}
}

{% else %}

{% if 'weight' in consul_services[item] %}
{% set weight_value = consul_services[item].pop('weight') %}
{% if 'tags' in consul_services[item] %}
Expand All @@ -22,3 +57,5 @@
{ {{ '' if consul_services[item].pop('haproxy', '') else '' }}
"service": {{ consul_services[item] | to_nice_json }}
}

{% endif %}
13 changes: 13 additions & 0 deletions test/integration/tags/serverspec/consul_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,16 @@
its(:stdout) { should contain '"Status":"(warning|critical)"' }
end
end

describe 'supertaggedapp' do
describe command 'curl -s -v http://127.0.0.1:8500/v1/health/service/supertaggedapp' do
its(:exit_status) { should eq 0 }
its(:stdout) { should contain '"Service":"supertaggedapp"' }
its(:stdout) { should match /"Tags":\[.*"env:staging".*/ }
its(:stdout) { should match /"Tags":\[.*"test".*/ }
its(:stdout) { should match /"Tags":\[.*"v0\.1\.1".*/ }
its(:stdout) { should match /"Tags":\[.*"from:producer".*/ }
its(:stdout) { should contain '"Port":9998' }
its(:stdout) { should contain '"Status":"(warning|critical)"' }
end
end
24 changes: 22 additions & 2 deletions test/integration/tags/tags_vars.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,35 @@ consul_services :
haproxy :
server_options : "check inter 60s fastinter 5s downinter 8s rise 3 fall 2"
service_mode : "tcp"
# A local service supertaggedapp that uses producer tags
supertaggedapp :
name : "supertaggedapp"
tags :
- "test"
- "v0.1.1"
- "env:staging"
port : 9998
check :
script : "curl localhost:9998 > /dev/null 2>&1"
interval : "60s"
haproxy :
server_options : "check inter 60s fastinter 5s downinter 8s rise 3 fall 2"
service_mode : "tcp"


consul_producer : True
consul_producer_services : [ 'superssh', 'hellofresh', "superdb" ]
consul_producer_services :
- 'superssh'
- 'hellofresh'
- 'superdb'
- name: supertaggedapp
add_tags: ['from:producer']

consul_consumer : True
consul_consumer_services :
- 'superdb'
- name: 'superssh'
- name: 'supertaggedapp'
- name: "hellofresh"
tags_contains: "test"
tag_regex: "v1.1.*"

0 comments on commit 2193ba6

Please sign in to comment.