1
Service exposing implementation details
2
=======================================
8
It is not in the scope of this specification to determine mapping to a
9
public DNS or other directory service.
12
Implementation of ``expose`` and ``unexpose`` subcommands
13
---------------------------------------------------------
15
Two new user commands were added::
17
juju expose <service name>
19
juju unexpose <service name>
21
These commands set and remove a flag znode, **/services/<internal
22
service id>/exposed**, respectively.
25
Hook command additions
26
----------------------
28
Two new hook commands were added for opening and closing ports. They
29
may be executed within any charm hook::
31
open-port port[/protocol]
33
close-port port[/protocol]
35
These commands store in the ZK tree, under **/units/<internal unit
36
id>/ports**, the desired opened port information as serialized to
37
JSON. For example, executing ``open-port 80`` would be serialized as
40
{"open": [{"port": 80, "proto": "tcp"}, ...]}
42
This format accommodates tracking other ancillary information for
45
These commands are executed immediately within the hook.
48
New ``exposed`` and ``unexposed`` service hooks
49
-----------------------------------------------
51
The ``exposed`` service hook runs upon a service being exposed with
52
the ``juju expose`` command. As part of the unit workflow, it is
53
scheduled to run upon the existence of **/services/<internal service
54
id>/exposed** and the service unit being in the ``started`` state.
56
Likewise, the ``unexposed`` service hook runs upon the removal of a
57
**/services/<internal service id>/exposed** flag znode.
59
These hooks will be implemented at a future time.
62
``juju status`` display of opened ports
63
-------------------------------------------
65
If a service has been exposed, then the juju status output is
66
augmented. For the YAML serialization, for each exposed service, the
67
``exposed`` key is added, with the value of ``true``. (It is not
68
displayed otherwise.) For each service unit of an exposed service with
69
opened ports, the ``open-ports`` key is added, with its value a
70
sequence of ``port/proto`` strings. If no ports are opened, its value
74
Provisioning agent implementation
75
---------------------------------
77
The provisioning agent currently is the only place within juju
78
that can take global actions with respect to the provider. Consequently,
79
provisioning is currently responsible for the current, if simple EC2
80
security group management (with the policy of open all ports, seen in
81
the code `juju.providers.ec2.launch.EC2LaunchMachine`).
83
The provisioning agent watches for the existence of
84
**/services/<internal service id>/exposed**, and if so watches the
85
service units settings **/units/<internal unit id>/ports** and makes
86
changes in the firewall settings through the provider.
88
For the EC2 provider, this is done through security groups (see
89
below). Later we will revisit to let a machine agent do this in the
90
context of iptables, so as to get out of the 500 security group limit
91
for EC2, enable multiple service units per machine, be generic with
92
other providers, and to provide future support for internal firewall
96
EC2 provider implementation
97
---------------------------
99
Prior to the launch of a new machine instance, a unique EC2 security
100
group is added. The machine instance is then assigned to this group at
101
launch. Likewise, terminating the machine will result in the EC2
102
provider deleting the security group for the machine. (This cleanup
103
will be implemented in a future branch.)
105
Given this model of a security group per machine, with one service
106
unit per machine, exposing and unexposing ports for a service unit
107
corresponds to EC2's support for authorization and revocation of ports
108
per security group. In particular, EC2 supports a source address of
109
``0.0.0.0/0`` that corresponds to exposing the port to the world.
111
To make this concrete, consider the example of exposing the
112
``my-wordpress`` service. Once the command ``open-port 80`` has been
113
run on a given service unit of ``my-wordpress``, then for the
114
corresponding machine instance, the equivalent of this EC2 command is
117
ec2-authorize $MACHINE_SECURITY_GROUP -P tcp -p 80 -s 0.0.0.0/0
119
``$MACHINE_SECURITY_GROUP`` is named ``juju-ENVIRONMENT-MACHINE_ID``,
120
eg. something like ``juju-prod-2``.
122
Any additional service units of ``my-wordpress``, if they run
123
``open-port 80``, will likewise invoke the equivalent of the above
124
command, for the corresponding machine security groups.
126
If ``my-wordpress`` is unexposed, a ``my-wordpress`` service unit is
127
removed, the ``my-wordpress`` service is destroyed, or the
128
``close-port`` command is run for a service unit, then the equivalent
129
of the following EC2 command is run, for all applicable machines::
131
ec2-revoke $MACHINE_SECURITY_GROUP -P tcp -p 80 -s 0.0.0.0/0
133
Although this section showed the equivalent EC2 commands for
134
simplicity, txaws is used for the actual implementation.
140
The following functionality needs to be added. This should divisible
141
into separate, small branches:
143
* Implement exposed and unexposed hooks.