CORD-536 updated to support the setting of repo via vars

Change-Id: I84988b634967d8be2e5a9f3a79352be5efa9c0c0
diff --git a/ansible/roles/docker/tasks/debian.yml b/ansible/roles/docker/tasks/debian.yml
index 55178b1..40539f9 100644
--- a/ansible/roles/docker/tasks/debian.yml
+++ b/ansible/roles/docker/tasks/debian.yml
@@ -1,6 +1,6 @@
 - name: Debian add Docker repository and update apt cache
   apt_repository:
-    repo: deb https://apt.dockerproject.org/repo ubuntu-{{ debian_version }} main
+    repo: "{{ docker_apt_repo | default('deb https://apt.dockerproject.org/repo ubuntu-{{ debian_version }} main') }}"
     update_cache: yes
     state: present
   tags: [docker]
diff --git a/ansible/roles/java8-oracle/tasks/main.yml b/ansible/roles/java8-oracle/tasks/main.yml
index 9bdc946..3c31110 100644
--- a/ansible/roles/java8-oracle/tasks/main.yml
+++ b/ansible/roles/java8-oracle/tasks/main.yml
@@ -5,7 +5,9 @@
 
 - name: Add Oracle Java repository
   become: yes
-  apt_repository: repo='ppa:webupd8team/java' update_cache=yes
+  apt_repository:
+    repo: "{{ java_apt_repo | default('ppa:webupd8team/java') }}"
+    update_cache: yes
 
 - name: Accept Java 8 license
   become: yes
diff --git a/build.gradle b/build.gradle
index 733ead5..aa33b39 100644
--- a/build.gradle
+++ b/build.gradle
@@ -314,8 +314,6 @@
             .p(config.seedServer.external_bc, "external_bc")
             .p(config.seedServer.external_network, "external_network")
             .p(config.seedServer.external_iface, "external_iface")
-            .p(config.seedServer.fabric_ip, "fabric_ip")
-            .p(config.seedServer.fabric_network, "fabric_network")
             .p(config.seedServer.fabric_iface, "fabric_iface")
             .p(config.seedServer.domain, "domain")
 	    .p(config.seedServer.virtualbox_support, "virtualbox_support")
@@ -372,8 +370,6 @@
             .p(config.seedServer.external_gw, "external_gw")
             .p(config.seedServer.external_network, "external_network")
             .p(config.seedServer.external_iface, "external_iface")
-	    .p(config.seedServer.fabric_ip, "fabric_ip")
-	    .p(config.seedServer.fabric_network, "fabric_network")
 	    .p(config.seedServer.fabric_iface, "fabric_iface")
             .p(config.seedServer.domain, "domain")
             .p(config.seedServer.virtualbox_support, "virtualbox_support")
diff --git a/ip-allocator/allocator.go b/ip-allocator/allocator.go
index a4757e4..03dc9e8 100644
--- a/ip-allocator/allocator.go
+++ b/ip-allocator/allocator.go
@@ -25,7 +25,8 @@
 	Port      int    `default:"4242"`
 	Listen    string `default:"0.0.0.0"`
 	Network   string `default:"10.0.0.0/24"`
-	Skip      int    `default:"1"`
+	RangeLow  string `default:"10.0.0.2" envconfig:"RANGE_LOW"`
+	RangeHigh string `default:"10.0.0.253" envconfig:"RANGE_HIGH"`
 	LogLevel  string `default:"warning" envconfig:"LOG_LEVEL"`
 	LogFormat string `default:"text" envconfig:"LOG_FORMAT"`
 }
