def sync_local_device_to_group(self, device_group_name): """ Sync local device to group """ request_url = self.bigip.icr_url + '/cm' payload = dict() payload['command'] = 'run' payload['options'] = [{'config-sync': 'to-group ' + device_group_name}] response = self.bigip.icr_session.post( request_url, data=json.dumps(payload), timeout=const.CONNECTION_TIMEOUT) if response.status_code < 400: return True else: Log.error('sync', response.text) raise exceptions.BigIPClusterSyncFailure(response.text) return False
def sync(self, name, force_now=False): """ Ensure local device in sync with group """ sync_start_time = time.time() dev_name = self.get_local_device_name() sleep_delay = const.SYNC_DELAY attempts = 0 if force_now: self.sync_local_device_to_group(name) time.sleep(sleep_delay) attempts += 1 while attempts < const.MAX_SYNC_ATTEMPTS: state = self.get_sync_status() if state in ['Standalone', 'In Sync']: break elif state == 'Awaiting Initial Sync': attempts += 1 Log.info( 'Cluster', "Device %s - Synchronizing initial config to group %s" % (dev_name, name)) self.sync_local_device_to_group(name) time.sleep(sleep_delay) elif state in ['Disconnected', 'Not All Devices Synced', 'Changes Pending']: attempts += 1 last_log_time = 0 now = time.time() wait_start_time = now # Keep checking the sync state in a quick loop. # We want to detect In Sync as quickly as possible. while now - wait_start_time < sleep_delay: # Only log once per second if now - last_log_time >= 1: Log.info( 'Cluster', 'Device %s, Group %s not synced. ' % (dev_name, name) + 'Waiting. State is: %s' % state) last_log_time = now state = self.get_sync_status() if state in ['Standalone', 'In Sync']: break time.sleep(.5) now = time.time() else: # if we didn't break out due to the group being in sync # then attempt to force a sync. self.sync_local_device_to_group(name) sleep_delay += const.SYNC_DELAY # no need to sleep here because we already spent the sleep # interval checking status. continue # Only a break from the inner while loop due to Standalone or # In Sync will reach here. # Normal exit of the while loop reach the else statement # above which continues the outer loop break elif state == 'Sync Failure': Log.info('Cluster', "Device %s - Synchronization failed for %s" % (dev_name, name)) Log.debug('Cluster', 'SYNC SECONDS (Sync Failure): ' + str(time.time() - sync_start_time)) raise exceptions.BigIPClusterSyncFailure( 'Device service group %s' % name + ' failed after ' + '%s attempts.' % const.MAX_SYNC_ATTEMPTS + ' Correct sync problem manually' + ' according to sol13946 on ' + ' support.f5.com.') else: attempts += 1 Log.info('Cluster', "Device %s " % dev_name + "Synchronizing config attempt %s to group %s:" % (attempts, name) + " current state: %s" % state) self.sync_local_device_to_group(name) time.sleep(sleep_delay) sleep_delay += const.SYNC_DELAY else: if state == 'Disconnected': Log.debug('Cluster', 'SYNC SECONDS(Disconnected): ' + str(time.time() - sync_start_time)) raise exceptions.BigIPClusterSyncFailure( 'Device service group %s' % name + ' could not reach a sync state' + ' because they can not communicate' + ' over the sync network. Please' + ' check connectivity.') else: Log.debug('Cluster', 'SYNC SECONDS(Timeout): ' + str(time.time() - sync_start_time)) raise exceptions.BigIPClusterSyncFailure( 'Device service group %s' % name + ' could not reach a sync state after ' + '%s attempts.' % const.MAX_SYNC_ATTEMPTS + ' It is in %s state currently.' % state + ' Correct sync problem manually' + ' according to sol13946 on ' + ' support.f5.com.') Log.debug('Cluster', 'SYNC SECONDS(Success): ' + str(time.time() - sync_start_time))