summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--playbooks/aws/openshift-cluster/config.yml1
-rw-r--r--playbooks/common/openshift-master/config.yml2
-rw-r--r--playbooks/common/openshift-node/config.yml2
-rw-r--r--playbooks/gce/openshift-cluster/config.yml1
-rw-r--r--playbooks/libvirt/openshift-cluster/config.yml1
-rw-r--r--playbooks/openstack/openshift-cluster/config.yml1
-rw-r--r--roles/calico/README.md28
-rw-r--r--roles/calico/defaults/main.yaml10
-rw-r--r--roles/calico/handlers/main.yml8
-rw-r--r--roles/calico/meta/main.yml16
-rw-r--r--roles/calico/tasks/main.yml74
-rw-r--r--roles/calico/templates/calico.cfg.j29
-rw-r--r--roles/calico/templates/calico.conf.j218
-rw-r--r--roles/calico/templates/calico.service.j229
-rw-r--r--roles/calico_master/README.md28
-rw-r--r--roles/calico_master/defaults/main.yaml2
-rw-r--r--roles/calico_master/meta/main.yml17
-rw-r--r--roles/calico_master/tasks/main.yml41
-rw-r--r--roles/calico_master/templates/calico-policy-controller.yml.j2105
-rw-r--r--roles/openshift_common/tasks/main.yml9
-rwxr-xr-xroles/openshift_facts/library/openshift_facts.py19
21 files changed, 421 insertions, 0 deletions
diff --git a/playbooks/aws/openshift-cluster/config.yml b/playbooks/aws/openshift-cluster/config.yml
index d60b68885..8d64b0521 100644
--- a/playbooks/aws/openshift-cluster/config.yml
+++ b/playbooks/aws/openshift-cluster/config.yml
@@ -33,5 +33,6 @@
openshift_use_openshift_sdn: "{{ lookup('oo_option', 'use_openshift_sdn') }}"
os_sdn_network_plugin_name: "{{ lookup('oo_option', 'sdn_network_plugin_name') }}"
openshift_use_flannel: "{{ lookup('oo_option', 'use_flannel') }}"
+ openshift_use_calico: "{{ lookup('oo_option', 'use_calico') }}"
openshift_use_fluentd: "{{ lookup('oo_option', 'use_fluentd') }}"
openshift_use_dnsmasq: false
diff --git a/playbooks/common/openshift-master/config.yml b/playbooks/common/openshift-master/config.yml
index 68b9db03a..81c922043 100644
--- a/playbooks/common/openshift-master/config.yml
+++ b/playbooks/common/openshift-master/config.yml
@@ -129,6 +129,8 @@
etcd_cert_prefix: "master.etcd-"
- role: nuage_master
when: openshift.common.use_nuage | bool
+ - role: calico_master
+ when: openshift.common.use_calico | bool
post_tasks:
- name: Create group for deployment type
diff --git a/playbooks/common/openshift-node/config.yml b/playbooks/common/openshift-node/config.yml
index 6c5a299c1..792ffb4e2 100644
--- a/playbooks/common/openshift-node/config.yml
+++ b/playbooks/common/openshift-node/config.yml
@@ -82,6 +82,8 @@
etcd_cert_subdir: "openshift-node-{{ openshift.common.hostname }}"
etcd_cert_config_dir: "{{ openshift.common.config_base }}/node"
when: openshift.common.use_flannel | bool
+ - role: calico
+ when: openshift.common.use_calico | bool
- role: nuage_node
when: openshift.common.use_nuage | bool
- role: contiv
diff --git a/playbooks/gce/openshift-cluster/config.yml b/playbooks/gce/openshift-cluster/config.yml
index 8e46c5919..2625d4d05 100644
--- a/playbooks/gce/openshift-cluster/config.yml
+++ b/playbooks/gce/openshift-cluster/config.yml
@@ -32,4 +32,5 @@
openshift_use_openshift_sdn: "{{ lookup('oo_option', 'use_openshift_sdn') }}"
os_sdn_network_plugin_name: "{{ lookup('oo_option', 'sdn_network_plugin_name') }}"
openshift_use_flannel: "{{ lookup('oo_option', 'use_flannel') }}"
+ openshift_use_calico: "{{ lookup('oo_option', 'use_calico') }}"
openshift_use_fluentd: "{{ lookup('oo_option', 'use_fluentd') }}"
diff --git a/playbooks/libvirt/openshift-cluster/config.yml b/playbooks/libvirt/openshift-cluster/config.yml
index 44b0f5a3c..f782d6dab 100644
--- a/playbooks/libvirt/openshift-cluster/config.yml
+++ b/playbooks/libvirt/openshift-cluster/config.yml
@@ -33,5 +33,6 @@
openshift_use_openshift_sdn: "{{ lookup('oo_option', 'use_openshift_sdn') }}"
os_sdn_network_plugin_name: "{{ lookup('oo_option', 'sdn_network_plugin_name') }}"
openshift_use_flannel: "{{ lookup('oo_option', 'use_flannel') }}"
+ openshift_use_calico: "{{ lookup('oo_option', 'use_calico') }}"
openshift_use_fluentd: "{{ lookup('oo_option', 'use_fluentd') }}"
openshift_use_dnsmasq: false
diff --git a/playbooks/openstack/openshift-cluster/config.yml b/playbooks/openstack/openshift-cluster/config.yml
index 1366c83ca..f9ddb9469 100644
--- a/playbooks/openstack/openshift-cluster/config.yml
+++ b/playbooks/openstack/openshift-cluster/config.yml
@@ -29,4 +29,5 @@
openshift_use_openshift_sdn: "{{ lookup('oo_option', 'use_openshift_sdn') }}"
os_sdn_network_plugin_name: "{{ lookup('oo_option', 'sdn_network_plugin_name') }}"
openshift_use_flannel: "{{ lookup('oo_option', 'use_flannel') }}"
+ openshift_use_calico: "{{ lookup('oo_option', 'use_calico') }}"
openshift_use_fluentd: "{{ lookup('oo_option', 'use_fluentd') }}"
diff --git a/roles/calico/README.md b/roles/calico/README.md
new file mode 100644
index 000000000..99e870521
--- /dev/null
+++ b/roles/calico/README.md
@@ -0,0 +1,28 @@
+# Calico
+
+Configure Calico components for the Master host.
+
+## Requirements
+
+* Ansible 2.2
+
+## Warning: This Calico Integration is in Alpha
+
+Calico shares the etcd instance used by OpenShift, and distributes client etcd certificates to each node.
+For this reason, **we do not (yet) recommend running Calico on any production-like
+cluster, or using it for any purpose besides early access testing.**
+
+## Installation
+
+To install, set the following inventory configuration parameters:
+
+* `openshift_use_calico=True`
+* `openshift_use_openshift_sdn=False`
+* `os_sdn_network_plugin_name='cni'`
+
+
+### Contact Information
+
+Author: Dan Osborne <dan@projectcalico.org>
+
+For support, join the `#openshift` channel on the [calico users slack](calicousers.slack.com).
diff --git a/roles/calico/defaults/main.yaml b/roles/calico/defaults/main.yaml
new file mode 100644
index 000000000..a81fc3af7
--- /dev/null
+++ b/roles/calico/defaults/main.yaml
@@ -0,0 +1,10 @@
+---
+kubeconfig: "{{openshift.common.config_base}}/node/{{ 'system:node:' + openshift.common.hostname }}.kubeconfig"
+etcd_endpoints: "{{ hostvars[groups.oo_first_master.0].openshift.master.etcd_urls | join(',') }}"
+
+cni_conf_dir: "/etc/cni/net.d/"
+cni_bin_dir: "/opt/cni/bin/"
+
+calico_etcd_ca_cert_file: "/etc/origin/calico/calico.etcd-ca.crt"
+calico_etcd_cert_file: "/etc/origin/calico/calico.etcd-client.crt"
+calico_etcd_key_file: "/etc/origin/calico/calico.etcd-client.key"
diff --git a/roles/calico/handlers/main.yml b/roles/calico/handlers/main.yml
new file mode 100644
index 000000000..65d75cf00
--- /dev/null
+++ b/roles/calico/handlers/main.yml
@@ -0,0 +1,8 @@
+---
+- name: restart calico
+ become: yes
+ systemd: name=calico state=restarted
+
+- name: restart docker
+ become: yes
+ systemd: name=docker state=restarted
diff --git a/roles/calico/meta/main.yml b/roles/calico/meta/main.yml
new file mode 100644
index 000000000..102b82bde
--- /dev/null
+++ b/roles/calico/meta/main.yml
@@ -0,0 +1,16 @@
+---
+galaxy_info:
+ author: Dan Osborne
+ description: Calico networking
+ company: Tigera, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 2.2
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+ - system
+dependencies:
+- role: openshift_facts
diff --git a/roles/calico/tasks/main.yml b/roles/calico/tasks/main.yml
new file mode 100644
index 000000000..287fed321
--- /dev/null
+++ b/roles/calico/tasks/main.yml
@@ -0,0 +1,74 @@
+---
+- include: ../../../roles/etcd_client_certificates/tasks/main.yml
+ vars:
+ etcd_cert_prefix: calico.etcd-
+ etcd_cert_config_dir: "{{ openshift.common.config_base }}/calico"
+ embedded_etcd: "{{ hostvars[groups.oo_first_master.0].openshift.master.embedded_etcd }}"
+ etcd_ca_host: "{{ groups.oo_etcd_to_config.0 }}"
+ etcd_cert_subdir: "openshift-calico-{{ openshift.common.hostname }}"
+
+- name: Assure the calico certs have been generated
+ stat:
+ path: "{{ item }}"
+ with_items:
+ - "{{ calico_etcd_ca_cert_file }}"
+ - "{{ calico_etcd_cert_file}}"
+ - "{{ calico_etcd_key_file }}"
+
+- name: Configure Calico service unit file
+ template:
+ dest: "/lib/systemd/system/calico.service"
+ src: calico.service.j2
+
+- name: Enable calico
+ become: yes
+ systemd:
+ name: calico
+ daemon_reload: yes
+ state: started
+ enabled: yes
+ register: start_result
+
+- name: Assure CNI conf dir exists
+ become: yes
+ file: path="{{ cni_conf_dir }}" state=directory
+
+- name: Generate Calico CNI config
+ become: yes
+ template:
+ src: "calico.conf.j2"
+ dest: "{{ cni_conf_dir }}/10-calico.conf"
+
+- name: Assures Kuberentes CNI bin dir exists
+ become: yes
+ file: path="{{ cni_bin_dir }}" state=directory
+
+- name: Download Calico CNI Plugin
+ become: yes
+ get_url:
+ url: https://github.com/projectcalico/cni-plugin/releases/download/v1.5.5/calico
+ dest: "{{ cni_bin_dir }}"
+ mode: a+x
+
+- name: Download Calico IPAM Plugin
+ become: yes
+ get_url:
+ url: https://github.com/projectcalico/cni-plugin/releases/download/v1.5.5/calico-ipam
+ dest: "{{ cni_bin_dir }}"
+ mode: a+x
+
+- name: Download and unzip standard CNI plugins
+ become: yes
+ unarchive:
+ remote_src: True
+ src: https://github.com/containernetworking/cni/releases/download/v0.4.0/cni-amd64-v0.4.0.tgz
+ dest: "{{ cni_bin_dir }}"
+
+- name: Assure Calico conf dir exists
+ become: yes
+ file: path=/etc/calico/ state=directory
+
+- name: Set calicoctl.cfg
+ template:
+ src: calico.cfg.j2
+ dest: "/etc/calico/calicoctl.cfg"
diff --git a/roles/calico/templates/calico.cfg.j2 b/roles/calico/templates/calico.cfg.j2
new file mode 100644
index 000000000..722385ed8
--- /dev/null
+++ b/roles/calico/templates/calico.cfg.j2
@@ -0,0 +1,9 @@
+apiVersion: v1
+kind: calicoApiConfig
+metadata:
+spec:
+ datastoreType: "etcdv2"
+ etcdEndpoints: "{{ etcd_endpoints }}"
+ etcdKeyFile: "{{ calico_etcd_key_file }}"
+ etcdCertFile: "{{ calico_etcd_cert_file }}"
+ etcdCaCertFile: "{{ calico_etcd_ca_cert_file }}"
diff --git a/roles/calico/templates/calico.conf.j2 b/roles/calico/templates/calico.conf.j2
new file mode 100644
index 000000000..3c8c6b046
--- /dev/null
+++ b/roles/calico/templates/calico.conf.j2
@@ -0,0 +1,18 @@
+{
+ "name": "calico",
+ "type": "calico",
+ "ipam": {
+ "type": "calico-ipam"
+ },
+ "etcd_endpoints": "{{ etcd_endpoints }}",
+ "etcd_key_file": "{{ calico_etcd_key_file }}",
+ "etcd_cert_file": "{{ calico_etcd_cert_file }}",
+ "etcd_ca_cert_file": "{{ calico_etcd_ca_cert_file }}",
+ "kubernetes": {
+ "kubeconfig": "{{ kubeconfig }}"
+ },
+ "hostname": "{{ openshift.common.hostname }}",
+ "policy": {
+ "type": "k8s"
+ }
+}
diff --git a/roles/calico/templates/calico.service.j2 b/roles/calico/templates/calico.service.j2
new file mode 100644
index 000000000..b882a5597
--- /dev/null
+++ b/roles/calico/templates/calico.service.j2
@@ -0,0 +1,29 @@
+[Unit]
+Description=calico
+After=docker.service
+Requires=docker.service
+
+[Service]
+Restart=always
+ExecStartPre=-/usr/bin/docker rm -f calico-node
+ExecStart=/usr/bin/docker run --net=host --privileged \
+ --name=calico-node \
+ -e WAIT_FOR_DATASTORE=true \
+ -e FELIX_DEFAULTENDPOINTTOHOSTACTION=ACCEPT \
+ -e CALICO_IPV4POOL_IPIP=always \
+ -e FELIX_IPV6SUPPORT=false \
+ -e ETCD_ENDPOINTS={{ etcd_endpoints }} \
+ -v /etc/origin/calico:/etc/origin/calico \
+ -e ETCD_CA_CERT_FILE={{ calico_etcd_ca_cert_file }} \
+ -e ETCD_CERT_FILE={{ calico_etcd_cert_file }} \
+ -e ETCD_KEY_FILE={{ calico_etcd_key_file }} \
+ -e NODENAME={{ openshift.common.hostname }} \
+ -v /var/log/calico:/var/log/calico \
+ -v /lib/modules:/lib/modules \
+ -v /var/run/calico:/var/run/calico \
+ calico/node:v1.1.0
+
+ExecStop=-/usr/bin/docker stop calico-node
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/calico_master/README.md b/roles/calico_master/README.md
new file mode 100644
index 000000000..2d34a967c
--- /dev/null
+++ b/roles/calico_master/README.md
@@ -0,0 +1,28 @@
+# Calico (Master)
+
+Configure Calico components for the Master host.
+
+## Requirements
+
+* Ansible 2.2
+
+## Warning: This Calico Integration is in Alpha
+
+Calico shares the etcd instance used by OpenShift, and distributes client etcd certificates to each node.
+For this reason, **we do not (yet) recommend running Calico on any production-like
+cluster, or using it for any purpose besides early access testing.**
+
+## Installation
+
+To install, set the following inventory configuration parameters:
+
+* `openshift_use_calico=True`
+* `openshift_use_openshift_sdn=False`
+* `os_sdn_network_plugin_name='cni'`
+
+
+### Contact Information
+
+Author: Dan Osborne <dan@projectcalico.org>
+
+For support, join the `#openshift` channel on the [calico users slack](calicousers.slack.com).
diff --git a/roles/calico_master/defaults/main.yaml b/roles/calico_master/defaults/main.yaml
new file mode 100644
index 000000000..db0d17884
--- /dev/null
+++ b/roles/calico_master/defaults/main.yaml
@@ -0,0 +1,2 @@
+---
+kubeconfig: "{{ openshift.common.config_base }}/master/openshift-master.kubeconfig"
diff --git a/roles/calico_master/meta/main.yml b/roles/calico_master/meta/main.yml
new file mode 100644
index 000000000..4d70c79cf
--- /dev/null
+++ b/roles/calico_master/meta/main.yml
@@ -0,0 +1,17 @@
+---
+galaxy_info:
+ author: Dan Osborne
+ description: Calico networking
+ company: Tigera, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 2.2
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+ - system
+dependencies:
+- role: calico
+- role: openshift_facts
diff --git a/roles/calico_master/tasks/main.yml b/roles/calico_master/tasks/main.yml
new file mode 100644
index 000000000..3358abe23
--- /dev/null
+++ b/roles/calico_master/tasks/main.yml
@@ -0,0 +1,41 @@
+---
+- name: Assure the calico certs have been generated
+ stat:
+ path: "{{ item }}"
+ with_items:
+ - "{{ calico_etcd_ca_cert_file }}"
+ - "{{ calico_etcd_cert_file}}"
+ - "{{ calico_etcd_key_file }}"
+
+- name: Create temp directory for policy controller definition
+ command: mktemp -d /tmp/openshift-ansible-XXXXXXX
+ register: mktemp
+ changed_when: False
+
+- name: Write Calico Policy Controller definition
+ template:
+ dest: "{{ mktemp.stdout }}/calico-policy-controller.yml"
+ src: calico-policy-controller.yml.j2
+
+- name: Launch Calico Policy Controller
+ command: >
+ {{ openshift.common.client_binary }} create
+ -f {{ mktemp.stdout }}/calico-policy-controller.yml
+ --config={{ openshift.common.config_base }}/master/admin.kubeconfig
+ register: calico_create_output
+ failed_when: ('already exists' not in calico_create_output.stderr) and ('created' not in calico_create_output.stdout)
+ changed_when: ('created' in calico_create_output.stdout)
+
+- name: Delete temp directory
+ file:
+ name: "{{ mktemp.stdout }}"
+ state: absent
+ changed_when: False
+
+
+- name: oc adm policy add-scc-to-user privileged system:serviceaccount:kube-system:calico
+ oc_adm_policy_user:
+ user: system:serviceaccount:kube-system:calico
+ resource_kind: scc
+ resource_name: privileged
+ state: present
diff --git a/roles/calico_master/templates/calico-policy-controller.yml.j2 b/roles/calico_master/templates/calico-policy-controller.yml.j2
new file mode 100644
index 000000000..66c334ceb
--- /dev/null
+++ b/roles/calico_master/templates/calico-policy-controller.yml.j2
@@ -0,0 +1,105 @@
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: calico
+ namespace: kube-system
+---
+kind: ClusterRole
+apiVersion: v1
+metadata:
+ name: calico
+ namespace: kube-system
+rules:
+ - apiGroups: [""]
+ resources:
+ - pods
+ - namespaces
+ verbs:
+ - list
+ - get
+ - watch
+ - apiGroups: ["extensions"]
+ resources:
+ - networkpolicies
+ verbs:
+ - list
+ - get
+ - watch
+---
+apiVersion: v1
+kind: ClusterRoleBinding
+metadata:
+ name: calico
+roleRef:
+ name: calico
+subjects:
+- kind: SystemUser
+ name: kube-system:calico
+- kind: ServiceAccount
+ name: calico
+ namespace: kube-system
+userNames:
+ - system:serviceaccount:kube-system:calico
+---
+# This manifest deploys the Calico policy controller on Kubernetes.
+# See https://github.com/projectcalico/k8s-policy
+apiVersion: extensions/v1beta1
+kind: Deployment
+metadata:
+ name: calico-policy-controller
+ namespace: kube-system
+ labels:
+ k8s-app: calico-policy
+ annotations:
+ scheduler.alpha.kubernetes.io/critical-pod: ''
+ scheduler.alpha.kubernetes.io/tolerations: |
+ [{"key": "dedicated", "value": "master", "effect": "NoSchedule" },
+ {"key":"CriticalAddonsOnly", "operator":"Exists"}]
+spec:
+ # The policy controller can only have a single active instance.
+ replicas: 1
+ strategy:
+ type: Recreate
+ template:
+ metadata:
+ name: calico-policy-controller
+ namespace: kube-system
+ labels:
+ k8s-app: calico-policy
+ spec:
+ # The policy controller must run in the host network namespace so that
+ # it isn't governed by policy that would prevent it from working.
+ hostNetwork: true
+ serviceAccountName: calico
+ containers:
+ - name: calico-policy-controller
+ image: quay.io/calico/kube-policy-controller:v0.5.3
+ env:
+ # The location of the Calico etcd cluster.
+ - name: ETCD_ENDPOINTS
+ value: {{ etcd_endpoints }}
+ # Location of the CA certificate for etcd.
+ - name: ETCD_CA_CERT_FILE
+ value: {{ calico_etcd_ca_cert_file }}
+ # Location of the client key for etcd.
+ - name: ETCD_KEY_FILE
+ value: {{ calico_etcd_key_file }}
+ # Location of the client certificate for etcd.
+ - name: ETCD_CERT_FILE
+ value: {{ calico_etcd_cert_file }}
+ # Since we're running in the host namespace and might not have KubeDNS
+ # access, configure the container's /etc/hosts to resolve
+ # kubernetes.default to the correct service clusterIP.
+ - name: CONFIGURE_ETC_HOSTS
+ value: "true"
+ volumeMounts:
+ # Mount in the etcd TLS secrets.
+ - name: certs
+ mountPath: /etc/origin/calico
+
+ volumes:
+ # Mount in the etcd TLS secrets.
+ - name: certs
+ hostPath:
+ path: /etc/origin/calico
diff --git a/roles/openshift_common/tasks/main.yml b/roles/openshift_common/tasks/main.yml
index e55c288a8..d9ccf87bc 100644
--- a/roles/openshift_common/tasks/main.yml
+++ b/roles/openshift_common/tasks/main.yml
@@ -24,6 +24,14 @@
when: openshift_use_nuage | default(false) | bool and openshift_use_contiv | default(false) | bool
- fail:
+ msg: Calico can not be used with openshift sdn, set openshift_use_openshift_sdn=false if you want to use Calico
+ when: openshift_use_openshift_sdn | default(true) | bool and openshift_use_calico | default(false) | bool
+
+- fail:
+ msg: Calico cannot currently be used with Flannel in Openshift. Set either openshift_use_calico or openshift_use_flannel, but not both
+ when: openshift_use_calico | default(false) | bool and openshift_use_flannel | default(false) | bool
+
+- fail:
msg: openshift_hostname must be 64 characters or less
when: openshift_hostname is defined and openshift_hostname | length > 64
@@ -35,6 +43,7 @@
use_openshift_sdn: "{{ openshift_use_openshift_sdn | default(None) }}"
sdn_network_plugin_name: "{{ os_sdn_network_plugin_name | default(None) }}"
use_flannel: "{{ openshift_use_flannel | default(None) }}"
+ use_calico: "{{openshift_use_calico | default(None) }}"
use_nuage: "{{ openshift_use_nuage | default(None) }}"
use_contiv: "{{ openshift_use_contiv | default(None) }}"
use_manageiq: "{{ openshift_use_manageiq | default(None) }}"
diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py
index eeab8a99c..e1f4c4e6d 100755
--- a/roles/openshift_facts/library/openshift_facts.py
+++ b/roles/openshift_facts/library/openshift_facts.py
@@ -467,6 +467,24 @@ def set_flannel_facts_if_unset(facts):
return facts
+def set_calico_facts_if_unset(facts):
+ """ Set calico facts if not already present in facts dict
+ dict: the facts dict updated with the calico facts if
+ missing
+ Args:
+ facts (dict): existing facts
+ Returns:
+ dict: the facts dict updated with the calico
+ facts if they were not already present
+
+ """
+ if 'common' in facts:
+ if 'use_calico' not in facts['common']:
+ use_calico = False
+ facts['common']['use_calico'] = use_calico
+ return facts
+
+
def set_nuage_facts_if_unset(facts):
""" Set nuage facts if not already present in facts dict
dict: the facts dict updated with the nuage facts if
@@ -1953,6 +1971,7 @@ class OpenShiftFacts(object):
facts = set_url_facts_if_unset(facts)
facts = set_project_cfg_facts_if_unset(facts)
facts = set_flannel_facts_if_unset(facts)
+ facts = set_calico_facts_if_unset(facts)
facts = set_nuage_facts_if_unset(facts)
facts = set_contiv_facts_if_unset(facts)
facts = set_node_schedulability(facts)