139 lines
4.9 KiB
Python
139 lines
4.9 KiB
Python
# Copyright 2016 Canonical Ltd
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
|
|
import charms.reactive as reactive
|
|
import charmhelpers.core.hookenv as hookenv
|
|
import charm.openstack.designate_bind as designate_bind
|
|
|
|
|
|
@reactive.when_not('installed')
|
|
def install_packages():
|
|
'''Install charms packages'''
|
|
designate_bind.install()
|
|
designate_bind.set_apparmor()
|
|
reactive.set_state('installed')
|
|
|
|
|
|
@reactive.when_not('rndckey.available')
|
|
def setup_secret():
|
|
'''Get the existing rndc key from leader db if one exists else generate a
|
|
new one'''
|
|
if designate_bind.init_rndckey():
|
|
reactive.set_state('rndckey.available')
|
|
|
|
|
|
@reactive.when('rndckey.available')
|
|
@reactive.when('dns-backend.related')
|
|
def send_info(dns_client):
|
|
'''Send the secret and the algorithm used to encode the key to clients'''
|
|
dns_client.send_rndckey_info(
|
|
designate_bind.get_rndc_secret(),
|
|
designate_bind.get_rndc_algorithm())
|
|
|
|
|
|
@reactive.when('rndckey.available')
|
|
@reactive.when('dns-backend.related')
|
|
def config_changed(*args):
|
|
'''Render configs and restart services if necessary'''
|
|
designate_bind.set_apparmor()
|
|
designate_bind.render_all_configs(args)
|
|
|
|
|
|
@reactive.when_not('sync.request.sent')
|
|
@reactive.when_not('zones.initialised')
|
|
@reactive.when_not('cluster.connected')
|
|
@reactive.when('installed')
|
|
def setup_sync_target_alone():
|
|
'''If this is the only unit in the application then setup a sync target.
|
|
This will likely by empty as zones.initialised is only unset when a unit
|
|
frst comes up but the presence of the target allows subsequent units to
|
|
bootstrap if leadership flips to them as they come up'''
|
|
if hookenv.is_leader():
|
|
designate_bind.setup_sync()
|
|
reactive.set_state('zones.initialised')
|
|
|
|
|
|
@reactive.when_not('zones.initialised')
|
|
@reactive.when('sync.request.sent')
|
|
@reactive.when('cluster.connected')
|
|
def update_zones_from_peer(hacluster):
|
|
'''A sync request has been sent by this unit so check if a peer has
|
|
responded and if so retrieve the zone information and install it'''
|
|
designate_bind.retrieve_zones(hacluster)
|
|
|
|
|
|
@reactive.when_not('sync.request.sent')
|
|
@reactive.when_not('zones.initialised')
|
|
@reactive.when('installed')
|
|
@reactive.when('cluster.connected')
|
|
def check_zone_status(hacluster):
|
|
'''This unit has not been initialised yet so request a zones file or
|
|
set an inital sync'''
|
|
|
|
if hookenv.is_leader():
|
|
if designate_bind.get_sync_time():
|
|
# This unit is not the leader but a sync target has already been
|
|
# set suggests this is a new unit which has been nominated as
|
|
# leader early in its lifecycle. The leader responds to sync
|
|
# requests and this unit is the leader so not worth sending out a
|
|
# sync request.
|
|
designate_bind.retrieve_zones()
|
|
else:
|
|
# This unit is the leader and no other unit has set up a sync
|
|
# target then create one since this is a new deployment
|
|
designate_bind.setup_sync()
|
|
reactive.set_state('zones.initialised')
|
|
else:
|
|
# If this unit is not the leader as is not yet initialised then request
|
|
# a zones file from a peer
|
|
designate_bind.request_sync(hacluster)
|
|
|
|
|
|
@reactive.when('zones.initialised')
|
|
@reactive.when('cluster.connected')
|
|
def process_sync_requests(hacluster):
|
|
'''If this unit is the leader process and new sync requests'''
|
|
if hookenv.is_leader():
|
|
designate_bind.process_requests(hacluster)
|
|
|
|
|
|
@reactive.when('zones.initialised')
|
|
def assess_status():
|
|
designate_bind.assess_status()
|
|
|
|
|
|
@reactive.when('config.changed.service_ips')
|
|
def service_ips_changed():
|
|
"""Reconfigure service IPs on the unit."""
|
|
designate_bind.reconfigure_service_ips()
|
|
|
|
|
|
@reactive.when('ha.connected')
|
|
def hacluster_connected(_):
|
|
"""Check if service IPs are awaiting configuration via hacluster."""
|
|
if reactive.is_flag_set(designate_bind.AWAITING_HACLUSTER_FLAG):
|
|
hookenv.log('hacluster connected, configuring Service IPs',
|
|
hookenv.INFO)
|
|
designate_bind.reconfigure_service_ips()
|
|
reactive.clear_flag(designate_bind.AWAITING_HACLUSTER_FLAG)
|
|
|
|
|
|
@reactive.when('ha-relation-departed')
|
|
def hacluster_departed(_):
|
|
"""Set blocked state if hacluster leaves and service_ips are configured."""
|
|
if hookenv.config('service_ips'):
|
|
reactive.set_flag(designate_bind.AWAITING_HACLUSTER_FLAG)
|
|
designate_bind.assess_status()
|