CORD-281 CORD-551 hide secret for switchq and pull images on deploy
Change-Id: Ie0a5f4b1f9804391b058b25663ba10fa73df4746
diff --git a/automation/state.go b/automation/state.go
index f305509..3769d2d 100644
--- a/automation/state.go
+++ b/automation/state.go
@@ -207,7 +207,7 @@
})
if err != nil {
- log.Errorf("unable to provision '%s' (%s) : %s", node.ID, node.Hostname(), err)
+ log.Errorf("unable to provision '%s' (%s) : %s", node.ID(), node.Hostname(), err)
}
} else if options.ProvisionTTL > 0 &&
diff --git a/roles/maas/tasks/main.yml b/roles/maas/tasks/main.yml
index 540c843..83c43b1 100644
--- a/roles/maas/tasks/main.yml
+++ b/roles/maas/tasks/main.yml
@@ -320,16 +320,17 @@
group: docker
mode: 0755
-- name: Ensure MAAS API Key Secret
+- name: Ensure Automation Container Secrets
become: yes
- lineinfile:
- dest: /etc/maas/secrets/automation.env
- create: true
- regexp: "^AUTOMATION_MAAS_API_KEY=.*$"
- line: "AUTOMATION_MAAS_API_KEY={{ apikey.stdout }}"
+ template:
+ src: templates/{{ item }}.j2
+ dest: /etc/maas/secrets/{{ item }}
owner: root
group: docker
mode: 0440
+ with_items:
+ - automation.env
+ - switchq.env
- name: Custom Automation Compose Configurations
become: yes
@@ -342,7 +343,28 @@
with_items:
- automation-compose.yml
-- name: Automation
+- name: Kill Automation Containers
+ become: yes
+ command: docker-compose -f /etc/maas/{{ item }} kill
+ with_items:
+ - automation-compose.yml
+ changed_when: true
+
+- name: Remove Automation Containers
+ become: yes
+ command: docker-compose -f /etc/maas/{{ item }} rm -f
+ with_items:
+ - automation-compose.yml
+ changed_when: true
+
+- name: Pull Latest Automation Images
+ become: yes
+ command: docker-compose -f /etc/maas/{{ item }} pull
+ with_items:
+ - automation-compose.yml
+ changed_when: true
+
+- name: Start Automation
become: yes
command: docker-compose -f /etc/maas/{{ item }} up -d
with_items:
diff --git a/roles/maas/templates/automation-compose.yml.j2 b/roles/maas/templates/automation-compose.yml.j2
index 52467f2..78ddb3a 100644
--- a/roles/maas/templates/automation-compose.yml.j2
+++ b/roles/maas/templates/automation-compose.yml.j2
@@ -72,6 +72,8 @@
- "lab.component=switchq"
links:
- provisioner
+ env_file:
+ - "/etc/maas/secrets/switchq.env"
environment:
- "SWITCHQ_SCRIPT=/etc/maas/ansible/do-switch"
- "SWITCHQ_PROVISION_URL=http://provisioner:4243/provision/"
@@ -81,7 +83,6 @@
- "SWITCHQ_LOG_LEVEL=debug"
- "SWITCHQ_LOG_FORMAT=text"
- "SWITCHQ_MAAS_URL=http://{{ mgmt_ip_address.stdout }}/MAAS"
- - "SWITCHQ_MAAS_API_KEY={{ apikey.stdout }}"
volumes:
- "/etc/bind/maas:/switchq/dhcp"
restart: unless-stopped
diff --git a/roles/maas/templates/automation.env.j2 b/roles/maas/templates/automation.env.j2
new file mode 100644
index 0000000..679cd8e
--- /dev/null
+++ b/roles/maas/templates/automation.env.j2
@@ -0,0 +1 @@
+AUTOMATION_MAAS_API_KEY={{ apikey.stdout }}
diff --git a/roles/maas/templates/switchq.env.j2 b/roles/maas/templates/switchq.env.j2
new file mode 100644
index 0000000..314e684
--- /dev/null
+++ b/roles/maas/templates/switchq.env.j2
@@ -0,0 +1 @@
+SWITCHQ_MAAS_API_KEY={{ apikey.stdout }}
diff --git a/switchq/switchq.go b/switchq/switchq.go
index deddf74..e946ff1 100644
--- a/switchq/switchq.go
+++ b/switchq/switchq.go
@@ -21,19 +21,21 @@
"github.com/gorilla/mux"
maas "github.com/juju/gomaasapi"
"github.com/kelseyhightower/envconfig"
+ "io/ioutil"
"net/http"
+ "regexp"
"sync"
"time"
)
type Config struct {
- VendorsURL string `default:"file:///switchq/vendors.json" envconfig:"vendors_url"`
- AddressURL string `default:"file:///switchq/dhcp_harvest.inc" envconfig:"address_url"`
- PollInterval string `default:"1m" envconfig:"poll_interval"`
- ProvisionTTL string `default:"1h" envconfig:"provision_ttl"`
- ProvisionURL string `default:"" envconfig:"provision_url"`
- RoleSelectorURL string `default:"" envconfig:"role_selector_url"`
- DefaultRole string `default:"fabric-switch" envconfig:"default_role"`
+ VendorsURL string `default:"file:///switchq/vendors.json" envconfig:"VENDORS_URL"`
+ AddressURL string `default:"file:///switchq/dhcp_harvest.inc" envconfig:"ADDRESS_URL"`
+ PollInterval string `default:"1m" envconfig:"POLL_INTERVAL"`
+ ProvisionTTL string `default:"1h" envconfig:"PROVISION_TTL"`
+ ProvisionURL string `default:"" envconfig:"PROVISION_URL"`
+ RoleSelectorURL string `default:"" envconfig:"ROLE_SELECTOR_URL"`
+ DefaultRole string `default:"fabric-switch" envconfig:"DEFAULT_ROLE"`
Script string `default:"do-ansible"`
LogLevel string `default:"warning" envconfig:"LOG_LEVEL"`
LogFormat string `default:"text" envconfig:"LOG_FORMAT"`
@@ -41,6 +43,8 @@
Port int `default:"4244"`
MaasURL string `default:"http://localhost/MAAS" envconfig:"MAAS_URL"`
MaasKey string `default:"" envconfig:"MAAS_API_KEY"`
+ ShowApiKey bool `default:"false" envconfig:"MAAS_SHOW_API_KEY"`
+ ApiKeyFile string `default:"/secrets/maas_api_key" envconfig:"MAAS_API_KEY_FILE"`
vendors Vendors
addressSource AddressSource
@@ -302,25 +306,33 @@
}
log.Level = level
+ re := regexp.MustCompile("[^:]")
+ pubKey := context.config.MaasKey
+ if !context.config.ShowApiKey {
+ pubKey = re.ReplaceAllString(context.config.MaasKey, "X")
+ }
+
log.Infof(`Configuration:
- Vendors URL: %s
- Poll Interval: %s
- Address Source: %s
- Provision TTL: %s
- Provision URL: %s
- Role Selector URL: %s
- Default Role: %s
- Script: %s
- API Listen IP: %s
- API Listen Port: %d
- MAAS URL: %s
- MAAS APIKEY: %s
- Log Level: %s
- Log Format: %s`,
+ VENDORS_URL: %s
+ POLL_INTERVAL: %s
+ ADDRESS_URL: %s
+ PROVISION_TTL: %s
+ PROVISION_URL: %s
+ ROLE_SELECTOR_URL: %s
+ DEFAULT_ROLE: %s
+ SCRIPT: %s
+ LISTEN: %s
+ PORT: %d
+ MAAS_URL: %s
+ MAAS_SHOW_API_KEY %t
+ MAAS_API_KEY: %s
+ MAAS_API_KEY_FILE: %s
+ LOG_LEVEL: %s
+ LOG_FORMAT: %s`,
context.config.VendorsURL, context.config.PollInterval, context.config.AddressURL, context.config.ProvisionTTL,
context.config.ProvisionURL, context.config.RoleSelectorURL, context.config.DefaultRole, context.config.Script,
- context.config.Listen, context.config.Port, context.config.MaasURL, context.config.MaasKey,
- context.config.LogLevel, context.config.LogFormat)
+ context.config.Listen, context.config.Port, context.config.MaasURL, context.config.ShowApiKey, pubKey,
+ context.config.ApiKeyFile, context.config.LogLevel, context.config.LogFormat)
context.config.vendors, err = NewVendors(context.config.VendorsURL)
checkError(err, "Unable to create known vendors list from specified URL '%s' : %s", context.config.VendorsURL, err)
@@ -334,6 +346,24 @@
context.config.ttl, err = time.ParseDuration(context.config.ProvisionTTL)
checkError(err, "Unable to parse specified provision TTL value of '%s' : %s", context.config.ProvisionTTL, err)
+ // Attempt to load the API key from a file if it was not set via the environment
+ // and if the file exists
+ if context.config.MaasKey == "" {
+ log.Debugf("Attempting to read MAAS API key from file '%s', because it was not set via environment", context.config.ApiKeyFile)
+ keyBytes, err := ioutil.ReadFile(context.config.ApiKeyFile)
+ if err != nil {
+ log.Warnf("Failed to read MAAS API key from file '%s', was the file mounted as a volume? : %s ",
+ context.config.ApiKeyFile, err)
+ } else {
+ context.config.MaasKey = string(keyBytes)
+ if context.config.ShowApiKey {
+ pubKey = context.config.MaasKey
+ } else {
+ pubKey = re.ReplaceAllString(context.config.MaasKey, "X")
+ }
+ }
+ }
+
if len(context.config.MaasURL) > 0 {
// Attempt to connect to MAAS