Change Require to unit scope + bug fixes

* Remove logic for getting rndc info from interface. How the rndc
  secret is derived is not really a function of the  interface, so
  remove it.

* Move slave_ips to use reactive framework rather than dropping down
  to relation_* tools

* Switch to unit scope. Switch interface to UNIT scope so information
  can be collected from individual units.

* Add method for collecting unit and address information

Change-Id: Id9ddb8b6bce8044da160672988492415689616b4
This commit is contained in:
Liam Young 2016-07-10 08:09:12 +00:00
parent dc26f9a155
commit eb3b2968e8
2 changed files with 68 additions and 26 deletions

View File

@ -36,16 +36,7 @@ class BindRNDCProvides(RelationBase):
conv = self.conversation()
conv.remove_state('{relation_name}.related')
def send_rndckey_info(self):
key_file = '/etc/bind/rndc.key'
with open(key_file, 'r') as f:
content = f.readlines()
# XXX Naive parsing of keyfile
for line in content:
if line and line.split()[0] == 'algorithm':
algorithm = line.split()[1]
if line and line.split()[0] == 'secret':
rndckey = line.split()[1]
def send_rndckey_info(self, rndckey, algorithm):
for conv in self.conversations():
conv.set_remote('rndckey', rndckey)
conv.set_remote('algorithm', algorithm)

View File

@ -6,7 +6,7 @@
# 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
# 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,
@ -20,37 +20,88 @@ from charms.reactive import scopes
class BindRNDCRequires(RelationBase):
scope = scopes.GLOBAL
scope = scopes.UNIT
# These remote data fields will be automatically mapped to accessors
# with a basic documentation string provided.
auto_accessors = ['algorithm', 'rndckey', 'private-address']
@hook('{requires:bind-rndc}-relation-joined')
def joined(self):
self.set_state('{relation_name}.connected')
conv = self.conversation()
conv.set_state('{relation_name}.connected')
@hook('{requires:bind-rndc}-relation-changed')
def changed(self):
self.set_state('{relation_name}.connected')
conv = self.conversation()
conv.set_state('{relation_name}.connected')
if self.data_complete():
self.set_state('{relation_name}.available')
conv.set_state('{relation_name}.available')
@hook('{requires:bind-rndc}-relation-{broken,departed}')
def departed_or_broken(self):
self.remove_state('{relation_name}.connected')
conv = self.conversation()
conv.remove_state('{relation_name}.connected')
if not self.data_complete():
self.remove_state('{relation_name}.available')
conv.remove_state('{relation_name}.available')
def data_complete(self):
"""Check if all information for a RNDC connection has been sent
@returns boolean: True if all required data for connection is present
"""
Get the connection string, if available, or None.
"""
data = {
'algorithm': self.algorithm(),
'secret': self.rndckey(),
'private_address': self.private_address(),
}
if all(data.values()):
if self.rndc_info and all(self.rndc_info.values()):
return True
return False
@property
def rndc_info(self):
"""Get RNDC connection information from DNS Slave
@returns dict: Return dict of RNDC connection information
"""
for conv in self.conversations():
data = {
'algorithm': conv.get_remote('algorithm'),
'secret': conv.get_remote('rndckey'),
}
if all(data.values()):
return data
return {}
@property
def algorithm(self):
"""Get algorith used to gen rndc secret from DNS Slave
@returns str: Return algorith used to gen rndc secret
"""
return self.rndc_info.get('algorithm')
@property
def rndckey(self):
"""Get rndc secret from DNS Slave
@returns str: Return rndc secret
"""
return self.rndc_info.get('secret')
@property
def private_address(self):
"""Get private address of unit in current relation context
@returns str: Return ip address
"""
conv = self.conversation()
return conv.get_remote('private-address')
def slave_ips(self):
"""Address information of DNS slaves
@return list: List of dicts containing unit name and address
"""
values = []
for conv in self.conversations():
values.append({
# Unit scoped relation so only one unit per conversation.
'unit': list(conv.units)[0],
'address': conv.get_remote('private-address')})
return values