| #!/usr/bin/python |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you 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 sys |
| from merge import QueueFile |
| import logging |
| import os |
| import os.path |
| import configure |
| import json |
| |
| # first commandline argument should be the file to process |
| argc = len(sys.argv) |
| if argc != 2 and argc != 3: |
| logging.error("Invalid usage, args passed: %s" % sys.argv) |
| sys.exit(1) |
| |
| # FIXME we should get this location from a configuration class |
| jsonPath = "/var/cache/cloud/%s" |
| jsonFilename = sys.argv[1] |
| jsonConfigFile = jsonPath % jsonFilename |
| currentGuestNetConfig = "/etc/cloudstack/guestnetwork.json" |
| |
| |
| def finish_config(): |
| # Converge |
| returncode = configure.main(sys.argv) |
| sys.exit(returncode) |
| |
| |
| def process_file(): |
| logging.info("Processing JSON file %s" % sys.argv[1]) |
| qf = QueueFile() |
| if len(sys.argv) > 2 and sys.argv[2].lower() == "false": |
| qf.keep = False |
| |
| qf.setFile(sys.argv[1]) |
| qf.load(None) |
| # These can be safely deferred, dramatically speeding up loading times |
| if not (os.environ.get('DEFER_CONFIG', False) and ('vm_dhcp_entry.json' in sys.argv[1] or 'vm_metadata.json' in sys.argv[1])): |
| # Converge |
| finish_config() |
| |
| |
| def is_guestnet_configured(guestnet_dict, keys): |
| |
| existing_keys = [] |
| new_eth_key = None |
| |
| for k1, v1 in guestnet_dict.items(): |
| if k1 in keys and len(v1) > 0: |
| existing_keys.append(k1) |
| |
| if not existing_keys: |
| ''' |
| It seems all the interfaces have been removed. Let's allow a new configuration to come in. |
| ''' |
| logging.warn("update_config.py :: Reconfiguring guest network...") |
| return False |
| |
| file = open(jsonConfigFile) |
| new_guestnet_dict = json.load(file) |
| |
| if not new_guestnet_dict['add']: |
| ''' |
| Guest network has to be removed. |
| ''' |
| logging.info("update_config.py :: Removing guest network...") |
| return False |
| |
| ''' |
| Check if we have a new guest network ready to be setup |
| ''' |
| device = new_guestnet_dict['device'] |
| |
| if device in existing_keys: |
| ''' |
| Device already configured, ignore. |
| ''' |
| return True |
| |
| exists = False |
| |
| for key in existing_keys: |
| for interface in guestnet_dict[key]: |
| new_mac = new_guestnet_dict["mac_address"].encode('utf-8') |
| old_mac = interface["mac_address"].encode('utf-8') |
| new_ip = new_guestnet_dict["router_guest_ip"].encode('utf-8') |
| old_ip = interface["router_guest_ip"].encode('utf-8') |
| |
| if (new_mac == old_mac) and (new_ip == old_ip): |
| exists = True |
| break |
| |
| if exists: |
| break |
| |
| return exists |
| |
| |
| # If the command line json file is unprocessed process it |
| # This is important or, the control interfaces will get deleted! |
| if jsonFilename != "cmd_line.json" and os.path.isfile(jsonPath % "cmd_line.json"): |
| qf = QueueFile() |
| qf.setFile("cmd_line.json") |
| qf.load(None) |
| |
| if not (os.path.isfile(jsonConfigFile) and os.access(jsonConfigFile, os.R_OK)): |
| # Ignore if file is already processed |
| if os.path.isfile(jsonPath % ("processed/" + jsonFilename + ".gz")): |
| sys.exit(0) |
| logging.error("update_config.py :: Unable to read and access %s to process it" % jsonConfigFile) |
| sys.exit(1) |
| |
| # If the guest network is already configured and have the same IP, do not try to configure it again otherwise it will break |
| if jsonFilename.startswith("guest_network.json"): |
| if os.path.isfile(currentGuestNetConfig): |
| file = open(currentGuestNetConfig) |
| guestnet_dict = json.load(file) |
| |
| if not is_guestnet_configured(guestnet_dict, ['eth1', 'eth2', 'eth3', 'eth4', 'eth5', 'eth6', 'eth7', 'eth8', 'eth9']): |
| logging.info("update_config.py :: Processing Guest Network.") |
| process_file() |
| else: |
| logging.info("update_config.py :: No need to process Guest Network.") |
| finish_config() |
| else: |
| logging.info("update_config.py :: No GuestNetwork configured yet. Configuring first one now.") |
| process_file() |
| else: |
| logging.info("update_config.py :: Processing incoming file => %s" % sys.argv[1]) |
| process_file() |