@@ -62,16 +63,19 @@
 	log.Level = level
 
 	log.Infof(`Configuration:
-	    Listen:       %s
-	    Port:         %d
-	    Network:      %s
-	    SKip:         %d
-	    Log Level:    %s
-	    Log Format:   %s`, config.Listen, config.Port, config.Network, config.Skip,
+	    LISTEN:       %s
+	    PORT:         %d
+	    NETWORK:      %s
+	    RANGE_LOW:    %s
+	    RANGE_HIGH:   %s
+	    LOG_LEVEL:    %s
+	    LOG_FORMAT:   %s`,
+		config.Listen, config.Port,
+		config.Network, config.RangeLow, config.RangeHigh,
 		config.LogLevel, config.LogFormat)
 
 	context.storage = &MemoryStorage{}
-	context.storage.Init(config.Network, config.Skip)
+	context.storage.Init(config.Network, config.RangeLow, config.RangeHigh)
 
 	router := mux.NewRouter()
 	router.HandleFunc("/allocations/{mac}", context.ReleaseAllocationHandler).Methods("DELETE")
diff --git a/ip-allocator/storage.go b/ip-allocator/storage.go
index 3fc3e99..0832558 100644
--- a/ip-allocator/storage.go
+++ b/ip-allocator/storage.go
@@ -14,6 +14,7 @@
 package main
 
 import (
+	"bytes"
 	"math"
 	"net"
 	"strconv"
@@ -21,7 +22,7 @@
 )
 
 type Storage interface {
-	Init(networkIn string, skip int) error
+	Init(networkIn string, low string, high string) error
 	Get(mac string) (string, error)
 	GetAll() map[string]string
 	Put(mac, ip string) error
@@ -36,7 +37,25 @@
 	readIdx, writeIdx, size uint
 }
 
-func (s *MemoryStorage) Init(networkIn string, skip int) error {
+func inIPRange(from net.IP, to net.IP, test net.IP) bool {
+	if from == nil || to == nil || test == nil {
+		return false
+	}
+
+	from16 := from.To16()
+	to16 := to.To16()
+	test16 := test.To16()
+	if from16 == nil || to16 == nil || test16 == nil {
+		return false
+	}
+
+	if bytes.Compare(test16, from16) >= 0 && bytes.Compare(test16, to16) <= 0 {
+		return true
+	}
+	return false
+}
+
+func (s *MemoryStorage) Init(networkIn string, low string, high string) error {
 	_, network, err := net.ParseCIDR(networkIn)
 	if err != nil {
 		return err
@@ -55,25 +74,24 @@
 	if err != nil {
 		return err
 	}
-	hostCount := int(math.Pow(2, float64(32-bits))) - skip
+	hostCount := int(math.Pow(2, float64(32-bits)))
 	s.readIdx = 0
 	s.writeIdx = 0
 	s.size = uint(hostCount)
 	s.allocated = make(map[string]IPv4)
-	s.available = make([]IPv4, hostCount)
-	for i := 0; i < skip; i += 1 {
-		ip, err = ip.Next()
-		if err != nil {
-			return err
-		}
-	}
+	s.available = make([]IPv4, 0, hostCount)
+	ipLow := net.ParseIP(low)
+	ipHigh := net.ParseIP(high)
 	for i := 0; i < hostCount; i += 1 {
-		s.available[i] = ip
+		if inIPRange(ipLow, ipHigh, net.ParseIP(ip.String())) {
+			s.available = append(s.available, ip)
+		}
 		ip, err = ip.Next()
 		if err != nil {
 			return err
 		}
 	}
+	log.Debugf("AVAILABLE: %+v\n", s.available)
 	return nil
 }
 
diff --git a/provisioner/provisioner.go b/provisioner/provisioner.go
index 590470b..73d0d1a 100644
--- a/provisioner/provisioner.go
+++ b/provisioner/provisioner.go
@@ -24,10 +24,11 @@
 type Config struct {
 	Port            int    `default:"4243"`
 	Listen          string `default:"0.0.0.0"`
-	RoleSelectorURL string `default:"" envconfig:"role_selector_url"`
-	DefaultRole     string `default:"compute-node" envconfig:"default_role"`
+	RoleSelectorURL string `default:"" envconfig:"ROLE_SELECTOR_URL"`
+	DefaultRole     string `default:"compute-node" envconfig:"DEFAULT_ROLE"`
 	Script          string `default:"do-ansible"`
-	StorageURL      string `default:"memory:" envconfig:"storage_url"`
+	StorageURL      string `default:"memory:" envconfig:"STORAGE_URL"`
+	NumberOfWorkers int    `default:"5" envconfig:"NUMBER_OF_WORKERS"`
 	LogLevel        string `default:"warning" envconfig:"LOG_LEVEL"`
 	LogFormat       string `default:"text" envconfig:"LOG_FORMAT"`
 }
@@ -66,16 +67,18 @@
 	log.Level = level
 
 	log.Infof(`Configuration:
-	    Listen:          %s
-	    Port:            %d
-	    RoleSelectorURL: %s
-	    DefaultRole:     %s
-	    Script:          %s
-	    StorageURL:      %s
-	    Log Level:       %s
-	    Log Format:      %s`,
+	    LISTEN:             %s
+	    PORT:               %d
+	    ROLE_SELECTION_URL: %s
+	    DEFAULT_ROLE:       %s
+	    SCRIPT:             %s
+	    STORAGE_URL:        %s
+	    NUMBER_OF_WORERS:   %d
+	    LOG_LEVEL:          %s
+	    LOG_FORMAT:         %s`,
 		context.config.Listen, context.config.Port, context.config.RoleSelectorURL,
 		context.config.DefaultRole, context.config.Script, context.config.StorageURL,
+		context.config.NumberOfWorkers,
 		context.config.LogLevel, context.config.LogFormat)
 
 	context.storage, err = NewStorage(context.config.StorageURL)
