Merge pull request #1 from salt-formulas/known-fixups
Cleanup + extend tests/pillars
diff --git a/.gitignore b/.gitignore
index 1bfce6e..aa8e42a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
+.kitchen
tests/build/
*.swp
*.pyc
-.ropeproject
\ No newline at end of file
+.ropeproject
diff --git a/.gitreview b/.gitreview
deleted file mode 100644
index 7b183fe..0000000
--- a/.gitreview
+++ /dev/null
@@ -1,4 +0,0 @@
-[gerrit]
-host=review.openstack.org
-port=29418
-project=openstack/salt-formula-neutron.git
diff --git a/Makefile b/Makefile
index fc83783..1043fbe 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,38 @@
DESTDIR=/
SALTENVDIR=/usr/share/salt-formulas/env
RECLASSDIR=/usr/share/salt-formulas/reclass
-FORMULANAME=$(shell grep name: metadata.yml|head -1|cut -d : -f 2|grep -Eo '[a-z0-9\-]*')
+FORMULANAME=$(shell grep name: metadata.yml|head -1|cut -d : -f 2|grep -Eo '[a-z0-9\-\_]*')
+VERSION=$(shell grep version: metadata.yml|head -1|cut -d : -f 2|grep -Eo '[a-z0-9\.\-\_]*')
+VERSION_MAJOR := $(shell echo $(VERSION)|cut -d . -f 1-2)
+VERSION_MINOR := $(shell echo $(VERSION)|cut -d . -f 3)
+
+NEW_MAJOR_VERSION ?= $(shell date +%Y.%m|sed 's,\.0,\.,g')
+NEW_MINOR_VERSION ?= $(shell /bin/bash -c 'echo $$[ $(VERSION_MINOR) + 1 ]')
+
+MAKE_PID := $(shell echo $$PPID)
+JOB_FLAG := $(filter -j%, $(subst -j ,-j,$(shell ps T | grep "^\s*$(MAKE_PID).*$(MAKE)")))
+
+ifneq ($(subst -j,,$(JOB_FLAG)),)
+JOBS := $(subst -j,,$(JOB_FLAG))
+else
+JOBS := 1
+endif
+
+KITCHEN_LOCAL_YAML?=.kitchen.yml
+KITCHEN_OPTS?="--concurrency=$(JOBS)"
+KITCHEN_OPTS_CREATE?=""
+KITCHEN_OPTS_CONVERGE?=""
+KITCHEN_OPTS_VERIFY?=""
+KITCHEN_OPTS_TEST?=""
all:
@echo "make install - Install into DESTDIR"
@echo "make test - Run tests"
+ @echo "make kitchen - Run Kitchen CI tests (create, converge, verify)"
@echo "make clean - Cleanup after tests run"
+ @echo "make release-major - Generate new major release"
+ @echo "make release-minor - Generate new minor release"
+ @echo "make changelog - Show changes since last release"
install:
# Formula
@@ -14,6 +40,7 @@
cp -a $(FORMULANAME) $(DESTDIR)/$(SALTENVDIR)/
[ ! -d _modules ] || cp -a _modules $(DESTDIR)/$(SALTENVDIR)/
[ ! -d _states ] || cp -a _states $(DESTDIR)/$(SALTENVDIR)/ || true
+ [ ! -d _grains ] || cp -a _grains $(DESTDIR)/$(SALTENVDIR)/ || true
# Metadata
[ -d $(DESTDIR)/$(RECLASSDIR)/service/$(FORMULANAME) ] || mkdir -p $(DESTDIR)/$(RECLASSDIR)/service/$(FORMULANAME)
cp -a metadata/service/* $(DESTDIR)/$(RECLASSDIR)/service/$(FORMULANAME)
@@ -21,6 +48,71 @@
test:
[ ! -d tests ] || (cd tests; ./run_tests.sh)
+release-major: check-changes
+ @echo "Current version is $(VERSION), new version is $(NEW_MAJOR_VERSION)"
+ @[ $(VERSION_MAJOR) != $(NEW_MAJOR_VERSION) ] || (echo "Major version $(NEW_MAJOR_VERSION) already released, nothing to do. Do you want release-minor?" && exit 1)
+ echo "$(NEW_MAJOR_VERSION)" > VERSION
+ sed -i 's,version: .*,version: "$(NEW_MAJOR_VERSION)",g' metadata.yml
+ [ ! -f debian/changelog ] || dch -v $(NEW_MAJOR_VERSION) -m --force-distribution -D `dpkg-parsechangelog -S Distribution` "New version"
+ make genchangelog-$(NEW_MAJOR_VERSION)
+ (git add -u; git commit -m "Version $(NEW_MAJOR_VERSION)")
+ git tag -s -m $(NEW_MAJOR_VERSION) $(NEW_MAJOR_VERSION)
+
+release-minor: check-changes
+ @echo "Current version is $(VERSION), new version is $(VERSION_MAJOR).$(NEW_MINOR_VERSION)"
+ echo "$(VERSION_MAJOR).$(NEW_MINOR_VERSION)" > VERSION
+ sed -i 's,version: .*,version: "$(VERSION_MAJOR).$(NEW_MINOR_VERSION)",g' metadata.yml
+ [ ! -f debian/changelog ] || dch -v $(VERSION_MAJOR).$(NEW_MINOR_VERSION) -m --force-distribution -D `dpkg-parsechangelog -S Distribution` "New version"
+ make genchangelog-$(VERSION_MAJOR).$(NEW_MINOR_VERSION)
+ (git add -u; git commit -m "Version $(VERSION_MAJOR).$(NEW_MINOR_VERSION)")
+ git tag -s -m $(NEW_MAJOR_VERSION) $(VERSION_MAJOR).$(NEW_MINOR_VERSION)
+
+check-changes:
+ @git log --pretty=oneline --decorate $(VERSION)..HEAD | grep -Eqc '.*' || (echo "No new changes since version $(VERSION)"; exit 1)
+
+changelog:
+ git log --pretty=short --invert-grep --grep="Merge pull request" --decorate $(VERSION)..HEAD
+
+genchangelog: genchangelog-$(VERSION_MAJOR).$(NEW_MINOR_VERSION)
+
+genchangelog-%:
+ $(eval NEW_VERSION := $(patsubst genchangelog-%,%,$@))
+ (echo "=========\nChangelog\n=========\n"; \
+ (echo $(NEW_VERSION);git tag) | sort -r | grep -E '^[0-9\.]+' | while read i; do \
+ cur=$$i; \
+ test $$i = $(NEW_VERSION) && i=HEAD; \
+ prev=`(echo $(NEW_VERSION);git tag)|sort|grep -E '^[0-9\.]+'|grep -B1 "$$cur\$$"|head -1`; \
+ echo "Version $$cur\n=============================\n"; \
+ git log --pretty=short --invert-grep --grep="Merge pull request" --decorate $$prev..$$i; \
+ echo; \
+ done) > CHANGELOG.rst
+
+kitchen-check:
+ @[ -e $(KITCHEN_LOCAL_YAML) ] || (echo "Kitchen tests not available, there's no $(KITCHEN_LOCAL_YAML)." && exit 1)
+
+kitchen: kitchen-check kitchen-create kitchen-converge kitchen-verify kitchen-list
+
+kitchen-create: kitchen-check
+ kitchen create ${KITCHEN_OPTS} ${KITCHEN_OPTS_CREATE}
+ [ "$(shell echo $(KITCHEN_LOCAL_YAML)|grep -Eo docker)" = "docker" ] || sleep 120
+
+kitchen-converge: kitchen-check
+ kitchen converge ${KITCHEN_OPTS} ${KITCHEN_OPTS_CONVERGE} &&\
+ kitchen converge ${KITCHEN_OPTS} ${KITCHEN_OPTS_CONVERGE}
+
+kitchen-verify: kitchen-check
+ [ ! -d tests/integration ] || kitchen verify -t tests/integration ${KITCHEN_OPTS} ${KITCHEN_OPTS_VERIFY}
+ [ -d tests/integration ] || kitchen verify ${KITCHEN_OPTS} ${KITCHEN_OPTS_VERIFY}
+
+kitchen-test: kitchen-check
+ [ ! -d tests/integration ] || kitchen test -t tests/integration ${KITCHEN_OPTS} ${KITCHEN_OPTS_TEST}
+ [ -d tests/integration ] || kitchen test ${KITCHEN_OPTS} ${KITCHEN_OPTS_TEST}
+
+kitchen-list: kitchen-check
+ kitchen list
+
clean:
+ [ ! -x "$(shell which kitchen)" ] || kitchen destroy
+ [ ! -d .kitchen ] || rm -rf .kitchen
[ ! -d tests/build ] || rm -rf tests/build
[ ! -d build ] || rm -rf build
diff --git a/README.rst b/README.rst
index 084c423..b1a3047 100644
--- a/README.rst
+++ b/README.rst
@@ -21,6 +21,8 @@
server:
enabled: true
version: mitaka
+ allow_pagination: true
+ pagination_max_limit: 100
bind:
address: 172.20.0.1
port: 9696
@@ -52,6 +54,11 @@
audit:
enabled: false
+Note: The pagination is useful to retrieve a large bunch of resources,
+because a single request may fail (timeout). This is enabled with both
+parameters *allow_pagination* and *pagination_max_limit* as shown above.
+
+
Neutron VXLAN tenant networks with Network Nodes (with DVR for East-West
and Network node for North-South)
=========================================================================
@@ -589,6 +596,107 @@
....
+Client role
+-----------
+
+Neutron networks
+
+.. code-block:: yaml
+
+ neutron:
+ client:
+ enabled: true
+ server:
+ identity:
+ network:
+ inet1:
+ tenant: demo
+ shared: False
+ admin_state_up: True
+ router_external: True
+ provider_physical_network: inet
+ provider_network_type: flat
+ provider_segmentation_id: 2
+ subnet:
+ inet1-subnet1:
+ cidr: 192.168.90.0/24
+ enable_dhcp: False
+ inet2:
+ tenant: admin
+ shared: False
+ router_external: True
+ provider_network_type: "vlan"
+ subnet:
+ inet2-subnet1:
+ cidr: 192.168.92.0/24
+ enable_dhcp: False
+ inet2-subnet2:
+ cidr: 192.168.94.0/24
+ enable_dhcp: True
+ identity1:
+ network:
+ ...
+
+
+Neutron routers
+
+.. code-block:: yaml
+
+ neutron:
+ client:
+ enabled: true
+ server:
+ identity:
+ router:
+ inet1-router:
+ tenant: demo
+ admin_state_up: True
+ gateway_network: inet
+ interfaces:
+ - inet1-subnet1
+ - inet1-subnet2
+ identity1:
+ router:
+ ...
+
+ TODO: implement adding new interfaces to a router while updating it
+
+
+Neutron security groups
+
+.. code-block:: yaml
+
+ neutron:
+ client:
+ enabled: true
+ server:
+ identity:
+ security_group:
+ security_group1:
+ tenant: demo
+ description: security group 1
+ rules:
+ - direction: ingress
+ ethertype: IPv4
+ protocol: TCP
+ port_range_min: 1
+ port_range_max: 65535
+ remote_ip_prefix: 0.0.0.0/0
+ - direction: ingress
+ ethertype: IPv4
+ protocol: UDP
+ port_range_min: 1
+ port_range_max: 65535
+ remote_ip_prefix: 0.0.0.0/0
+ - direction: ingress
+ protocol: ICMP
+ remote_ip_prefix: 0.0.0.0/0
+ identity1:
+ security_group:
+ ...
+
+ TODO: implement updating existing security rules (now it adds new rule if trying to update existing one)
+
Usage
=====
@@ -623,3 +731,36 @@
Developers should also join the discussion on the IRC list, at:
https://wiki.openstack.org/wiki/Meetings/openstack-salt
+
+Documentation and Bugs
+======================
+
+To learn how to install and update salt-formulas, consult the documentation
+available online at:
+
+ http://salt-formulas.readthedocs.io/
+
+In the unfortunate event that bugs are discovered, they should be reported to
+the appropriate issue tracker. Use Github issue tracker for specific salt
+formula:
+
+ https://github.com/salt-formulas/salt-formula-neutron/issues
+
+For feature requests, bug reports or blueprints affecting entire ecosystem,
+use Launchpad salt-formulas project:
+
+ https://launchpad.net/salt-formulas
+
+You can also join salt-formulas-users team and subscribe to mailing list:
+
+ https://launchpad.net/~salt-formulas-users
+
+Developers wishing to work on the salt-formulas projects should always base
+their work on master branch and submit pull request against specific formula.
+
+ https://github.com/salt-formulas/salt-formula-neutron
+
+Any questions or feedback is always welcome so feel free to join our IRC
+channel:
+
+ #salt-formulas @ irc.freenode.net
diff --git a/metadata/service/compute/single.yml b/metadata/service/compute/single.yml
index d86284d..e1196b2 100644
--- a/metadata/service/compute/single.yml
+++ b/metadata/service/compute/single.yml
@@ -1,5 +1,7 @@
applications:
- neutron
+classes:
+- service.neutron.support
parameters:
neutron:
compute:
@@ -24,5 +26,3 @@
mechanism:
ovs:
driver: openvswitch
-
-
diff --git a/metadata/service/gateway/single.yml b/metadata/service/gateway/single.yml
index 1e8fa2b..4ff30d1 100644
--- a/metadata/service/gateway/single.yml
+++ b/metadata/service/gateway/single.yml
@@ -1,5 +1,7 @@
applications:
- neutron
+classes:
+- service.neutron.support
parameters:
neutron:
gateway:
diff --git a/neutron/_modules/neutronng.py b/neutron/_modules/neutronng.py
new file mode 100644
index 0000000..55a5acd
--- /dev/null
+++ b/neutron/_modules/neutronng.py
@@ -0,0 +1,420 @@
+# -*- coding: utf-8 -*-
+
+import logging
+from functools import wraps
+LOG = logging.getLogger(__name__)
+
+# Import third party libs
+HAS_NEUTRON = False
+try:
+ from neutronclient.v2_0 import client
+ HAS_NEUTRON = True
+except ImportError:
+ pass
+
+__opts__ = {}
+
+
+def __virtual__():
+ '''
+ Only load this module if neutron
+ is installed on this minion.
+ '''
+ if HAS_NEUTRON:
+ return 'neutronng'
+ return False
+
+
+def _autheticate(func_name):
+ '''
+ Authenticate requests with the salt keystone module and format return data
+ '''
+ @wraps(func_name)
+ def decorator_method(*args, **kwargs):
+ '''
+ Authenticate request and format return data
+ '''
+ connection_args = {'profile': kwargs.get('profile', None)}
+ nkwargs = {}
+ for kwarg in kwargs:
+ if 'connection_' in kwarg:
+ connection_args.update({kwarg: kwargs[kwarg]})
+ elif '__' not in kwarg:
+ nkwargs.update({kwarg: kwargs[kwarg]})
+ kstone = __salt__['keystone.auth'](**connection_args)
+ token = kstone.auth_token
+ endpoint = kstone.service_catalog.url_for(
+ service_type='network',
+ endpoint_type='publicURL')
+ neutron_interface = client.Client(
+ endpoint_url=endpoint, token=token)
+ return_data = func_name(neutron_interface, *args, **nkwargs)
+ if isinstance(return_data, list):
+ # format list as a dict for rendering
+ return {data.get('name', None) or data['id']: data
+ for data in return_data}
+ return return_data
+ return decorator_method
+
+
+@_autheticate
+def list_floatingips(neutron_interface, **kwargs):
+ '''
+ list all floatingips
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.list_floatingips
+ '''
+ return neutron_interface.list_floatingips(**kwargs)['floatingips']
+
+
+@_autheticate
+def list_security_groups(neutron_interface, **kwargs):
+ '''
+ list all security_groups
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.list_security_groups
+ '''
+ return neutron_interface.list_security_groups(**kwargs)['security_groups']
+
+
+@_autheticate
+def list_subnets(neutron_interface, **kwargs):
+ '''
+ list all subnets
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.list_subnets
+ '''
+ return neutron_interface.list_subnets(**kwargs)['subnets']
+
+
+@_autheticate
+def list_networks(neutron_interface, **kwargs):
+ '''
+ list all networks
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.list_networks
+ '''
+ return neutron_interface.list_networks(**kwargs)['networks']
+
+
+@_autheticate
+def list_ports(neutron_interface, **kwargs):
+ '''
+ list all ports
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.list_ports
+ '''
+ return neutron_interface.list_ports(**kwargs)['ports']
+
+
+@_autheticate
+def list_routers(neutron_interface, **kwargs):
+ '''
+ list all routers
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.list_routers
+ '''
+ return neutron_interface.list_routers(**kwargs)['routers']
+
+@_autheticate
+def update_floatingip(neutron_interface, fip, port_id=None):
+ '''
+ update floating IP. Should be used to associate and disassociate
+ floating IP with instance
+ CLI Example:
+ .. code-block:: bash
+ to associate with an instance's port
+ salt '*' neutron.update_floatingip openstack-floatingip-id port-id
+ to disassociate from an instance's port
+ salt '*' neutron.update_floatingip openstack-floatingip-id
+ '''
+ neutron_interface.update_floatingip(fip, {"floatingip":
+ {"port_id": port_id}})
+
+
+@_autheticate
+def update_subnet(neutron_interface, subnet_id, **subnet_params):
+ '''
+ update given subnet
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.update_subnet openstack-subnet-id name='new_name'
+ '''
+ neutron_interface.update_subnet(subnet_id, {'subnet': subnet_params})
+
+
+@_autheticate
+def update_network(neutron_interface, network_id, **net_params):
+ '''
+ Update give network
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.update_network openstack-net-id admin_state_up=false
+ '''
+ network_params = {}
+ for param in net_params:
+ if 'provider_' in param or 'router_' in param:
+ network_params[param.replace('_', ':', 1)] = net_params[param]
+ else:
+ network_params[param] = net_params[param]
+ LOG.info('ATTRIBUTES ' + str(network_params))
+ neutron_interface.update_network(network_id, {'network': network_params})
+
+
+@_autheticate
+def update_router(neutron_interface, router_id, **router_params):
+ '''
+ update given router
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.update_router openstack-router-id name='new_name'
+ external_gateway='openstack-network-id' administrative_state=true
+ '''
+ neutron_interface.update_router(router_id, {'router': router_params})
+
+
+@_autheticate
+def router_gateway_set(neutron_interface, router_id, external_gateway):
+ '''
+ Set external gateway for a router
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.update_router openstack-router-id openstack-network-id
+ '''
+ neutron_interface.update_router(
+ router_id, {'router': {'external_gateway_info':
+ {'network_id': external_gateway}}})
+
+
+@_autheticate
+def router_gateway_clear(neutron_interface, router_id):
+ '''
+ Clear external gateway for a router
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.update_router openstack-router-id
+ '''
+ neutron_interface.update_router(
+ router_id, {'router': {'external_gateway_info': None}})
+
+
+@_autheticate
+def create_router(neutron_interface, **router_params):
+ '''
+ Create OpenStack Neutron router
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.create_router name=R1
+ '''
+ response = neutron_interface.create_router({'router': router_params})
+ if 'router' in response and 'id' in response['router']:
+ return response['router']['id']
+
+
+@_autheticate
+def router_add_interface(neutron_interface, router_id, subnet_id):
+ '''
+ Attach router to a subnet
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.router_add_interface openstack-router-id subnet-id
+ '''
+ neutron_interface.add_interface_router(router_id, {'subnet_id': subnet_id})
+
+
+@_autheticate
+def router_rem_interface(neutron_interface, router_id, subnet_id):
+ '''
+ Dettach router from a subnet
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.router_rem_interface openstack-router-id subnet-id
+ '''
+ neutron_interface.remove_interface_router(
+ router_id, {'subnet_id': subnet_id})
+
+
+@_autheticate
+def create_security_group(neutron_interface, **sg_params):
+ '''
+ Create a new security group
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.create_security_group name='new_rule'
+ description='test rule'
+ '''
+ response = neutron_interface.create_security_group(
+ {'security_group': sg_params})
+ if 'security_group' in response and 'id' in response['security_group']:
+ return response['security_group']['id']
+
+
+@_autheticate
+def create_security_group_rule(neutron_interface, **rule_params):
+ '''
+ Create a rule entry for a security group
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.create_security_group_rule
+ '''
+ neutron_interface.create_security_group_rule(
+ {'security_group_rule': rule_params})
+
+
+@_autheticate
+def create_floatingip(neutron_interface, **floatingip_params):
+ '''
+ Create a new floating IP
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.create_floatingip floating_network_id=ext-net-id
+ '''
+ response = neutron_interface.create_floatingip(
+ {'floatingip': floatingip_params})
+ if 'floatingip' in response and 'id' in response['floatingip']:
+ return response['floatingip']['id']
+
+
+@_autheticate
+def create_subnet(neutron_interface, **subnet_params):
+ '''
+ Create a new subnet in OpenStack
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.create_subnet name='subnet name'
+ network_id='openstack-network-id' cidr='192.168.10.0/24' \\
+ gateway_ip='192.168.10.1' ip_version='4' enable_dhcp=false \\
+ start_ip='192.168.10.10' end_ip='192.168.10.20'
+ '''
+ if 'start_ip' in subnet_params:
+ subnet_params.update(
+ {'allocation_pools': [{'start': subnet_params.pop('start_ip'),
+ 'end': subnet_params.pop('end_ip', None)}]})
+ response = neutron_interface.create_subnet({'subnet': subnet_params})
+ if 'subnet' in response and 'id' in response['subnet']:
+ return response['subnet']['id']
+
+
+@_autheticate
+def create_network(neutron_interface, **net_params):
+ '''
+ Create a new network segment in OpenStack
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.create_network name=External
+ provider_network_type=flat provider_physical_network=ext
+ '''
+ network_params = {}
+ for param in net_params:
+ if 'provider_' in param or 'router_' in param:
+ network_params[param.replace('_', ':', 1)] = net_params[param]
+ else:
+ network_params[param] = net_params[param]
+ response = neutron_interface.create_network({'network': network_params})
+ if 'network' in response and 'id' in response['network']:
+ return response['network']['id']
+
+
+@_autheticate
+def create_port(neutron_interface, **port_params):
+ '''
+ Create a new port in OpenStack
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.create_port network_id='openstack-network-id'
+ '''
+ response = neutron_interface.create_port({'port': port_params})
+ if 'port' in response and 'id' in response['port']:
+ return response['port']['id']
+
+
+@_autheticate
+def update_port(neutron_interface, port_id, **port_params):
+ '''
+ Create a new port in OpenStack
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.update_port name='new_port_name'
+ '''
+ neutron_interface.update_port(port_id, {'port': port_params})
+
+
+@_autheticate
+def delete_floatingip(neutron_interface, floating_ip_id):
+ '''
+ delete a floating IP
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.delete_floatingip openstack-floating-ip-id
+ '''
+ neutron_interface.delete_floatingip(floating_ip_id)
+
+
+@_autheticate
+def delete_security_group(neutron_interface, sg_id):
+ '''
+ delete a security group
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.delete_security_group openstack-security-group-id
+ '''
+ neutron_interface.delete_security_group(sg_id)
+
+
+@_autheticate
+def delete_security_group_rule(neutron_interface, rule):
+ '''
+ delete a security group rule. pass all rule params that match the rule
+ to be deleted
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.delete_security_group_rule direction='ingress'
+ ethertype='ipv4' security_group_id='openstack-security-group-id'
+ port_range_min=100 port_range_max=4096 protocol='tcp'
+ remote_group_id='default'
+ '''
+ sg_rules = neutron_interface.list_security_group_rules(
+ security_group_id=rule['security_group_id'])
+ for sg_rule in sg_rules['security_group_rules']:
+ sgr_id = sg_rule.pop('id')
+ if sg_rule == rule:
+ neutron_interface.delete_security_group_rule(sgr_id)
+
+
+@_autheticate
+def delete_subnet(neutron_interface, subnet_id):
+ '''
+ delete given subnet
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.delete_subnet openstack-subnet-id
+ '''
+ neutron_interface.delete_subnet(subnet_id)
+
+
+@_autheticate
+def delete_network(neutron_interface, network_id):
+ '''
+ delete given network
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.delete_network openstack-network-id
+ '''
+ neutron_interface.delete_network(network_id)
+
+
+@_autheticate
+def delete_router(neutron_interface, router_id):
+ '''
+ delete given router
+ CLI Example:
+ .. code-block:: bash
+ salt '*' neutron.delete_router openstack-router-id
+ '''
+ neutron_interface.delete_router(router_id)
\ No newline at end of file
diff --git a/neutron/_states/neutronng.py b/neutron/_states/neutronng.py
new file mode 100644
index 0000000..b7c9195
--- /dev/null
+++ b/neutron/_states/neutronng.py
@@ -0,0 +1,522 @@
+# -*- coding: utf-8 -*-
+'''
+Management of Neutron resources
+===============================
+:depends: - neutronclient Python module
+:configuration: See :py:mod:`salt.modules.neutron` for setup instructions.
+.. code-block:: yaml
+ neutron network present:
+ neutron.network_present:
+ - name: Netone
+ - provider_physical_network: PHysnet1
+ - provider_network_type: vlan
+'''
+import logging
+from functools import wraps
+LOG = logging.getLogger(__name__)
+
+
+def __virtual__():
+ '''
+ Only load if neutron module is present in __salt__
+ '''
+ return 'neutronng' if 'neutron.list_networks' in __salt__ else False
+
+
+def _test_call(method):
+ (resource, functionality) = method.func_name.split('_')
+ if functionality == 'present':
+ functionality = 'updated'
+ else:
+ functionality = 'removed'
+
+ @wraps(method)
+ def check_for_testing(name, *args, **kwargs):
+ if __opts__.get('test', None):
+ return _no_change(name, resource, test=functionality)
+ return method(name, *args, **kwargs)
+ return check_for_testing
+
+
+def _neutron_module_call(method, *args, **kwargs):
+ return __salt__['neutronng.{0}'.format(method)](*args, **kwargs)
+
+
+def _auth(profile=None):
+ '''
+ Set up neutron credentials
+ '''
+ if profile:
+ credentials = __salt__['config.option'](profile)
+ user = credentials['keystone.user']
+ password = credentials['keystone.password']
+ tenant = credentials['keystone.tenant']
+ auth_url = credentials['keystone.auth_url']
+
+ kwargs = {
+ 'connection_user': user,
+ 'connection_password': password,
+ 'connection_tenant': tenant,
+ 'connection_auth_url': auth_url
+ }
+
+ return kwargs
+
+@_test_call
+def network_present(name=None,
+ tenant=None,
+ provider_network_type=None,
+ provider_physical_network=None,
+ router_external=None,
+ admin_state_up=None,
+ shared=None,
+ provider_segmentation_id=None,
+ profile=None):
+ '''
+ Ensure that the neutron network is present with the specified properties.
+ name
+ The name of the network to manage
+ '''
+ tenant_name = tenant
+ connection_args = _auth(profile)
+ try:
+ tenant_id = __salt__['keystone.tenant_get'](
+ name=tenant_name, **connection_args)[tenant_name]['id']
+ except:
+ tenant_id = None
+ LOG.debug('Cannot get the tenant id. User {0} is not an admin.'.format(
+ connection_args['connection_user']))
+ existing_network = _neutron_module_call(
+ 'list_networks', name=name, **connection_args)
+ network_arguments = _get_non_null_args(
+ name=name,
+ provider_network_type=provider_network_type,
+ provider_physical_network=provider_physical_network,
+ router_external=router_external,
+ admin_state_up=admin_state_up,
+ shared=shared,
+ tenant_id=tenant_id,
+ provider_segmentation_id=provider_segmentation_id)
+
+ if not existing_network:
+ network_arguments.update(connection_args)
+ _neutron_module_call('create_network', **network_arguments)
+ existing_network = _neutron_module_call(
+ 'list_networks', name=name, **connection_args)
+ if existing_network:
+ return _created(name, 'network', existing_network[name])
+ return _update_failed(name, 'network')
+
+ LOG.info('CONNECTION STRINGS' + str(connection_args))
+ LOG.info('existing ' + str(existing_network))
+ LOG.info('new ' + str(network_arguments))
+ existing_network = dict((key.replace(':', '_', 1), value)
+ for key, value in
+ existing_network[name].iteritems())
+ # generate differential
+ diff = dict((key, value) for key, value in network_arguments.iteritems()
+ if existing_network.get(key, None) != value)
+ if diff:
+ # update the changes
+ network_arguments = diff.copy()
+ network_arguments.update(connection_args)
+ try:
+ LOG.debug('updating network {0} with changes {1}'.format(
+ name, str(diff)))
+ _neutron_module_call('update_network',
+ existing_network['id'],
+ **network_arguments)
+ changes_dict = _created(name, 'network', diff)
+ changes_dict['comment'] = '{1} {0} updated'.format(name, 'network')
+ return changes_dict
+ except:
+ LOG.exception('Could not update network {0}'.format(name))
+ return _update_failed(name, 'network')
+ return _no_change(name, 'network')
+
+
+@_test_call
+def network_absent(name, profile=None):
+ connection_args = _auth(profile)
+ existing_network = _neutron_module_call(
+ 'list_networks', name=name, **connection_args)
+ if existing_network:
+ _neutron_module_call(
+ 'delete_network', existing_network[name]['id'], **connection_args)
+ if _neutron_module_call('list_networks', name=name, **connection_args):
+ return _delete_failed(name, 'network')
+ return _deleted(name, 'network', existing_network[name])
+ return _absent(name, 'network')
+
+
+@_test_call
+def subnet_present(name=None,
+ tenant=None,
+ network=None,
+ cidr=None,
+ ip_version=4,
+ enable_dhcp=True,
+ allocation_pools=None,
+ gateway_ip=None,
+ dns_nameservers=None,
+ host_routes=None,
+ profile=None):
+ '''
+ Ensure that the neutron subnet is present with the specified properties.
+ name
+ The name of the subnet to manage
+ '''
+ connection_args = _auth(profile)
+ tenant_name = tenant
+ try:
+ tenant_id = __salt__['keystone.tenant_get'](
+ name=tenant_name, **connection_args)[tenant_name]['id']
+ except:
+ tenant_id = None
+ LOG.debug('Cannot get the tenant id. User {0} is not an admin.'.format(
+ connection_args['connection_user']))
+ existing_subnet = _neutron_module_call(
+ 'list_subnets', tenant_id=tenant_id, name=name, **connection_args)
+ subnet_arguments = _get_non_null_args(
+ name=name,
+ network=network,
+ cidr=cidr,
+ ip_version=ip_version,
+ enable_dhcp=enable_dhcp,
+ allocation_pools=allocation_pools,
+ gateway_ip=gateway_ip,
+ dns_nameservers=dns_nameservers,
+ host_routes=host_routes)
+ # replace network with network_id
+ if 'network' in subnet_arguments:
+ network = subnet_arguments.pop('network', None)
+ existing_network = _neutron_module_call(
+ 'list_networks', tenant_id=tenant_id, name=network, **connection_args)
+ if existing_network:
+ subnet_arguments['network_id'] = existing_network[network]['id']
+ if not existing_subnet:
+ subnet_arguments.update(connection_args)
+ _neutron_module_call('create_subnet', tenant_id=tenant_id, **subnet_arguments)
+ existing_subnet = _neutron_module_call(
+ 'list_subnets', tenant_id=tenant_id, name=name, **connection_args)
+ if existing_subnet:
+ return _created(name, 'subnet', existing_subnet[name])
+ return _update_failed(name, 'subnet')
+ # change from internal representation
+ existing_subnet = existing_subnet[name]
+ # create differential
+ LOG.error('existing ' + str(existing_subnet))
+ LOG.error('new ' + str(subnet_arguments))
+ diff = dict((key, value) for key, value in subnet_arguments.iteritems()
+ if existing_subnet.get(key, None) != value)
+ if diff:
+ # update the changes
+ subnet_arguments = diff.copy()
+ subnet_arguments.update(connection_args)
+ try:
+ LOG.debug('updating subnet {0} with changes {1}'.format(
+ name, str(diff)))
+ _neutron_module_call('update_subnet',
+ existing_subnet['id'],
+ **subnet_arguments)
+ changes_dict = _created(name, 'subnet', diff)
+ changes_dict['comment'] = '{1} {0} updated'.format(name, 'subnet')
+ return changes_dict
+ except:
+ LOG.exception('Could not update subnet {0}'.format(name))
+ return _update_failed(name, 'subnet')
+ return _no_change(name, 'subnet')
+
+
+@_test_call
+def subnet_absent(name, profile=None):
+ connection_args = _auth(profile)
+ existing_subnet = _neutron_module_call(
+ 'list_subnets', tenant_id=tenant_id, name=name, **connection_args)
+ if existing_subnet:
+ _neutron_module_call(
+ 'delete_subnet', existing_subnet[name]['id'], **connection_args)
+ if _neutron_module_call('list_subnets', name=name, **connection_args):
+ return _delete_failed(name, 'subnet')
+ return _deleted(name, 'subnet', existing_subnet[name])
+ return _absent(name, 'subnet')
+ return _absent(name, 'network')
+
+
+@_test_call
+def router_present(name=None,
+ tenant=None,
+ gateway_network=None,
+ interfaces=None,
+ admin_state_up=True,
+ profile=None):
+ '''
+ Ensure that the neutron router is present with the specified properties.
+ name
+ The name of the subnet to manage
+ gateway_network
+ The network that would be the router's default gateway
+ interfaces
+ list of subnets the router attaches to
+ '''
+ connection_args = _auth(profile)
+ tenant_name = tenant
+ try:
+ tenant_id = __salt__['keystone.tenant_get'](
+ name=tenant_name, **connection_args)[tenant_name]['id']
+ except:
+ tenant_id = None
+ LOG.debug('Cannot get the tenant id. User {0} is not an admin.'.format(
+ connection_args['connection_user']))
+ existing_router = _neutron_module_call(
+ 'list_routers', name=name, **connection_args)
+ if not existing_router:
+ _neutron_module_call('create_router', name=name, tenant_id=tenant_id, admin_state_up=admin_state_up, **connection_args)
+ created_router = _neutron_module_call(
+ 'list_routers', name=name, **connection_args)
+ if created_router:
+ router_id = created_router[name]['id']
+ network = _neutron_module_call(
+ 'list_networks', name=gateway_network, **connection_args)
+ gateway_network_id = network[gateway_network]['id']
+ _neutron_module_call('router_gateway_set',
+ router_id=router_id,
+ external_gateway=gateway_network_id,
+ **connection_args)
+ for interface in interfaces:
+ subnet = _neutron_module_call(
+ 'list_subnets', name=interface, **connection_args)
+ subnet_id = subnet[interface]['id']
+ _neutron_module_call('router_add_interface',
+ router_id=router_id,
+ subnet_id=subnet_id,
+ **connection_args)
+ return _created(name,
+ 'router',
+ _neutron_module_call('list_routers',
+ name=name,
+ **connection_args))
+ return _create_failed(name, 'router')
+
+ router_id = existing_router[name]['id']
+ existing_router = existing_router[name]
+ diff = {}
+ if ( admin_state_up == True or admin_state_up == False ) and existing_router['admin_state_up'] != admin_state_up:
+ diff.update({'admin_state_up': admin_state_up})
+ if gateway_network:
+ network = _neutron_module_call(
+ 'list_networks', name=gateway_network, **connection_args)
+ gateway_network_id = network[gateway_network]['id']
+ if not existing_router['external_gateway_info'] and not existing_router['external_gateway_info'] == None:
+ if existing_router['external_gateway_info']['network_id'] != gateway_network_id:
+ diff.update({'external_gateway_info': {'network_id': gateway_network_id}})
+ elif not existing_router['external_gateway_info'] == None:
+ if not 'network_id' in existing_router['external_gateway_info'] or existing_router['external_gateway_info']['network_id'] != gateway_network_id:
+ diff.update({'external_gateway_info': {'network_id': gateway_network_id}})
+ if diff:
+ # update the changes
+ router_args = diff.copy()
+ router_args.update(connection_args)
+ try:
+ _neutron_module_call('update_router', existing_router['id'], **router_args)
+ changes_dict = _created(name, 'router', diff)
+ changes_dict['comment'] = 'Router {0} updated'.format(name)
+ return changes_dict
+ except:
+ LOG.exception('Router {0} could not be updated'.format(name))
+ return _update_failed(name, 'router')
+ return _no_change(name, 'router')
+
+def security_group_present(name=None,
+ tenant=None,
+ description=None,
+ rules=[],
+ profile=None):
+ '''
+ Ensure that the security group is present with the specified properties.
+ name
+ The name of the security group
+ description
+ The description of the security group
+ rules
+ list of rules to be added to the given security group
+ '''
+ # If the user is an admin, he's able to see the security groups from
+ # other tenants. In this case, we'll use the tenant id to get an existing
+ # security group.
+ connection_args = _auth(profile)
+ tenant_name = tenant
+ try:
+ tenant_id = __salt__['keystone.tenant_get'](
+ name=tenant_name, **connection_args)[tenant_name]['id']
+ except:
+ tenant_id = None
+ LOG.debug('Cannot get the tenant id. User {0} is not an admin.'.format(
+ connection_args['connection_user']))
+ if tenant_id:
+ security_group = _neutron_module_call(
+ 'list_security_groups', name=name, tenant_id=tenant_id,
+ **connection_args)
+ else:
+ security_group = _neutron_module_call(
+ 'list_security_groups', name=name, **connection_args)
+
+ if not security_group:
+ # Create the security group as it doesn't exist already.
+ security_group_id = _neutron_module_call('create_security_group',
+ name=name,
+ description=description,
+ tenant_id=tenant_id,
+ **connection_args)
+ else:
+ security_group_id = security_group[name]['id']
+
+ # Set the missing rules attributes (in case the user didn't specify them
+ # in pillar) to some default values.
+ rules_attributes_defaults = {
+ 'direction': 'ingress',
+ 'ethertype': 'IPv4',
+ 'protocol': 'TCP',
+ 'port_range_min': None,
+ 'port_range_max': None,
+ 'remote_ip_prefix': None
+ }
+ for rule in rules:
+ for attribute in rules_attributes_defaults.keys():
+ if not rule.has_key(attribute):
+ rule[attribute] = rules_attributes_defaults[attribute]
+
+ # Remove all the duplicates rules given by the user in pillar.
+ unique_rules = []
+ for rule in rules:
+ if rule not in unique_rules:
+ unique_rules.append(rule)
+
+ # Get the existing security group rules.
+ existing_rules = _neutron_module_call(
+ 'list_security_groups',
+ id=security_group_id,
+ **connection_args)[name]['security_group_rules']
+
+ new_rules = {}
+ for rule in unique_rules:
+ rule_found = False
+ for existing_rule in existing_rules:
+ attributes_match = True
+ # Compare the attributes of the existing security group rule with
+ # the attributes of the rule that we want to add.
+ for attribute in rules_attributes_defaults.keys():
+ existing_attribute = '' if not existing_rule[attribute] \
+ else str(existing_rule[attribute]).lower()
+ attribute = '' if not rule[attribute] \
+ else str(rule[attribute]).lower()
+ if existing_attribute != attribute:
+ attributes_match = False
+ break
+ if attributes_match:
+ rule_found = True
+ break
+ if rule_found:
+ # Skip adding the rule as it already exists.
+ continue
+ rule_index = len(new_rules) + 1
+ new_rules.update({'Rule {0}'.format(rule_index): rule})
+ _neutron_module_call('create_security_group_rule',
+ security_group_id=security_group_id,
+ direction=rule['direction'],
+ ethertype=rule['ethertype'],
+ protocol=rule['protocol'],
+ port_range_min=rule['port_range_min'],
+ port_range_max=rule['port_range_max'],
+ remote_ip_prefix=rule['remote_ip_prefix'],
+ tenant_id=tenant_id,
+ **connection_args)
+
+ if not security_group:
+ # The security group didn't exist. It was created and specified
+ # rules were added to it.
+ security_group = _neutron_module_call('list_security_groups',
+ id=security_group_id,
+ **connection_args)[name]
+ return _created(name, 'security_group', security_group)
+ if len(new_rules) == 0:
+ # Security group already exists and specified rules are already
+ # present.
+ return _no_change(name, 'security_group')
+ # Security group already exists, but the specified rules were added to it.
+ return _updated(name, 'security_group', {'New Rules': new_rules})
+
+def _created(name, resource, resource_definition):
+ changes_dict = {'name': name,
+ 'changes': resource_definition,
+ 'result': True,
+ 'comment': '{0} {1} created'.format(resource, name)}
+ return changes_dict
+
+def _updated(name, resource, resource_definition):
+ changes_dict = {'name': name,
+ 'changes': resource_definition,
+ 'result': True,
+ 'comment': '{0} {1} updated'.format(resource, name)}
+ return changes_dict
+
+def _no_change(name, resource, test=False):
+ changes_dict = {'name': name,
+ 'changes': {},
+ 'result': True}
+ if test:
+ changes_dict['comment'] = \
+ '{0} {1} will be {2}'.format(resource, name, test)
+ else:
+ changes_dict['comment'] = \
+ '{0} {1} is in correct state'.format(resource, name)
+ return changes_dict
+
+
+def _deleted(name, resource, resource_definition):
+ changes_dict = {'name': name,
+ 'changes': {},
+ 'comment': '{0} {1} removed'.format(resource, name),
+ 'result': True}
+ return changes_dict
+
+
+def _absent(name, resource):
+ changes_dict = {'name': name,
+ 'changes': {},
+ 'comment': '{0} {1} not present'.format(resource, name),
+ 'result': True}
+ return changes_dict
+
+
+def _delete_failed(name, resource):
+ changes_dict = {'name': name,
+ 'changes': {},
+ 'comment': '{0} {1} failed to delete'.format(resource,
+ name),
+ 'result': False}
+ return changes_dict
+
+def _create_failed(name, resource):
+ changes_dict = {'name': name,
+ 'changes': {},
+ 'comment': '{0} {1} failed to create'.format(resource,
+ name),
+ 'result': False}
+ return changes_dict
+
+def _update_failed(name, resource):
+ changes_dict = {'name': name,
+ 'changes': {},
+ 'comment': '{0} {1} failed to update'.format(resource,
+ name),
+ 'result': False}
+ return changes_dict
+
+
+def _get_non_null_args(**kwargs):
+ '''
+ Return those kwargs which are not null
+ '''
+ return dict((key, value,) for key, value in kwargs.iteritems()
+ if value is not None)
\ No newline at end of file
diff --git a/neutron/client.sls b/neutron/client.sls
new file mode 100644
index 0000000..865186e
--- /dev/null
+++ b/neutron/client.sls
@@ -0,0 +1,96 @@
+{%- from "neutron/map.jinja" import client with context %}
+{%- if client.enabled %}
+
+neutron_client_packages:
+ pkg.installed:
+ - names: {{ client.pkgs }}
+
+
+{%- for identity_name, identity in client.server.iteritems() %}
+
+{%- for network_name, network in identity.network.iteritems() %}
+
+neutron_openstack_network_{{ network_name }}:
+ neutronng.network_present:
+ - name: {{ network_name }}
+ - profile: {{ identity_name }}
+ - tenant: {{ network.tenant }}
+
+ {%- if network.provider_network_type is defined %}
+ - provider_network_type: {{ network.provider_network_type }}
+ {%- endif %}
+ {%- if network.provider_physical_network is defined %}
+ - provider_physical_network: {{ network.provider_physical_network }}
+ {%- endif %}
+ {%- if network.router_external is defined %}
+ - router_external: {{ network.router_external }}
+ {%- endif %}
+ {%- if network.admin_state_up is defined %}
+ - admin_state_up: {{ network.admin_state_up }}
+ {%- endif %}
+ {%- if network.shared is defined %}
+ - shared: {{ network.shared }}
+ {%- endif %}
+ {%- if network.provider_segmentation_id is defined %}
+ - provider_segmentation_id: {{ network.provider_segmentation_id }}
+ {%- endif %}
+
+{%- for subnet_name, subnet in network.subnet.iteritems() %}
+neutron_openstack_subnet_{{ subnet_name }}:
+ neutronng.subnet_present:
+ - name: {{ subnet_name }}
+ - network: {{ network_name }}
+ - profile: {{ identity_name }}
+ - tenant: {{ network.tenant }}
+
+ {%- if subnet.cidr is defined %}
+ - cidr: {{ subnet.cidr }}
+ {%- endif %}
+ {%- if subnet.ip_version is defined %}
+ - ip_version: {{ subnet.ip_version }}
+ {%- endif %}
+ {%- if subnet.enable_dhcp is defined %}
+ - enable_dhcp: {{ subnet.enable_dhcp }}
+ {%- endif %}
+ {%- if subnet.allocation_pools is defined %}
+ - allocation_pools: {{ subnet.allocation_pools }}
+ {%- endif %}
+ {%- if subnet.gateway_ip is defined %}
+ - gateway_ip: {{ subnet.gateway_ip }}
+ {%- endif %}
+ {%- if subnet.dns_nameservers is defined %}
+ - dns_nameservers: {{ subnet.dns_nameservers }}
+ {%- endif %}
+ {%- if subnet.host_routes is defined %}
+ - host_routes: {{ subnet.host_routes }}
+ {%- endif %}
+ - require:
+ - neutronng: neutron_openstack_network_{{ network_name }}
+
+{%- endfor %}
+{%- endfor %}
+
+{%- for router_name, router in identity.router.iteritems() %}
+neutron_openstack_router_{{ router_name }}:
+ neutronng.router_present:
+ - name: {{ router_name }}
+ - interfaces: {{ router.interfaces }}
+ - gateway_network: {{ router.gateway_network }}
+ - profile: {{ identity_name }}
+ - tenant: {{ router.tenant }}
+ - admin_state_up: {{ router.admin_state_up }}
+{%- endfor %}
+
+{%- for security_group_name, security_group in identity.security_group.iteritems() %}
+openstack_security_group_{{ security_group_name }}:
+ neutronng.security_group_present:
+ - name: {{ security_group_name }}
+ - description: {{ security_group.description }}
+ - rules: {{ security_group.rules }}
+ - profile: {{ identity_name }}
+ - tenant: {{ security_group.tenant }}
+{%- endfor %}
+
+{%- endfor %}
+
+{%- endif %}
diff --git a/neutron/files/collectd_openstack_neutron.conf b/neutron/files/collectd_openstack_neutron.conf
index 8593cdf..43bbf02 100644
--- a/neutron/files/collectd_openstack_neutron.conf
+++ b/neutron/files/collectd_openstack_neutron.conf
@@ -5,6 +5,8 @@
Username "{{ plugin.username }}"
Password "{{ plugin.password }}"
Tenant "{{ plugin.tenant }}"
- MaxRetries "2"
- Timeout "20"
+ MaxRetries "{{ plugin.max_retries|default(2) }}"
+ Timeout "{{ plugin.timeout|default(20) }}"
+ PaginationLimit "{{ plugin.pagination_limit|default(100) }}"
+ PollingInterval "{{ plugin.polling_interval|default(60) }}"
</Module>
diff --git a/neutron/files/collectd_openstack_neutron_agents.conf b/neutron/files/collectd_openstack_neutron_agents.conf
new file mode 100644
index 0000000..41a42b4
--- /dev/null
+++ b/neutron/files/collectd_openstack_neutron_agents.conf
@@ -0,0 +1,10 @@
+Import "openstack_neutron_agents"
+
+<Module "openstack_neutron_agents">
+ KeystoneUrl "{{ plugin.url }}"
+ Username "{{ plugin.username }}"
+ Password "{{ plugin.password }}"
+ Tenant "{{ plugin.tenant }}"
+ MaxRetries "2"
+ Timeout "20"
+</Module>
diff --git a/neutron/files/grafana_dashboards/neutron_openvswitch_influxdb.json b/neutron/files/grafana_dashboards/neutron_openvswitch_influxdb.json
new file mode 100644
index 0000000..f8419ec
--- /dev/null
+++ b/neutron/files/grafana_dashboards/neutron_openvswitch_influxdb.json
@@ -0,0 +1,3808 @@
+{
+ "annotations": {
+ "enable": true,
+ "list": [
+ {
+ "datasource": "lma",
+ "enable": true,
+ "iconColor": "#C0C6BE",
+ "iconSize": 13,
+ "lineColor": "rgba(255, 96, 96, 0.592157)",
+ "name": "Status",
+ "query": "select title,tags,text from annotations where $timeFilter and cluster =~ /^neutron/",
+ "showLine": true,
+ "tagsColumn": "tags",
+ "textColumn": "text",
+ "titleColumn": "title"
+ }
+ ]
+ },
+ "editable": true,
+ "gnetId": null,
+ "hideControls": false,
+ "id": null,
+ "links": [],
+ "refresh": "1m",
+ "rows": [
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "cacheTimeout": null,
+ "colorBackground": true,
+ "colorValue": false,
+ "colors": [
+ "rgba(71, 212, 59, 0.4)",
+ "rgba(241, 181, 37, 0.73)",
+ "rgba(225, 40, 40, 0.59)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 6,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 1,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "column": "value",
+ "condition": "",
+ "dsType": "influxdb",
+ "fill": "",
+ "function": "last",
+ "groupBy": [],
+ "groupByTags": [],
+ "groupby_field": "",
+ "interval": "",
+ "measurement": "cluster_status",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"cluster_status\" WHERE \"environment_label\" =~ /^$environment$/ AND \"cluster_name\" = 'neutron' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "cluster_name",
+ "operator": "=",
+ "value": "neutron-control"
+ }
+ ]
+ }
+ ],
+ "thresholds": "1,3",
+ "title": "control plane",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "no data",
+ "value": "null"
+ },
+ {
+ "op": "=",
+ "text": "OKAY",
+ "value": "0"
+ },
+ {
+ "op": "=",
+ "text": "WARN",
+ "value": "1"
+ },
+ {
+ "op": "=",
+ "text": "UNKN",
+ "value": "2"
+ },
+ {
+ "op": "=",
+ "text": "CRIT",
+ "value": "3"
+ },
+ {
+ "op": "=",
+ "text": "DOWN",
+ "value": "4"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": true,
+ "colorValue": false,
+ "colors": [
+ "rgba(71, 212, 59, 0.4)",
+ "rgba(241, 181, 37, 0.73)",
+ "rgba(225, 40, 40, 0.59)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 42,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 1,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "column": "value",
+ "condition": "",
+ "dsType": "influxdb",
+ "fill": "",
+ "function": "last",
+ "groupBy": [],
+ "groupByTags": [],
+ "groupby_field": "",
+ "interval": "",
+ "measurement": "cluster_status",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"cluster_status\" WHERE \"environment_label\" =~ /^$environment$/ AND \"cluster_name\" = 'neutron' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "cluster_name",
+ "operator": "=",
+ "value": "neutron-data"
+ }
+ ]
+ }
+ ],
+ "thresholds": "1,3",
+ "title": "data plane",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "no data",
+ "value": "null"
+ },
+ {
+ "op": "=",
+ "text": "OKAY",
+ "value": "0"
+ },
+ {
+ "op": "=",
+ "text": "WARN",
+ "value": "1"
+ },
+ {
+ "op": "=",
+ "text": "UNKN",
+ "value": "2"
+ },
+ {
+ "op": "=",
+ "text": "CRIT",
+ "value": "3"
+ },
+ {
+ "op": "=",
+ "text": "DOWN",
+ "value": "4"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(71, 212, 59, 0.4)",
+ "rgba(245, 150, 40, 0.73)",
+ "rgba(225, 40, 40, 0.59)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 13,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": true
+ },
+ "targets": [
+ {
+ "column": "value",
+ "condition": "",
+ "dsType": "influxdb",
+ "fill": "",
+ "function": "count",
+ "groupBy": [
+ {
+ "interval": "auto",
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "groupby_field": "",
+ "interval": "",
+ "measurement": "openstack_neutron_http_response_times",
+ "policy": "default",
+ "query": "SELECT sum(\"count\") FROM \"openstack_neutron_http_response_times\" WHERE \"hostname\" =~ /$server/ AND \"http_status\" = '5xx' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "count"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "sum"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "hostname",
+ "operator": "=~",
+ "value": "/$server/"
+ },
+ {
+ "condition": "AND",
+ "key": "http_status",
+ "operator": "=",
+ "value": "5xx"
+ }
+ ]
+ }
+ ],
+ "thresholds": "0,1",
+ "title": "HTTP 5xx errors",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "0",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 7,
+ "interval": ">60s",
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": false,
+ "max": true,
+ "min": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "span": 8,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "GET",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "mean",
+ "groupBy": [
+ {
+ "interval": "auto",
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "interval": "",
+ "measurement": "openstack_neutron_http_response_times",
+ "policy": "default",
+ "query": "SELECT max(\"upper_90\") FROM \"openstack_neutron_http_response_times\" WHERE \"hostname\" =~ /$server/ AND \"http_method\" = 'GET' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "upper_90"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "max"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "hostname",
+ "operator": "=~",
+ "value": "/$server/"
+ },
+ {
+ "condition": "AND",
+ "key": "http_method",
+ "operator": "=",
+ "value": "GET"
+ }
+ ]
+ },
+ {
+ "alias": "POST",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "mean",
+ "groupBy": [
+ {
+ "interval": "auto",
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "interval": "",
+ "measurement": "openstack_neutron_http_response_times",
+ "policy": "default",
+ "query": "SELECT max(\"upper_90\") FROM \"openstack_neutron_http_response_times\" WHERE \"hostname\" =~ /$server/ AND \"http_method\" = 'POST' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "B",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "upper_90"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "max"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "hostname",
+ "operator": "=~",
+ "value": "/$server/"
+ },
+ {
+ "condition": "AND",
+ "key": "http_method",
+ "operator": "=",
+ "value": "POST"
+ }
+ ]
+ },
+ {
+ "alias": "PUT",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "mean",
+ "groupBy": [
+ {
+ "interval": "auto",
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "interval": "",
+ "measurement": "openstack_neutron_http_response_times",
+ "policy": "default",
+ "query": "SELECT max(\"upper_90\") FROM \"openstack_neutron_http_response_times\" WHERE \"hostname\" =~ /$server/ AND \"http_method\" = 'PUT' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "C",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "upper_90"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "max"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "hostname",
+ "operator": "=~",
+ "value": "/$server/"
+ },
+ {
+ "condition": "AND",
+ "key": "http_method",
+ "operator": "=",
+ "value": "PUT"
+ }
+ ]
+ },
+ {
+ "alias": "DELETE",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "mean",
+ "groupBy": [
+ {
+ "interval": "auto",
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "interval": "",
+ "measurement": "openstack_neutron_http_response_times",
+ "policy": "default",
+ "query": "SELECT max(\"upper_90\") FROM \"openstack_neutron_http_response_times\" WHERE \"hostname\" =~ /$server/ AND \"http_method\" = 'DELETE' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "D",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "upper_90"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "max"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "hostname",
+ "operator": "=~",
+ "value": "/$server/"
+ },
+ {
+ "condition": "AND",
+ "key": "http_method",
+ "operator": "=",
+ "value": "DELETE"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "HTTP response time on $server",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 9,
+ "interval": "> 60s",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "span": 4,
+ "stack": false,
+ "steppedLine": true,
+ "targets": [
+ {
+ "alias": "healthy",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "last",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "groupByTags": [],
+ "measurement": "openstack_check_api",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"openstack_check_api\" WHERE \"environment_label\" =~ /^$environment$/ AND \"service\" = 'neutron-api' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=",
+ "value": "$environment"
+ },
+ {
+ "key": "service",
+ "operator": "=",
+ "value": "neutron-api"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "API Availability",
+ "tooltip": {
+ "msResolution": false,
+ "shared": false,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": "",
+ "logBase": 1,
+ "max": 1,
+ "min": 0,
+ "show": false
+ },
+ {
+ "format": "short",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": true,
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 8,
+ "interval": "> 60s",
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "hideEmpty": false,
+ "max": true,
+ "min": true,
+ "rightSide": false,
+ "show": true,
+ "total": true,
+ "values": true
+ },
+ "lines": false,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "span": 8,
+ "stack": true,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "2xx",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "count",
+ "groupBy": [
+ {
+ "interval": "auto",
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "interval": "",
+ "measurement": "openstack_neutron_http_response_times",
+ "policy": "default",
+ "query": "SELECT sum(\"count\") FROM \"openstack_neutron_http_response_times\" WHERE \"hostname\" =~ /$server/ AND \"http_status\" = '2xx' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "count"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "sum"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "hostname",
+ "operator": "=~",
+ "value": "/$server/"
+ },
+ {
+ "condition": "AND",
+ "key": "http_status",
+ "operator": "=",
+ "value": "2xx"
+ }
+ ]
+ },
+ {
+ "alias": "1xx",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "count",
+ "groupBy": [
+ {
+ "interval": "auto",
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "hide": false,
+ "interval": "",
+ "measurement": "openstack_neutron_http_response_times",
+ "policy": "default",
+ "query": "SELECT sum(\"count\") FROM \"openstack_neutron_http_response_times\" WHERE \"hostname\" =~ /$server/ AND \"http_status\" = '1xx' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "B",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "count"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "sum"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "hostname",
+ "operator": "=~",
+ "value": "/$server/"
+ },
+ {
+ "condition": "AND",
+ "key": "http_status",
+ "operator": "=",
+ "value": "1xx"
+ }
+ ]
+ },
+ {
+ "alias": "3xx",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "count",
+ "groupBy": [
+ {
+ "interval": "auto",
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "hide": false,
+ "interval": "",
+ "measurement": "openstack_neutron_http_response_times",
+ "policy": "default",
+ "query": "SELECT sum(\"count\") FROM \"openstack_neutron_http_response_times\" WHERE \"hostname\" =~ /$server/ AND \"http_status\" = '3xx' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "C",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "count"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "sum"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "hostname",
+ "operator": "=~",
+ "value": "/$server/"
+ },
+ {
+ "condition": "AND",
+ "key": "http_status",
+ "operator": "=",
+ "value": "3xx"
+ }
+ ]
+ },
+ {
+ "alias": "4xx",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "count",
+ "groupBy": [
+ {
+ "interval": "auto",
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "hide": false,
+ "interval": "",
+ "measurement": "openstack_neutron_http_response_times",
+ "policy": "default",
+ "query": "SELECT sum(\"count\") FROM \"openstack_neutron_http_response_times\" WHERE \"hostname\" =~ /$server/ AND \"http_status\" = '4xx' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "D",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "count"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "sum"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "hostname",
+ "operator": "=~",
+ "value": "/$server/"
+ },
+ {
+ "condition": "AND",
+ "key": "http_status",
+ "operator": "=",
+ "value": "4xx"
+ }
+ ]
+ },
+ {
+ "alias": "5xx",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "count",
+ "groupBy": [
+ {
+ "interval": "auto",
+ "params": [
+ "auto"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "hide": false,
+ "interval": "",
+ "measurement": "openstack_neutron_http_response_times",
+ "policy": "default",
+ "query": "SELECT sum(\"count\") FROM \"openstack_neutron_http_response_times\" WHERE \"hostname\" =~ /$server/ AND \"http_status\" = '5xx' AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "E",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "count"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "sum"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "hostname",
+ "operator": "=~",
+ "value": "/$server/"
+ },
+ {
+ "condition": "AND",
+ "key": "http_status",
+ "operator": "=",
+ "value": "5xx"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Number of HTTP responses on $server",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Service Status",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "100px",
+ "panels": [
+ {
+ "content": "<br />\n<h3 align=\"center\"> Up </h3>",
+ "editable": true,
+ "error": false,
+ "id": 29,
+ "links": [],
+ "mode": "html",
+ "span": 2,
+ "style": {},
+ "title": "",
+ "type": "text"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(255, 255, 255, 0.89)",
+ "rgba(255, 255, 255, 0.97)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 30,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "mean",
+ "groupBy": [],
+ "groupByTags": [],
+ "measurement": "haproxy_backend_servers",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"haproxy_backend_servers\" WHERE \"environment_label\" = '$environment' AND \"backend\" = 'neutron_api' AND \"state\" = 'up' AND $timeFilter",
+ "rawQuery": true,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=",
+ "value": "$environment"
+ },
+ {
+ "key": "backend",
+ "operator": "=",
+ "value": "neutron_api"
+ },
+ {
+ "condition": "AND",
+ "key": "state",
+ "operator": "=",
+ "value": "up"
+ }
+ ]
+ }
+ ],
+ "thresholds": "1,1",
+ "title": "Neutron",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "content": "",
+ "editable": true,
+ "error": false,
+ "id": 31,
+ "links": [],
+ "mode": "markdown",
+ "span": 8,
+ "style": {},
+ "title": "",
+ "type": "text"
+ },
+ {
+ "content": "<br />\n<h3 align=\"center\"> Down </h3>",
+ "editable": true,
+ "error": false,
+ "id": 32,
+ "links": [],
+ "mode": "html",
+ "span": 2,
+ "style": {},
+ "title": "",
+ "type": "text"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(255, 255, 255, 0.97)",
+ "rgba(255, 255, 255, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 33,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "mean",
+ "groupBy": [],
+ "groupByTags": [],
+ "measurement": "haproxy_backend_servers",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"haproxy_backend_servers\" WHERE \"environment_label\" =~ /^$environment$/ AND \"backend\" = 'neutron_api' AND \"state\" = 'down' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=",
+ "value": "$environment"
+ },
+ {
+ "key": "backend",
+ "operator": "=",
+ "value": "neutron_api"
+ },
+ {
+ "condition": "AND",
+ "key": "state",
+ "operator": "=",
+ "value": "down"
+ }
+ ]
+ }
+ ],
+ "thresholds": "0,1",
+ "title": "",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "content": "",
+ "editable": true,
+ "error": false,
+ "id": 34,
+ "links": [],
+ "mode": "markdown",
+ "span": 8,
+ "style": {},
+ "title": "",
+ "type": "text"
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Neutron API",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "100",
+ "panels": [
+ {
+ "content": "<br />\n<h3 align=\"center\"> Up </h3>",
+ "editable": true,
+ "error": false,
+ "id": 43,
+ "links": [],
+ "mode": "html",
+ "span": 2,
+ "style": {},
+ "title": "",
+ "type": "text"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(255, 255, 255, 0.89)",
+ "rgba(255, 255, 255, 0.97)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 44,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "openstack_neutron_agents",
+ "policy": "default",
+ "query": "SELECT mean(\"value\") FROM \"openstack_neutron_agents\" WHERE \"environment_label\" =~ /^$environment$/ AND \"service\" = 'dhcp' AND \"state\" = 'up' AND $timeFilter",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=~",
+ "value": "/^$environment$/"
+ },
+ {
+ "condition": "AND",
+ "key": "service",
+ "operator": "=",
+ "value": "dhcp"
+ },
+ {
+ "condition": "AND",
+ "key": "state",
+ "operator": "=",
+ "value": "up"
+ }
+ ]
+ }
+ ],
+ "thresholds": "1,1",
+ "title": "DHCP",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(255, 255, 255, 0.89)",
+ "rgba(255, 255, 255, 0.97)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 45,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "openstack_neutron_agents",
+ "policy": "default",
+ "query": "SELECT mean(\"value\") FROM \"openstack_neutron_agents\" WHERE \"environment_label\" =~ /^$environment$/ AND \"service\" = 'dhcp' AND \"state\" = 'up' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=~",
+ "value": "/^$environment$/"
+ },
+ {
+ "condition": "AND",
+ "key": "service",
+ "operator": "=",
+ "value": "l3"
+ },
+ {
+ "condition": "AND",
+ "key": "state",
+ "operator": "=",
+ "value": "up"
+ }
+ ]
+ }
+ ],
+ "thresholds": "1,1",
+ "title": "L3",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(255, 255, 255, 0.89)",
+ "rgba(255, 255, 255, 0.97)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 46,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "openstack_neutron_agents",
+ "policy": "default",
+ "query": "SELECT mean(\"value\") FROM \"openstack_neutron_agents\" WHERE \"environment_label\" =~ /^$environment$/ AND \"service\" = 'dhcp' AND \"state\" = 'up' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=~",
+ "value": "/^$environment$/"
+ },
+ {
+ "condition": "AND",
+ "key": "service",
+ "operator": "=",
+ "value": "metadata"
+ },
+ {
+ "condition": "AND",
+ "key": "state",
+ "operator": "=",
+ "value": "up"
+ }
+ ]
+ }
+ ],
+ "thresholds": "1,1",
+ "title": "Metadata",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(255, 255, 255, 0.89)",
+ "rgba(255, 255, 255, 0.97)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 47,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "openstack_neutron_agents",
+ "policy": "default",
+ "query": "SELECT mean(\"value\") FROM \"openstack_neutron_agents\" WHERE \"environment_label\" =~ /^$environment$/ AND \"service\" = 'dhcp' AND \"state\" = 'up' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=~",
+ "value": "/^$environment$/"
+ },
+ {
+ "condition": "AND",
+ "key": "service",
+ "operator": "=",
+ "value": "openvswitch"
+ },
+ {
+ "condition": "AND",
+ "key": "state",
+ "operator": "=",
+ "value": "up"
+ }
+ ]
+ }
+ ],
+ "thresholds": "1,1",
+ "title": "OpenvSwitch",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "content": "",
+ "editable": true,
+ "error": false,
+ "id": 48,
+ "links": [],
+ "mode": "markdown",
+ "span": 2,
+ "style": {},
+ "title": "",
+ "type": "text"
+ },
+ {
+ "content": "<br />\n<h3 align=\"center\"> Down </h3>",
+ "editable": true,
+ "error": false,
+ "id": 49,
+ "links": [],
+ "mode": "html",
+ "span": 2,
+ "style": {},
+ "title": "",
+ "type": "text"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(255, 255, 255, 0.9)",
+ "rgba(255, 255, 255, 0.89)",
+ "rgba(255, 0, 0, 0.97)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 50,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "hide": false,
+ "measurement": "openstack_neutron_agents",
+ "policy": "default",
+ "query": "SELECT mean(\"value\") FROM \"openstack_neutron_agents\" WHERE \"environment_label\" =~ /^$environment$/ AND \"service\" = 'dhcp' AND \"state\" = 'up' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=~",
+ "value": "/^$environment$/"
+ },
+ {
+ "condition": "AND",
+ "key": "service",
+ "operator": "=",
+ "value": "dhcp"
+ },
+ {
+ "condition": "AND",
+ "key": "state",
+ "operator": "=",
+ "value": "down"
+ }
+ ]
+ }
+ ],
+ "thresholds": "0,1",
+ "title": "",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(255, 255, 255, 0.97)",
+ "rgba(255, 255, 255, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 51,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "openstack_neutron_agents",
+ "policy": "default",
+ "query": "SELECT mean(\"value\") FROM \"openstack_neutron_agents\" WHERE \"environment_label\" =~ /^$environment$/ AND \"service\" = 'dhcp' AND \"state\" = 'up' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=~",
+ "value": "/^$environment$/"
+ },
+ {
+ "condition": "AND",
+ "key": "service",
+ "operator": "=",
+ "value": "l3"
+ },
+ {
+ "condition": "AND",
+ "key": "state",
+ "operator": "=",
+ "value": "down"
+ }
+ ]
+ }
+ ],
+ "thresholds": "0,1",
+ "title": "",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(255, 255, 255, 0.97)",
+ "rgba(255, 255, 255, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 52,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "openstack_neutron_agents",
+ "policy": "default",
+ "query": "SELECT mean(\"value\") FROM \"openstack_neutron_agents\" WHERE \"environment_label\" =~ /^$environment$/ AND \"service\" = 'dhcp' AND \"state\" = 'up' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=~",
+ "value": "/^$environment$/"
+ },
+ {
+ "condition": "AND",
+ "key": "service",
+ "operator": "=",
+ "value": "metadata"
+ },
+ {
+ "condition": "AND",
+ "key": "state",
+ "operator": "=",
+ "value": "down"
+ }
+ ]
+ }
+ ],
+ "thresholds": "0,1",
+ "title": "",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(255, 255, 255, 0.97)",
+ "rgba(255, 255, 255, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 53,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "dsType": "influxdb",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "openstack_neutron_agents",
+ "policy": "default",
+ "query": "SELECT mean(\"value\") FROM \"openstack_neutron_agents\" WHERE \"environment_label\" =~ /^$environment$/ AND \"service\" = 'dhcp' AND \"state\" = 'up' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=~",
+ "value": "/^$environment$/"
+ },
+ {
+ "condition": "AND",
+ "key": "service",
+ "operator": "=",
+ "value": "openvswitch"
+ },
+ {
+ "condition": "AND",
+ "key": "state",
+ "operator": "=",
+ "value": "down"
+ }
+ ]
+ }
+ ],
+ "thresholds": "0,1",
+ "title": "",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "content": "",
+ "editable": true,
+ "error": false,
+ "id": 54,
+ "links": [],
+ "mode": "markdown",
+ "span": 2,
+ "style": {},
+ "title": "",
+ "type": "text"
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Neutron Agents",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": null,
+ "decimals": 0,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 1,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": " active",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "column": "value",
+ "dsType": "influxdb",
+ "fill": "",
+ "function": "last",
+ "groupBy": [],
+ "groupByTags": [],
+ "measurement": "openstack_neutron_networks",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"openstack_neutron_networks\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'active' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=",
+ "value": "$environment"
+ },
+ {
+ "key": "state",
+ "operator": "=",
+ "value": "active"
+ }
+ ]
+ }
+ ],
+ "thresholds": "",
+ "title": "Networks",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "datasource": null,
+ "decimals": 0,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 35,
+ "interval": "> 60s",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "span": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_state",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "last",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "groupByTags": [
+ "state"
+ ],
+ "measurement": "openstack_neutron_networks",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"openstack_neutron_networks\" WHERE \"environment_label\" =~ /^$environment$/ AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=",
+ "value": "$environment"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": "",
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 2,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": " active",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "last",
+ "groupBy": [],
+ "groupByTags": [],
+ "measurement": "openstack_neutron_subnets",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"openstack_neutron_subnets\" WHERE \"environment_label\" =~ /^$environment$/ AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=",
+ "value": "$environment"
+ }
+ ]
+ }
+ ],
+ "thresholds": "",
+ "title": "Subnets",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "datasource": null,
+ "decimals": 0,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 36,
+ "interval": "> 60s",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "span": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "number of subnets",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "last",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "groupByTags": [],
+ "measurement": "openstack_neutron_subnets",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"openstack_neutron_subnets\" WHERE \"environment_label\" =~ /^$environment$/ AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=",
+ "value": "$environment"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": "",
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 3,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": " active",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "last",
+ "groupBy": [],
+ "groupByTags": [],
+ "measurement": "openstack_neutron_ports",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"openstack_neutron_ports\" WHERE \"environment_label\" =~ /^$environment$/ AND \"owner\" = 'compute' AND \"state\" = 'active' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=",
+ "value": "$environment"
+ },
+ {
+ "key": "owner",
+ "operator": "=",
+ "value": "compute"
+ },
+ {
+ "condition": "AND",
+ "key": "state",
+ "operator": "=",
+ "value": "active"
+ }
+ ]
+ }
+ ],
+ "thresholds": "",
+ "title": "Compute ports",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "datasource": null,
+ "decimals": 0,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 37,
+ "interval": "> 60s",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "span": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_owner",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "last",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "owner"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "groupByTags": [
+ "owner"
+ ],
+ "measurement": "openstack_neutron_ports",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"openstack_neutron_ports\" WHERE \"environment_label\" =~ /^$environment$/ AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=",
+ "value": "$environment"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": "",
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": null,
+ "decimals": 0,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 6,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": " active",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "last",
+ "groupBy": [],
+ "groupByTags": [],
+ "measurement": "openstack_neutron_routers",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"openstack_neutron_routers\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'active' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=",
+ "value": "$environment"
+ },
+ {
+ "key": "state",
+ "operator": "=",
+ "value": "active"
+ }
+ ]
+ }
+ ],
+ "thresholds": "",
+ "title": "Routers",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "datasource": null,
+ "decimals": 0,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 38,
+ "interval": "> 60s",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "span": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_state",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "last",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "state"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "groupByTags": [
+ "state"
+ ],
+ "measurement": "openstack_neutron_routers",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"openstack_neutron_routers\" WHERE \"environment_label\" =~ /^$environment$/ AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=",
+ "value": "$environment"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": "",
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "id": 41,
+ "interval": "> 60s",
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": " associated",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "last",
+ "groupBy": [],
+ "groupByTags": [],
+ "measurement": "openstack_neutron_floatingips",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"openstack_neutron_floatingips\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'associated' AND $timeFilter GROUP BY time($interval) fill(null)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=",
+ "value": "$environment"
+ },
+ {
+ "key": "state",
+ "operator": "=",
+ "value": "associated"
+ }
+ ]
+ }
+ ],
+ "thresholds": "",
+ "title": "Floating IP addresses",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "datasource": null,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 39,
+ "interval": "> 60s",
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "span": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "alias": "$tag_state",
+ "column": "value",
+ "dsType": "influxdb",
+ "function": "last",
+ "groupBy": [
+ {
+ "params": [
+ "$interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "state"
+ ],
+ "type": "tag"
+ },
+ {
+ "params": [
+ "0"
+ ],
+ "type": "fill"
+ }
+ ],
+ "groupByTags": [
+ "state"
+ ],
+ "measurement": "openstack_neutron_floatingips",
+ "policy": "default",
+ "query": "SELECT last(\"value\") FROM \"openstack_neutron_floatingips\" WHERE \"environment_label\" =~ /^$environment$/ AND $timeFilter GROUP BY time($interval) fill(0)",
+ "rawQuery": false,
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "last"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "environment_label",
+ "operator": "=",
+ "value": "$environment"
+ }
+ ]
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": "",
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Resources",
+ "titleSize": "h6"
+ }
+ ],
+ "schemaVersion": 13,
+ "sharedCrosshair": true,
+ "style": "dark",
+ "tags": [],
+ "templating": {
+ "enable": true,
+ "list": [
+ {
+ "allFormat": "regex values",
+ "allValue": null,
+ "current": {},
+ "datasource": null,
+ "hide": 0,
+ "includeAll": false,
+ "label": null,
+ "multi": false,
+ "name": "environment",
+ "options": [],
+ "query": "show tag values from cpu_idle with key = environment_label",
+ "refresh": 1,
+ "refresh_on_load": true,
+ "regex": "",
+ "sort": 0,
+ "tagValuesQuery": null,
+ "tagsQuery": null,
+ "type": "query"
+ },
+ {
+ "allFormat": "regex values",
+ "allValue": null,
+ "current": {},
+ "datasource": null,
+ "hide": 0,
+ "includeAll": true,
+ "label": null,
+ "multi": false,
+ "name": "server",
+ "options": [],
+ "query": " show tag values from openstack_neutron_http_response_times with key = hostname where environment_label =~ /^$environment$/ ",
+ "refresh": 1,
+ "refresh_on_load": true,
+ "regex": "",
+ "sort": 0,
+ "tagValuesQuery": null,
+ "tagsQuery": null,
+ "type": "query"
+ }
+ ]
+ },
+ "time": {
+ "from": "now-1h",
+ "to": "now"
+ },
+ "timepicker": {
+ "collapse": false,
+ "enable": true,
+ "notice": false,
+ "now": true,
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "status": "Stable",
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ],
+ "type": "timepicker"
+ },
+ "timezone": "browser",
+ "title": "Neutron",
+ "version": 1
+}
\ No newline at end of file
diff --git a/neutron/files/liberty/neutron-server.conf.Debian b/neutron/files/liberty/neutron-server.conf.Debian
index 80a4559..5e30e61 100644
--- a/neutron/files/liberty/neutron-server.conf.Debian
+++ b/neutron/files/liberty/neutron-server.conf.Debian
@@ -137,7 +137,11 @@
# Enable or disable bulk create/update/delete operations
# allow_bulk = True
# Enable or disable pagination
-# allow_pagination = False
+{% if server.get('allow_pagination', false) %}
+allow_pagination = True
+{% else %}
+allow_pagination = False
+{% endif %}
# Enable or disable sorting
# allow_sorting = False
# Enable or disable overlapping IPs for subnets
@@ -155,7 +159,7 @@
# be greater than 0. If the number of items requested is greater than
# pagination_max_limit, server will just return pagination_max_limit
# of number of items.
-# pagination_max_limit = -1
+pagination_max_limit = {{ server.pagination_max_limit|default('-1') }}
# Maximum number of DNS nameservers per subnet
# max_dns_nameservers = 5
diff --git a/neutron/files/mitaka/neutron-server.conf.Debian b/neutron/files/mitaka/neutron-server.conf.Debian
index eae3a94..bc05c66 100644
--- a/neutron/files/mitaka/neutron-server.conf.Debian
+++ b/neutron/files/mitaka/neutron-server.conf.Debian
@@ -62,14 +62,18 @@
#allow_bulk = true
# Allow the usage of the pagination (boolean value)
-#allow_pagination = false
+{% if server.get('allow_pagination', false) %}
+allow_pagination = True
+{% else %}
+allow_pagination = False
+{% endif %}
# Allow the usage of the sorting (boolean value)
#allow_sorting = false
# The maximum number of items returned in a single response, value was
# 'infinite' or negative integer means no limit (string value)
-#pagination_max_limit = -1
+pagination_max_limit = {{ server.pagination_max_limit|default('-1') }}
# Default value of availability zone hints. The availability zone aware
# schedulers use this when the resources availability_zone_hints is empty.
diff --git a/neutron/init.sls b/neutron/init.sls
index 8e39f6f..c12f434 100644
--- a/neutron/init.sls
+++ b/neutron/init.sls
@@ -8,4 +8,7 @@
{% endif %}
{% if pillar.neutron.compute is defined %}
- neutron.compute
+{% endif %}
+{% if pillar.neutron.client is defined %}
+- neutron.client
{% endif %}
\ No newline at end of file
diff --git a/neutron/map.jinja b/neutron/map.jinja
index 1af2a68..0eaf45f 100644
--- a/neutron/map.jinja
+++ b/neutron/map.jinja
@@ -48,13 +48,22 @@
},
}, merge=pillar.neutron.get('server', {})) %}
+{% set client = salt['grains.filter_by']({
+ 'Debian': {
+ 'pkgs': ['python-neutronclient']
+ },
+ 'RedHat': {
+ 'pkgs': ['python-neutronclient']
+ },
+}, merge=pillar.neutron.get('client', {})) %}
+
{%- if pillar.neutron.server is defined %}
{%- set tmp_server = pillar.neutron.server %}
{%- if not tmp_server.backend is defined %}
-{%- if tmp_server.plugin == "contrail" %}
+{%- if pillar.opencontrail is defined and tmp_server.plugin == "contrail" %}
{%- from "opencontrail/map.jinja" import config with context %}
diff --git a/neutron/meta/collectd.yml b/neutron/meta/collectd.yml
index 4fb96c5..e96fe23 100644
--- a/neutron/meta/collectd.yml
+++ b/neutron/meta/collectd.yml
@@ -1,4 +1,4 @@
-{%- if pillar.neutron.server %}
+{%- if pillar.neutron.server is defined %}
{%- from "neutron/map.jinja" import server with context %}
{%- if server.get('enabled', False) %}
local_plugin:
@@ -15,5 +15,12 @@
username: {{ server.identity.user }}
password: {{ server.identity.password }}
tenant: {{ server.identity.tenant }}
+ openstack_neutron_agents:
+ plugin: python
+ template: neutron/files/collectd_openstack_neutron_agents.conf
+ url: "http://{{ server.identity.host }}:{{ server.identity.port }}/v{% if server.identity.get('api_version', 2)|int == 2 %}2.0{% else %}3{% endif %}"
+ username: {{ server.identity.user }}
+ password: {{ server.identity.password }}
+ tenant: {{ server.identity.tenant }}
{%- endif %}
{%- endif %}
diff --git a/neutron/meta/grafana.yml b/neutron/meta/grafana.yml
index 358949f..602d6dc 100644
--- a/neutron/meta/grafana.yml
+++ b/neutron/meta/grafana.yml
@@ -1,4 +1,38 @@
dashboard:
+ main:
+ row:
+ ost-control-plane:
+ title: OpenStack Control Plane
+ panel:
+ neutron:
+ title: Neutron
+ links:
+ - dashboard: Neutron
+ title: Neutron
+ type: dashboard
+ target:
+ cluster_status:
+ rawQuery: true
+ query: SELECT last(value) FROM cluster_status WHERE cluster_name = 'neutron-control' AND environment_label = '$environment' AND $timeFilter GROUP BY time($interval) fill(null)
+{%- if pillar.neutron.get('server', {}).get('backend', {}).engine is defined and pillar.neutron.server.backend.engine == "ml2" %}
+ ost-data-plane:
+ title: OpenStack Data Plane
+ panel:
+ neutron:
+ title: Neutron
+ links:
+ - dashboard: Neutron
+ title: Neutron
+ type: dashboard
+ target:
+ cluster_status:
+ rawQuery: true
+ query: SELECT last(value) FROM cluster_status WHERE cluster_name = 'neutron-data' AND environment_label = '$environment' AND $timeFilter GROUP BY time($interval) fill(null)
+ neutron:
+ format: json
+ template: neutron/files/grafana_dashboards/neutron_openvswitch_influxdb.json
+{%- elif pillar.neutron.server is defined %}
neutron:
format: json
template: neutron/files/grafana_dashboards/neutron_influxdb.json
+{%- endif %}
diff --git a/neutron/meta/heka.yml b/neutron/meta/heka.yml
index 17fdc06..b14c967 100644
--- a/neutron/meta/heka.yml
+++ b/neutron/meta/heka.yml
@@ -1,10 +1,12 @@
{%- from "neutron/map.jinja" import server with context %}
-{%- if server.backend.engine == "ml2" %}
+{%- if server.get('backend', {}).engine is defined and server.backend.engine == "ml2" %}
{% set neutron_agents = ('l3', 'dhcp', 'metadata', 'openvswitch') %}
{%- else %}
{% set neutron_agents = () %}
{%- endif %}
+{% set ovs_support = pillar.neutron.get('compute', {}).get('enabled', False) or pillar.neutron.get('gateway', {}).get('enabled', False) %}
+
log_collector:
decoder:
neutron:
@@ -12,6 +14,12 @@
module_file: /usr/share/lma_collector/decoders/openstack_log.lua
module_dir: /usr/share/lma_collector/common;/usr/share/heka/lua_modules
adjust_timezone: true
+{%- if ovs_support %}
+ ovs:
+ engine: sandbox
+ module_file: /usr/share/lma_collector/decoders/ovs_log.lua
+ module_dir: /usr/share/lma_collector/common;/usr/share/heka/lua_modules
+{%- endif %}
splitter:
neutron:
engine: token
@@ -20,11 +28,21 @@
neutron_log:
engine: logstreamer
log_directory: "/var/log"
- file_match: 'neutron/(?P<Service>(dhcp-agent|l3-agent|metadata-agent|neutron-netns-cleanup|openvswitch-agent|server))\.log\.?(?P<Seq>\d*)$'
+ file_match: 'neutron/(?P<Service>(dhcp-agent|l3-agent|metadata-agent|neutron-netns-cleanup|openvswitch-agent|neutron-lbaas-agent|server))\.log\.?(?P<Seq>\d*)$'
differentiator: ['neutron', '_', 'Service']
priority: ["^Seq"]
decoder: "neutron_decoder"
splitter: "neutron_splitter"
+{%- if ovs_support %}
+ ovs_log:
+ engine: logstreamer
+ log_directory: "/var/log/openvswitch"
+ file_match: '(?P<Service>ovs\-vswitchd|ovsdb\-server|ovs\-ctl)\.log$'
+ differentiator: ['Service']
+ priority: ["^Seq"]
+ decoder: "ovs_decoder"
+ splitter: "TokenSplitter"
+{%- endif %}
metric_collector:
trigger:
neutron_logs_error:
@@ -41,7 +59,7 @@
window: 70
periods: 0
function: max
- {%- if pillar.neutron.server is defined %}
+{%- if pillar.neutron.server is defined %}
neutron_api_local_endpoint:
description: 'Neutron API is locally down'
severity: down
@@ -54,25 +72,32 @@
window: 60
periods: 0
function: last
- {%- endif %}
+{%- endif %}
alarm:
- {%- if pillar.neutron.server is defined %}
- neutron_logs:
+{%- if pillar.neutron.server is defined %}
+ neutron_logs_control:
alerting: enabled
triggers:
- neutron_logs_error
dimension:
- service: neutron-logs
+ service: neutron-logs-control
neutron_api_endpoint:
alerting: enabled
triggers:
- neutron_api_local_endpoint
dimension:
service: neutron-api-endpoint
- {%- endif %}
+{%- else %}
+ neutron_logs_data:
+ alerting: enabled
+ triggers:
+ - neutron_logs_error
+ dimension:
+ service: neutron-logs-data
+{%- endif %}
+{%- if pillar.neutron.server is defined %}
remote_collector:
trigger:
- {%- if pillar.neutron.server is defined %}
neutron_api_check_failed:
description: 'Endpoint check for neutron-api is failed'
severity: down
@@ -85,8 +110,7 @@
window: 60
periods: 0
function: last
- {%- endif %}
- {%- for agent in neutron_agents %}
+{%- for agent in neutron_agents %}
neutron_{{ agent }}_two_up:
description: 'Some Neutron {{ agent }} agents are down'
severity: warning
@@ -146,16 +170,14 @@
window: 60
periods: 0
function: last
- {%- endfor %}
+{%- endfor %}
alarm:
- {%- if pillar.neutron.server is defined %}
neutron_api_check:
triggers:
- neutron_api_check_failed
dimension:
service: neutron-api-check
- {%- endif %}
- {%- for agent in neutron_agents %}
+{%- for agent in neutron_agents %}
neutron_{{ agent }}:
alerting: enabled
triggers:
@@ -164,17 +186,19 @@
- neutron_{{ agent }}_two_up
dimension:
service: neutron-{{ agent }}
- {%- endfor %}
+{%- endfor %}
+{%- endif %}
aggregator:
alarm_cluster:
- neutron_logs:
+{%- if pillar.neutron.server is defined %}
+ neutron_logs_control:
policy: status_of_members
alerting: enabled
group_by: hostname
match:
- service: neutron-logs
+ service: neutron-logs-control
members:
- - neutron_logs
+ - neutron_logs_control
dimension:
service: neutron-control
nagios_host: 01-service-clusters
@@ -205,13 +229,13 @@
match:
service: neutron-control
members:
- - neutron_logs
+ - neutron_logs_control
- neutron_api_endpoint
- neutron_api_check
dimension:
cluster_name: neutron-control
nagios_host: 00-top-clusters
- {%- for agent in neutron_agents %}
+{%- for agent in neutron_agents %}
neutron_{{ agent }}:
policy: highest_severity
alerting: enabled
@@ -222,7 +246,7 @@
dimension:
service: neutron-data
nagios_host: 01-service-clusters
- {%- endfor %}
+{%- endfor %}
{%- if neutron_agents|length > 0 %}
neutron_data:
policy: highest_severity
@@ -230,10 +254,24 @@
match:
service: neutron-data
members:
- {%- for agent in neutron_agents %}
+ - neutron_logs_data
+{%- for agent in neutron_agents %}
- neutron_{{ agent }}
- {%- endfor %}
+{%- endfor %}
dimension:
cluster_name: neutron-data
nagios_host: 00-top-clusters
{%- endif %}
+{%- else %}
+ neutron_logs_data:
+ policy: status_of_members
+ alerting: enabled
+ group_by: hostname
+ match:
+ service: neutron-logs-data
+ members:
+ - neutron_logs_data
+ dimension:
+ service: neutron-data
+ nagios_host: 01-service-clusters
+{%- endif %}
diff --git a/neutron/server.sls b/neutron/server.sls
index 370e402..23b439b 100644
--- a/neutron/server.sls
+++ b/neutron/server.sls
@@ -1,5 +1,5 @@
{%- from "neutron/map.jinja" import server with context %}
-{%- if server.enabled %}
+{%- if server.get('enabled', False) %}
neutron_server_packages:
pkg.installed: