CORD-3065 Install openstack-helm on a single node

Change-Id: Iaf213a564ee2cb8704c2f8d115e005170178997f
diff --git a/openstack-helm/cloudlab-disk-setup.sh b/openstack-helm/cloudlab-disk-setup.sh
new file mode 100755
index 0000000..0a3da8a
--- /dev/null
+++ b/openstack-helm/cloudlab-disk-setup.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+#
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+###############################################
+# Disk setup and symlinks for a CloudLab node #
+###############################################
+
+# Don't do anything if not a CloudLab node
+[ ! -d /usr/local/etc/emulab ] && return
+
+# Mount extra space, if haven't already
+if [ ! -d /mnt/extra ]
+then
+    sudo mkdir -p /mnt/extra
+
+    # for NVME SSD on Utah Cloudlab, not supported by mkextrafs
+    if df | grep -q nvme0n1p1 && [ -e /usr/testbed/bin/mkextrafs ]
+    then
+        # set partition type of 4th partition to Linux, ignore errors
+        echo -e "t\\n4\\n82\\np\\nw\\nq" | sudo fdisk /dev/nvme0n1 || true
+
+        sudo mkfs.ext4 /dev/nvme0n1p4
+        echo "/dev/nvme0n1p4 /mnt/extra/ ext4 defaults 0 0" | sudo tee -a /etc/fstab
+        sudo mount /mnt/extra
+        mount | grep nvme0n1p4 || (echo "ERROR: NVME mkfs/mount failed, exiting!" && exit 1)
+
+    elif [ -e /usr/testbed/bin/mkextrafs ]  # if on Clemson/Wisconsin Cloudlab
+    then
+        # Sometimes this command fails on the first try
+        sudo /usr/testbed/bin/mkextrafs -s 1 -r /dev/sdb -qf "/mnt/extra/" || sudo /usr/testbed/bin/mkextrafs -s 1 -r /dev/sdb -qf "/mnt/extra/"
+
+        # Check that the mount succeeded (sometimes mkextrafs succeeds but device not mounted)
+        mount | grep sdb || (echo "ERROR: mkextrafs failed, exiting!" && exit 1)
+    fi
+fi
+
+for DIR in docker kubelet openstack-helm nova
+do
+    sudo mkdir -p /mnt/extra/$DIR
+    sudo chmod -R a+rwx /mnt/extra/$DIR
+    [ ! -e /var/lib/$DIR ] && sudo ln -s /mnt/extra/$DIR /var/lib/$DIR
+done
diff --git a/openstack-helm/files/resolv.conf.preppedkube b/openstack-helm/files/resolv.conf.preppedkube
deleted file mode 100644
index caf0c72..0000000
--- a/openstack-helm/files/resolv.conf.preppedkube
+++ /dev/null
@@ -1,2 +0,0 @@
-nameserver 10.233.0.3
-search cluster.local
\ No newline at end of file
diff --git a/openstack-helm/install-on-preppedkube.yml b/openstack-helm/install-on-preppedkube.yml
deleted file mode 100644
index 042b0e0..0000000
--- a/openstack-helm/install-on-preppedkube.yml
+++ /dev/null
@@ -1,123 +0,0 @@
----
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# This playbook can be used to install openstack-helm and XOS on the
-# "preppedkube" scenario (three VMs running K8S on a single server).
-# The intent is to duplicate the installation instructions in this doc:
-# https://docs.google.com/document/d/1_8owQLD2OtWfKMrPmqo015daeHCGlXPw4mSyLiSKHhg/edit#
-
-- name: Prep the head node
-  vars:
-    HELM_VERSION: 2.8.1
-  hosts: head
-  become: yes
-  tasks:
-    - name: Download helm binary
-      unarchive:
-        src: https://storage.googleapis.com/kubernetes-helm/helm-v{{ HELM_VERSION }}-linux-amd64.tar.gz
-        dest: /tmp
-        remote_src: yes
-
-    - name: Install helm binary
-      copy:
-        src: /tmp/linux-amd64/helm
-        dest: /usr/local/bin/helm
-        remote_src: yes
-        mode: 0755
-
-    - name: Disable apt cache
-      file:
-        path: /etc/apt/apt.conf.d/03apt-cacher-ng
-        state: absent
-
-    - name: Install apt packages
-      apt:
-        name: "{{ item }}"
-      with_items:
-      - nmap
-      - jq
-      - python-pip
-
-    - name: Stop Apache
-      service:
-        name: apache2
-        state: stopped
-      ignore_errors: yes
-
-    - name: Add node labels
-      command: kubectl label nodes --all --overwrite ceph-mds=enabled ceph-mgr=enabled ceph-mon=enabled ceph-osd=enabled ceph-rgw=enabled linuxbridge=enabled openstack-compute-node=enabled openstack-control-plane=enabled openvswitch=enabled openstack-helm-node-class=general
-      tags:
-      - skip_ansible_lint
-
-    - name: Add head node labels
-      command: kubectl label nodes {{ ansible_hostname }} --overwrite openstack-helm-node-class=primary
-      tags:
-      - skip_ansible_lint
-
-- name: Prep all nodes
-  hosts: head compute
-  become: yes
-  tasks:
-    - name: Point node DNS resolver to kube-dns
-      copy:
-        src: files/resolv.conf.preppedkube
-        dest: /etc/resolv.conf
-
-    - name: Install ceph-common
-      apt:
-        name: ceph-common
-
-- name: Install openstack-helm
-  hosts: head
-  roles:
-    - install-openstack-helm
-
-- name: Get public key used on head node (VTN)
-  hosts: head
-  tasks:
-  - name: Read public key
-    slurp:
-      src: "{{ ansible_env.HOME }}/.ssh/authorized_keys"
-    register: public_key
-
-- name: Add public key to compute nodes (VTN)
-  hosts: compute
-  tasks:
-  - name: Add public key to compute nodes
-    authorized_key:
-      user: "{{ ansible_env.USER }}"
-      state: present
-      key: "{{ hostvars[groups['head'][0]].public_key['content'] | b64decode }}"
-
-- name: Run kubectl commands (FIX ME!!!)
-  hosts: localhost
-  connection: local
-  tasks:
-  - name: Prep openvswitch on the nodes for VTN
-    shell: |
-      OVSDB_PODS=$( kubectl get pod --namespace openstack|grep openvswitch-db|awk '{print $1}' )
-      for pod in $OVSDB_PODS
-      do
-          kubectl --namespace openstack exec $pod -- ovs-appctl -t ovsdb-server ovsdb-server/add-remote ptcp:6641
-      done
-    tags:
-    - skip_ansible_lint
-
-- name: Deploy XOS
-  hosts: localhost
-  connection: local
-  roles:
-    - deploy-xos
diff --git a/openstack-helm/inventory.ini b/openstack-helm/inventory.ini
deleted file mode 100644
index 8b8ef98..0000000
--- a/openstack-helm/inventory.ini
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-[head]
-head1
-
-[compute]
-compute1
-compute2
\ No newline at end of file
diff --git a/openstack-helm/openstack-helm-dev-setup.sh b/openstack-helm/openstack-helm-dev-setup.sh
new file mode 100644
index 0000000..83f355a
--- /dev/null
+++ b/openstack-helm/openstack-helm-dev-setup.sh
@@ -0,0 +1,113 @@
+#!/bin/bash
+#
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+###########################################################
+# Install openstack-helm dev setup on Ubuntu 16.04 server #
+#     Including customizations to Neutron for CORD        #
+###########################################################
+
+set -xe
+
+# CORD versioning
+OPENSTACK_HELM_BRANCH="${OPENSTACK_HELM_BRANCH:-master}"
+
+# openstack-helm steps to execute
+STEPS="000-install-packages 010-deploy-k8s 020-setup-client 030-ingress 040-ceph 045-ceph-ns-activate 050-mariadb 060-rabbitmq 070-memcached 080-keystone 090-heat 110-ceph-radosgateway 120-glance 140-openvswitch 150-libvirt 160-compute-kit"
+
+
+# Set up extra disk space if running on CloudLab
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+if [ -d /usr/local/etc/emulab ]
+then
+  sudo delgroup docker || true
+  "$DIR"/cloudlab-disk-setup.sh
+fi
+
+cd ~
+[ ! -e openstack-helm-infra ] && git clone https://git.openstack.org/openstack/openstack-helm-infra.git -b "${OPENSTACK_HELM_BRANCH}"
+[ ! -e openstack-helm ] && git clone https://git.openstack.org/openstack/openstack-helm.git -b "${OPENSTACK_HELM_BRANCH}"
+
+# Customizations for CORD
+cat <<EOF > /tmp/glance-cord.yaml
+---
+network:
+  api:
+    ingress:
+      annotations:
+        nginx.ingress.kubernetes.io/proxy-body-size: "0"
+EOF
+export OSH_EXTRA_HELM_ARGS_GLANCE="-f /tmp/glance-cord.yaml"
+
+cat <<EOF > /tmp/nova-cord.yaml
+---
+labels:
+  api_metadata:
+    node_selector_key: openstack-helm-node-class
+    node_selector_value: primary
+network:
+  backend: []
+pod:
+  replicas:
+    api_metadata: 1
+    placement: 1
+    osapi: 1
+    conductor: 1
+    consoleauth: 1
+    scheduler: 1
+    novncproxy: 1
+EOF
+export OSH_EXTRA_HELM_ARGS_NOVA="-f /tmp/nova-cord.yaml"
+
+cat <<EOF > /tmp/neutron-cord.yaml
+---
+images:
+  tags:
+    neutron_server: xosproject/neutron-onos:newton
+manifests:
+  daemonset_dhcp_agent: false
+  daemonset_l3_agent: false
+  daemonset_lb_agent: false
+  daemonset_metadata_agent: false
+  daemonset_ovs_agent: false
+  daemonset_sriov_agent: false
+network:
+  backend: []
+  interface:
+    tunnel: "eth0"
+pod:
+  replicas:
+    server: 1
+conf:
+  plugins:
+    ml2_conf:
+      ml2:
+        type_drivers: vxlan
+        tenant_network_types: vxlan
+        mechanism_drivers: onos_ml2
+      ml2_type_vxlan:
+        vni_ranges: 1001:2000
+      onos:
+        url_path: http://onos-cord-ui.default.svc.cluster.local:8181/onos/cordvtn
+        username: onos
+        password: rocks
+EOF
+export OSH_EXTRA_HELM_ARGS_NEUTRON="-f /tmp/neutron-cord.yaml"
+
+cd ~/openstack-helm
+for STEP in $STEPS
+do
+    ./tools/deployment/developer/ceph/"$STEP".sh
+done
diff --git a/openstack-helm/roles/deploy-xos/defaults/main.yml b/openstack-helm/roles/deploy-xos/defaults/main.yml
deleted file mode 100644
index ba7f336..0000000
--- a/openstack-helm/roles/deploy-xos/defaults/main.yml
+++ /dev/null
@@ -1,17 +0,0 @@
----
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-ONOS_VERSION: 1.12.0
\ No newline at end of file
diff --git a/openstack-helm/roles/deploy-xos/tasks/main.yml b/openstack-helm/roles/deploy-xos/tasks/main.yml
deleted file mode 100644
index 376e8ea..0000000
--- a/openstack-helm/roles/deploy-xos/tasks/main.yml
+++ /dev/null
@@ -1,50 +0,0 @@
----
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-- name: Chart dependencies
-  command: helm dep update ./xos-profiles/base-openstack
-  args:
-    chdir: "{{ ansible_env.HOME }}/cord/build/helm-charts"
-  tags:
-  - skip_ansible_lint
-
-- name: Install charts
-  command: helm upgrade --install {{ item.name }} {{ item.path }}
-  args:
-    chdir: "{{ ansible_env.HOME }}/cord/build/helm-charts"
-  with_items:
-  - { name: xos-core, path: ./xos-core }
-  - { name: base-openstack, path: ./xos-profiles/base-openstack }
-  - { name: onos-cord, path: "./onos -f configs/onos-cord.yaml" }
-  tags:
-  - skip_ansible_lint
-
-- name: Wait for ONOS to come up
-  shell: kubectl get pod | grep onos-cord | grep Running
-  register: result
-  until: result is success
-  retries: 30
-  delay: 10
-  tags:
-  - skip_ansible_lint
-
-- name: Add head node private key to ONOS (HACK - should be a secret or something)
-  shell: |
-    HEAD_PRIVKEY={{ ansible_env.HOME}}/cord/build/scenarios/preppedkube/.vagrant/machines/head1/libvirt/private_key
-    ONOS_CORD_POD=$( kubectl get pod | grep onos-cord | awk '{print $1}' )
-    kubectl cp $HEAD_PRIVKEY $ONOS_CORD_POD:/root/node_key
-  tags:
-  - skip_ansible_lint
diff --git a/openstack-helm/roles/install-openstack-helm/files/neutron.yaml b/openstack-helm/roles/install-openstack-helm/files/neutron.yaml
deleted file mode 100644
index e552751..0000000
--- a/openstack-helm/roles/install-openstack-helm/files/neutron.yaml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-images:
-  tags:
-    neutron_server: xosproject/neutron-onos:newton
-manifests:
-  daemonset_dhcp_agent: false
-  daemonset_l3_agent: false
-  daemonset_lb_agent: false
-  daemonset_metadata_agent: false
-  daemonset_ovs_agent: false
-  daemonset_sriov_agent: false
-network:
-  backend: []
-  interface:
-    tunnel: "eth0"
-pod:
-  replicas:
-    server: 2
-conf:
-  plugins:
-    ml2_conf:
-      ml2:
-        type_drivers: vxlan
-        tenant_network_types: vxlan
-        mechanism_drivers: onos_ml2
-      ml2_type_vxlan:
-        vni_ranges: 1001:2000
-      onos:
-        url_path: http://onos-cord-ui.default.svc.cluster.local:8181/onos/cordvtn
-        username: onos
-        password: rocks
diff --git a/openstack-helm/roles/install-openstack-helm/files/nova.yaml b/openstack-helm/roles/install-openstack-helm/files/nova.yaml
deleted file mode 100644
index 52532b4..0000000
--- a/openstack-helm/roles/install-openstack-helm/files/nova.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
----
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-labels:
-  api_metadata:
-    node_selector_key: openstack-helm-node-class
-    node_selector_value: primary
-network:
-  backend: []
-pod:
-  replicas:
-    api_metadata: 1
-    placement: 2
-    osapi: 2
-    conductor: 2
-    consoleauth: 2
-    scheduler: 1
-    novncproxy: 1
\ No newline at end of file
diff --git a/openstack-helm/roles/install-openstack-helm/tasks/main.yml b/openstack-helm/roles/install-openstack-helm/tasks/main.yml
deleted file mode 100644
index 452a54a..0000000
--- a/openstack-helm/roles/install-openstack-helm/tasks/main.yml
+++ /dev/null
@@ -1,160 +0,0 @@
----
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-- name: Checkout openstack-helm
-  git:
-    repo: https://git.openstack.org/openstack/openstack-helm.git
-    dest: "{{ ansible_env.HOME }}/openstack-helm"
-  tags:
-  - skip_ansible_lint
-
-- name: Initialize Helm
-  command: helm init --client-only
-  tags:
-  - skip_ansible_lint
-
-- name: Run 'helm serve' in background
-  shell: nohup helm serve </dev/null >/dev/null 2>&1 &
-  tags:
-  - skip_ansible_lint
-
-- name: Wait 5 seconds for helm chart server to initialize
-  pause:
-    seconds: 5
-
-- name: Add localhost repo to Helm
-  command: helm repo add localhost http://localhost:8879/charts
-  tags:
-  - skip_ansible_lint
-
-- name: Install OpenStack clients and build charts
-  command: tools/deployment/multinode/010-setup-client.sh
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-    creates: "{{ ansible_env.HOME }}/openstack-helm/nova-0.1.0.tgz"
-  tags:
-  - skip_ansible_lint
-
-- name: Install ingress
-  command: tools/deployment/multinode/020-ingress.sh
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-    creates: /tmp/ingress-openstack.yaml
-  tags:
-  - skip_ansible_lint
-
-- name: Install Ceph
-  command: tools/deployment/multinode/030-ceph.sh
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-    creates: /tmp/ceph.yaml
-  tags:
-  - skip_ansible_lint
-
-- name: Activate Ceph
-  command: tools/deployment/multinode/040-ceph-ns-activate.sh
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-    creates: /tmp/ceph-openstack-config.yaml
-  tags:
-  - skip_ansible_lint
-
-- name: Install single copy of mariadb, to avoid deadlock
-  command: tools/deployment/developer/common/050-mariadb.sh
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-  tags:
-  - skip_ansible_lint
-
-- name: Install RabbitMQ
-  command: tools/deployment/multinode/060-rabbitmq.sh
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-  tags:
-  - skip_ansible_lint
-
-- name: Install memcached
-  command: tools/deployment/multinode/070-memcached.sh
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-  tags:
-  - skip_ansible_lint
-
-# Thus usually fails but things still look OK
-- name: Install Keystone
-  command: tools/deployment/multinode/080-keystone.sh
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-  ignore_errors: yes
-  tags:
-  - skip_ansible_lint
-
-- name: Install Ceph radosgateway
-  command: tools/deployment/multinode/090-ceph-radosgateway.sh
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-    creates: /tmp/radosgw-openstack.yaml
-  tags:
-  - skip_ansible_lint
-
-- name: Install Glance
-  command: tools/deployment/multinode/100-glance.sh
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-    creates: /tmp/glance.yaml
-  tags:
-  - skip_ansible_lint
-
-- name: Install OvS
-  command: tools/deployment/multinode/120-openvswitch.sh
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-  tags:
-  - skip_ansible_lint
-
-- name: Install Libvirt
-  command: tools/deployment/multinode/130-libvirt.sh
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-  tags:
-  - skip_ansible_lint
-
-#
-# Need to customize Neutron install for CORD
-#
-
-- name: Create values files for Nova and Neutron
-  copy:
-    src: files/{{ item }}
-    dest: /tmp/{{ item }}
-  with_items:
-    - nova.yaml
-    - neutron.yaml
-
-- name: Install Nova
-  command: helm upgrade --install nova ./nova --namespace=openstack --values=/tmp/nova.yaml
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-  tags:
-  - skip_ansible_lint
-
-- name: Install Neutron
-  command: helm upgrade --install neutron ./neutron --namespace=openstack --values=/tmp/neutron.yaml
-  args:
-    chdir: "{{ ansible_env.HOME }}/openstack-helm"
-  tags:
-  - skip_ansible_lint
-