@@ -92,7 +95,7 @@
 	http.Handle("/", router)
 
 	// Start the dispatcher and workers
-	context.dispatcher = NewDispatcher(5, context.storage)
+	context.dispatcher = NewDispatcher(context.config.NumberOfWorkers, context.storage)
 	context.dispatcher.Start()
 
 	http.ListenAndServe(fmt.Sprintf("%s:%d", context.config.Listen, context.config.Port), nil)
diff --git a/roles/ansible/tasks/main.yml b/roles/ansible/tasks/main.yml
index 2cf2f07..faffdd1 100644
--- a/roles/ansible/tasks/main.yml
+++ b/roles/ansible/tasks/main.yml
@@ -1,7 +1,7 @@
 - name: Ansible Repository
   become: yes
   apt_repository:
-    repo="ppa:ansible/ansible"
+    repo: "{{ ansible_apt_repo | default('ppa:ansible/ansible') }}"
 
 - name: Ensure Ansible
   become: yes
diff --git a/roles/compute-node/meta/main.yml b/roles/compute-node/meta/main.yml
index 45b0e96..047a60f 100644
--- a/roles/compute-node/meta/main.yml
+++ b/roles/compute-node/meta/main.yml
@@ -12,4 +12,5 @@
   galaxy_tags:
     - cord
 dependencies:
+  - { role: local-ubuntu-repository, when: ubuntu_apt_repo is defined }
   - { role : docker }
diff --git a/roles/docker/files/docker_apt_key.gpg b/roles/docker/files/docker_apt_key.gpg
new file mode 100644
index 0000000..bf09e4c
--- /dev/null
+++ b/roles/docker/files/docker_apt_key.gpg
@@ -0,0 +1,64 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+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
+EJOQTvBR8Q==
+=Yhur
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/roles/docker/meta/main.yml b/roles/docker/meta/main.yml
index bf39d8c..ca35ded 100644
--- a/roles/docker/meta/main.yml
+++ b/roles/docker/meta/main.yml
@@ -12,4 +12,5 @@
   galaxy_tags:
     - development
     - system
-dependencies: []
+dependencies:
+  - { role: local-ubuntu-repository, when: ubuntu_apt_repo is defined }
diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml
index 644bd80..d3b3622 100644
--- a/roles/docker/tasks/main.yml
+++ b/roles/docker/tasks/main.yml
@@ -8,13 +8,12 @@
 - name: Docker Apt Key
   become: yes
   apt_key:
-    keyserver: hkp://p80.pool.sks-keyservers.net:80
-    id: 58118E89F3A912897C070ADBF76221572C52609D
+    data="{{ lookup('file', 'docker_apt_key.gpg') }}"
 
 - name: Docker repository
   become: yes
   apt_repository:
-    repo: deb https://apt.dockerproject.org/repo ubuntu-trusty main
+    repo: "{{ docker_apt_repo | default('deb https://apt.dockerproject.org/repo ubuntu-trusty main') }}"
     update_cache: yes
     state: present
 
