README.md in vcloud-edge_gateway-0.2.1 vs README.md in vcloud-edge_gateway-0.2.2
- old
+ new
@@ -1,8 +1,11 @@
# vCloud Edge Gateway
-vCloud Edge Gateway is a tool that supports automated provisiong of a VMware vCloud Edge Gateway. It depends on [vCloud Core](https://github.com/alphagov/vcloud-core) and uses Fog under the hood.
+vCloud Edge Gateway is a CLI tool and Ruby library that supports automated
+provisiong of a VMware vCloud Director Edge Gateway appliance. It depends on
+[vCloud Core](https://rubygems.org/gems/vcloud-core) and uses
+[Fog](http://fog.io) under the hood.
## Installation
Add this line to your application's Gemfile:
@@ -20,170 +23,207 @@
To configure an Edge Gateway:
$ vcloud-configure-edge input.yaml
+
## Contributing
1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request
-#Below here, rules are out of date - they will be updated shortly
-###Configure edge gateway services
+### Configure edge gateway services
-You can configure following services on an existing edgegateway using fog.
-- FirewallService
-- NatService
-- LoadBalancerService
+You can configure the following services on an existing edgegateway using
+`vcloud-configure-edge`.
-###How to configure:
+- firewall_service
+- nat_service
+- load_balancer_service
-```ruby
-require 'fog'
-vcloud = Fog::Compute::VcloudDirector.new
-vcloud.post_configure_edge_gateway_services edge_gateway_id, configuration
-vcloud.process_task(task.body)
+NB: DHCP and VPN Services are not yet supported by the Fog platform underneath.
+Support for these is being considered.
+
+The `vcloud-configure-edge` tool takes an input YAML file describing one
+or more of these services and updates the edge gateway configuration to match,
+obeying the following rules:
+
+* A given service will not be reconfigured if its input configuration matches
+ the live configuration - to prevent unneccessary service reloads.
+* If a service is not defined in the input config, it will not be updated on
+ the remote edge gateway - to permit per-service configurations.
+* If more than one service is defined and have changed, then all changed
+ services will be updated in the same API request.
+
+#### firewall_service
+
+The edge gateway firewall service offers basic inbound and outbound
+IPv4 firewall rules, applied on top of a default policy.
+
+We default to the global firewall policy being 'drop', and each individual
+rule to be 'allow'. Rules are applied in order, with the last match winning.
+
+Each rule has the following form:
+
```
+ - description: "Description of your rule"
+ destination_port_range: "53" # defaults to 'Any'
+ destination_ip: "192.0.2.15"
+ source_ip: "Any"
+ source_port_range: "1024-65535" # defaults to 'Any'
+ protocol: 'udp' # defaults to 'tcp'
+ policy: 'allow' # defaults to 'drop'
+```
-The Configuration contain definitions of any of the services listed.Details of service configurations may vary,
-but the mechanism is the same for updating any Edge Gateway service.<br/>You can include one or more services when you configure an Edge Gateway.
+Rule fields have the following behaviour
-###Examples:
+* `policy` defaults to 'allow', can also be 'drop'.
+* `protocol` defaults to 'tcp'. Can be 'icmp', 'udp', 'tcp+udp' or 'any'
+* `source_port_range` and `destination_port_range` can be `Any` (default),
+ a single port number (eg '443'), or a port range such as '10000-20000'
+* `source_ip` and `destination_ip` *must* be specified.
+* `source_ip` and `destination_ip` can be one of:
+ * `Any` to match any address.
+ * `external`, or `internal` to refer to addresses on the respective 'sides'
+ of the edge gateway.
+ * A single IP address, such as `192.0.2.44`
+ * A CIDR range, eg `192.0.2.0/24`
+ * A hyphened range, such as `192.0.2.50-192.0.2.60`
-Service examples, to be used in place of the `configuration` object above.
+#### nat_service
-Firewall:
-```ruby
-configuration = {
- :FirewallService => {
- :IsEnabled => true,
- :DefaultAction => 'allow',
- :LogDefaultAction => false,
- :FirewallRule => [
- {
- :Policy => 'allow',
- :Description => 'description',
- :Protocols => {:Tcp => true},
- :Port => 22,
- :DestinationPortRange => 22,
- :DestinationIp => 'Internal',
- :SourcePort => 22,
- :SourceIp => 'External',
- :SourcePortRange => '22'
- }
- ]
- }
-}
+The edge gateway NAT service offers simple stateful Source-NAT and
+Destination-NAT rules.
+
+SNAT rules take a source IP address range and 'Translated IP address'. The translated
+address is generally the public address that you wish traffic to appear to be
+coming from. SNAT rules are typically used to enable outbound connectivity from
+a private address range behind the edge. The UUID of the external network that
+the traffic should appear to come from must also be specified, as per the
+`network_id` field below.
+
+A SNAT rule has the following form:
+
```
+ - rule_type: 'SNAT'
+ network_id: '12345678-1234-1234-1234-1234567890bb' # id of EdgeGateway external network
+ original_ip: "10.10.10.0/24" # internal IP range
+ translated_ip: "192.0.2.100
+```
-Load balancer:
-```ruby
-configuration = {
- :LoadBalancerService => {
- :IsEnabled => "true",
- :Pool => [
- {
- :Name => 'web-app',
- :ServicePort => [
- {
- :IsEnabled => "true",
- :Protocol => "HTTP",
- :Algorithm => "ROUND_ROBIN",
- :Port => 80,
- :HealthCheckPort => 80,
- :HealthCheck => {
- :Mode => "HTTP", :HealthThreshold => 1, :UnhealthThreshold => 6, :Interval => 20, :Timeout => 25
- }
- },
- {
- :IsEnabled => true,
- :Protocol => "HTTPS",
- :Algorithm => "ROUND_ROBIN",
- :Port => 443,
- :HealthCheckPort => 443,
- :HealthCheck => {
- :Mode => "SSL", :HealthThreshold => 1, :UnhealthThreshold => 6, :Interval => 20, :Timeout => 25
- }
- }
- ],
- :Member => [
- {
- :IpAddress => "192.0.2.0",
- :Weight => 1,
- :ServicePort => [
- {:Protocol => "HTTP", :Port => 80, :HealthCheckPort => 80}
- ]
- }
- ]
- }
- ],
- :VirtualServer => [
- {
- :IsEnabled => "true",
- :Name => "app1",
- :Description => "app1",
- :Interface => {:name => "Default", :href => "https://vmware.api.net/api/admin/network/2ad93597-7b54-43dd-9eb1-631dd337e5a7"},
- :IpAddress => '192.0.2.0',
- :ServiceProfile => [
- {:IsEnabled => "true", :Protocol => "HTTP", :Port => 80, :Persistence => {:Method => ""}},
- {:IsEnabled => "true", :Protocol => "HTTPS", :Port => 443, :Persistence => {:Method => ""}}
- ],
- :Logging => false,
- :Pool => 'web-app'
- }
- ]
- }
-}
+* `original_ip` can be a single IP address, a CIDR range, or a hyphenated
+ IP range.
+* `network_id` must be the UUID of the network on which the `translated_ip` sits.
+ Instructions are in the [finding external network
+ details](#finding-external-network-details-from-vcloud-walk) section below.
+* `translated_ip` must be an available address on the network specified by
+ `network_id`
+
+
+DNAT rules translate packets addressed to a particular destination IP (and
+typically port) and translate it to an internal address - they are usually
+defined to allow external hosts to connect to services on hosts with private IP
+addresses.
+
+A DNAT rule has the following form, and translates packets going to the
+`original_ip` (and `original_port`) to the `translated_ip` and
+`translated_port` values.
+
```
+- rule_type: 'DNAT'
+ network_id: '12345678-1234-1234-1234-1234567890bb' # id of EdgeGateway external network
+ original_ip: "192.0.2.98" # Useable address on external network
+ original_port: "22" # external port
+ translated_ip: "10.10.10.10" # internal address to DNAT to
+ translated_port: "22"
+```
-Nat:
-```ruby
-configuration = {
- :NatService => {
- :IsEnabled => true,
- :nat_type => 'ipTranslation',
- :Policy => 'allowTrafficIn',
- :NatRule => [
- {
- :Description => 'a snat rule',
- :RuleType => 'SNAT',
- :IsEnabled => true,
- :Id => '65538',
- :GatewayNatRule => {
- :Interface => {
- :name => 'nft00001',
- :href => 'https://vmware.api.net/api/admin/network/44265cc3-6d63-4ea9-ac72-4905b5aa6111'
- },
- :OriginalIp => "192.0.2.0",
- :TranslatedIp => "203.0.113.10"
- }
- },
- {
- :Description => 'a dnat rule',
- :RuleType => 'DNAT',
- :IsEnabled => true,
- :Id => '65539',
- :GatewayNatRule =>
- {
- :Interface => {
- :name => 'nft00001',
- :href => 'https://vmware.api.net/api/admin/network/44265cc3-6d63-4ea9-ac72-4905b5aa6111'
- },
- :Protocol => 'tcp',
- :OriginalIp => "203.0.113.10",
- :OriginalPort => 22,
- :TranslatedIp => "192.0.2.0",
- :TranslatedPort => 22
- },
- }
- ]
- }
- }
+* `network_id` specifies the UUID of the external network that packets are
+ translated from.
+* `original_ip` is an IP address on the external network above.
+
+#### load_balancer_service
+
+The load balancer service comprises two sets of configurations: 'pools' and
+'virtual_servers'. These are coupled together to form a load balanced service:
+
+* A virtual_server provides the front-end of a load balancer - the port and
+ IP that clients connect to.
+* A pool is a collection of one or more back-end nodes (IP+port combination)
+ that traffic is balanced across.
+* Each virtual_server entry specifies a pool that serves requests destined to
+ it.
+* Multiple virtual_servers can specify the same pool (to run the same service
+ on different FQDNs, for example)
+
+A typical load balancer configuration (for one service) would look something like:
+
```
+load_balancer_service:
-###Debug
+ pools:
+ - name: 'example-pool-1'
+ description: 'A pool balancing traffic across backend nodes on port 8080'
+ service:
+ http:
+ port: 8080
+ members:
+ - ip_address: 10.10.10.11
+ - ip_address: 10.10.10.12
+ - ip_address: 10.10.10.13
-Set environment variable DEBUG=true to see fog debug info.
+ virtual_servers:
+ - name: 'example-virtual-server-1'
+ description: 'A virtual server connecting to example-pool-1'
+ ip_address: 192.0.2.10
+ network: '12345678-1234-1234-1234-123456789012' # id of external network
+ pool: 'example-pool-1' # must refer to a pool name detailed above
+ service_profiles:
+ http: # protocol to balance, can be tcp/http/https.
+ port: '80' # external port
+```
+
+### Finding external network details from vcloud-walk
+
+You can find the network UUID and external address allocations using [vCloud
+Walker](https://rubygems.org/gems/vcloud-walker):
+
+To do this, do:
+
+```
+export FOG_CREDENTIAL={crediental-tag-for-your-organization}
+vcloud-walk edgegateways > edges.out
+```
+
+`edges.out` will contain the complete configuration of all edge gateways in
+your organization. Find the edge gateway you are interested in by searching for
+its name, then look for a GatewayInterface section that has an InterfaceType of
+'uplink'. This should define:
+
+* a 'href' element in a Network section. The UUID at the end of this href is
+ what you need.
+* an IpRange section with a StartAddress and EndAddress -- these define the
+ addresses that you can use for services on this external network.
+
+You can use [jq](http://stedolan.github.io/jq/) to make this easier:
+```
+cat edges.out | jq '
+ .[] | select(.name == "NAME_OF_YOUR_EDGE_GATEWAY")
+ | .Configuration.GatewayInterfaces.GatewayInterface[]
+ | select(.InterfaceType == "uplink")
+ | ( .Network.href, .SubnetParticipation )
+ '
+```
+
+
+
+### Debug output
+
+Set environment variable `DEBUG=true` and/or `EXCON_DEBUG=true` to see Fog debug info.
+
+### References
+
+* [vCloud Director Edge Gateway documentation](http://pubs.vmware.com/vcd-51/topic/com.vmware.vcloud.admin.doc_51/GUID-ADE1DCAB-874F-45A9-9337-1E971DAC0F7D.html)