diff --git a/roles/head-node/files/compute-node-vars.yml b/roles/head-node/files/compute-node-vars.yml.j2
similarity index 82%
rename from roles/head-node/files/compute-node-vars.yml
rename to roles/head-node/files/compute-node-vars.yml.j2
index 7ded468..10bc4e0 100644
--- a/roles/head-node/files/compute-node-vars.yml
+++ b/roles/head-node/files/compute-node-vars.yml.j2
@@ -52,3 +52,27 @@
 {% if compute_node.management.ignore.bus_types is defined and compute_node.management.ignore.bus_types != omit %}
 management_ignore_bus_types: '{{ compute_node.management.ignore.bus_types }}'
 {% endif %}
+{% if ubuntu_apt_repo is defined %}
+ubuntu_apt_repo: '{{ ubuntu_apt_repo }}'
+{% endif %}
+{% if ubuntu_updates_apt_repo is defined %}
+ubuntu_updates_apt_repo: '{{ ubuntu_updates_apt_repo }}'
+{% endif %}
+{% if docker_apt_repo is defined %}
+docker_apt_repo: '{{ docker_apt_repo }}'
+{% endif %}
+{% if java_apt_repo is defined %}
+java_apt_repo: '{{ java_apt_repo }}'
+{% endif %}
+{% if ansible_apt_repo is defined %}
+ansible_apt_repo: '{{ ansible_apt_repo }}'
+{% endif %}
+{% if maas_apt_repo is defined %}
+maas_apt_repo: '{{ maas_apt_repo }}'
+{% endif %}
+{% if dell_apt_repo is defined %}
+dell_apt_repo: '{{ dell_apt_repo }}'
+{% endif %}
+{% if juju_apt_repo is defined %}
+juju_apt_repo: '{{ juju_apt_repo }}'
+{% endif %}
diff --git a/roles/head-node/tasks/main.yml b/roles/head-node/tasks/main.yml
index f85c86e..a6409ef 100644
--- a/roles/head-node/tasks/main.yml
+++ b/roles/head-node/tasks/main.yml
@@ -81,7 +81,7 @@
 - name: Ensure Compute and Switch Node Variables
   become: yes
   template:
-    src=files/compute-node-vars.yml
+    src=files/compute-node-vars.yml.j2
     dest=/etc/maas/ansible/vars/compute-node-vars.yml
     owner=maas
     group=maas
diff --git a/roles/java8-oracle/tasks/main.yml b/roles/java8-oracle/tasks/main.yml
index 191c627..8573f43 100644
--- a/roles/java8-oracle/tasks/main.yml
+++ b/roles/java8-oracle/tasks/main.yml
@@ -5,7 +5,9 @@
 
 - name: Add Oracle Java Repository
   become: yes
-  apt_repository: repo='ppa:webupd8team/java' update_cache=yes
+  apt_repository:
+    repo: "{{ java_apt_repo | default('ppa:webupd8team/java') }}"
+    update_cache: yes
 
 - name: Accept Java 8 License
   become: yes
diff --git a/roles/local-ubuntu-repository/files/sources.list.j2 b/roles/local-ubuntu-repository/files/sources.list.j2
new file mode 100644
index 0000000..9fad8a1
--- /dev/null
+++ b/roles/local-ubuntu-repository/files/sources.list.j2
@@ -0,0 +1,8 @@
+# This file was generated by the CORD deployment scripts. The values in this file are
+# set in the deployment configuration file
+{% if ubuntu_apt_repo is defined %}
+{{ ubuntu_apt_repo }}
+{% endif %}
+{% if ubuntu_updates_apt_repo is defined %}
+{{ ubuntu_updates_apt_repo }}
+{% endif %}
diff --git a/roles/local-ubuntu-repository/tasks/main.yml b/roles/local-ubuntu-repository/tasks/main.yml
new file mode 100644
index 0000000..9e8c439
--- /dev/null
+++ b/roles/local-ubuntu-repository/tasks/main.yml
@@ -0,0 +1,46 @@
+---
+- name: Ensure Local Repository Settings
+  become: yes
+  template:
+    backup: yes
+    dest: /etc/apt/sources.list
+    src: files/sources.list.j2
+    group: root
+    owner: root
+    mode: 0644
+  when: ubuntu_apt_repo is defined
+
+- name: Capture Existing Respositories
+  command: find /etc/apt/sources.list.d \! -type d -name '*.list'
+  changed_when: false
+  register: existing_repo_lists
+  when: ubuntu_apt_repo is defined
+
+- name: Capture Timestamp
+  set_fact:
+    timestamp: "{{ lookup('pipe', 'date +%Y-%m-%d@%H:%M:%S') }}"
+  changed_when: false
+  when: ubuntu_apt_repo is defined
+
+- name: Backup Existing Respositories
+  become: yes
+  copy:
+    remote_src: True
+    src:  "{{ item }}"
+    dest: "{{ item }}.{{ timestamp }}~"
+  with_items: "{{ existing_repo_lists.stdout_lines }}"
+  when: ubuntu_apt_repo is defined
+
+- name: Remove Existing Repositories
+  become: yes
+  file:
+    state: absent
+    path: "{{ item }}"
+  with_items: "{{ existing_repo_lists.stdout_lines }}"
+  when: ubuntu_apt_repo is defined
+
+- name: Ensure Update Repository List
+  become: yes
+  apt:
+    update_cache: yes
+  when: ubuntu_apt_repo is defined
diff --git a/roles/maas/tasks/main.yml b/roles/maas/tasks/main.yml
index 0218c57..540c843 100644
--- a/roles/maas/tasks/main.yml
+++ b/roles/maas/tasks/main.yml
@@ -54,7 +54,7 @@
 - name: MAAS Repository
   become: yes
   apt_repository:
-    repo: ppa:maas/stable
+    repo: "{{ maas_apt_repo | default('ppa:maas/stable') }}"
     update_cache: yes
     state: present
     validate_certs: no
diff --git a/roles/maas/templates/automation-compose.yml.j2 b/roles/maas/templates/automation-compose.yml.j2
index 1ce54be..52467f2 100644
--- a/roles/maas/templates/automation-compose.yml.j2
+++ b/roles/maas/templates/automation-compose.yml.j2
@@ -28,7 +28,8 @@
       - "ALLOCATE_PORT=4242"
       - "ALLOCATE_LISTEN=0.0.0.0"
       - "ALLOCATE_NETWORK={{ networks.fabric }}"
-      - "ALLOCATE_SKIP=2"
+      - "ALLOCATE_RANGE_LOW={{ ranges.fabric.low }}"
+      - "ALLOCATE_RANGE_HIGH={{ ranges.fabric.high }}"
       - "ALLOCATE_LOG_LEVEL=debug"
       - "ALLOCATE_LOG_FORMAT=text"
     restart: unless-stopped
@@ -54,6 +55,7 @@
       - "PROVISION_DEFAULT_ROLE=compute-node"
       - "PROVISION_SCRIPT=/etc/maas/ansible/do-ansible"
       - "PROVISION_STORAGE_URL=consul://{{ mgmt_ip_address.stdout }}:8500"
+      - "PROVISION_NUMBER_OF_WORKERS=1"
       - "PROVISION_LOG_LEVEL=debug"
       - "PROVISION_LOG_FORMAT=text"
     volumes:
diff --git a/roles/maas/vars/main.yml b/roles/maas/vars/main.yml
index 7d2f69f..a20e6c2 100644
--- a/roles/maas/vars/main.yml
+++ b/roles/maas/vars/main.yml
@@ -43,13 +43,18 @@
     #                the leaf - spine fabric
     management: "{{ management_network | default('10.6.0.0/24') }}"
     bridge: "{{ bridge_network | default('172.42.0.0/24') }}"
-    fabric: "{{ fabric_network | default('10.6.1.0/24') }}"
+    fabric: "{{ fabric_ip | default('10.6.1.0/24') | ipaddr('0') }}"
 
     # CHANGE:
     #   'bridge' name of the bride to create that is used when connecting
     #            the VMs created in support of XOS
     bridge_name: "{{ bridge_name | default('mgmtbr') }}"
 
+ranges:
+    fabric:
+        low: "{{ fabric_range_low | default(fabric_ip | default('10.6.1.0/24')) | ipaddr(2) | ipaddr('address') }}"
+        high: "{{ fabric_range_high | default(fabric_ip | default('10.6.1.0/24')) | ipaddr(-3) | ipaddr('address') }}"
+
 docker:
     registry: "{{ docker_registry | default('opencord') }}"
     image_version: "{{ docker_image_version | default('latest') }}"