def test_get_configuration_valid(valid_state): parser = TerraformStateParser(valid_state) assert parser.get_partial_configuration() == { "cluster_name": "valid1", "nb_users": 10, "guest_passwd": "password-123", "storage": { "type": "nfs", "home_size": 100, "scratch_size": 50, "project_size": 50, }, "instances": { "mgmt": { "type": "p4-6gb", "count": 1 }, "login": { "type": "p4-6gb", "count": 1 }, "node": { "type": "p2-3gb", "count": 1 }, }, "domain": "calculquebec.cloud", "public_keys": ["ssh-rsa FAKE"], "image": "CentOS-7-x64-2019-07", "os_floating_ips": ["100.101.102.103"], }
def test_get_configuration_empty(empty_state): parser = TerraformStateParser(empty_state) assert parser.get_partial_configuration() == { "cluster_name": "", "domain": "", "image": "", "nb_users": 0, "instances": { "mgmt": { "type": "", "count": 0 }, "login": { "type": "", "count": 0 }, "node": { "type": "", "count": 0 }, }, "storage": { "type": "nfs", "home_size": 0, "project_size": 0, "scratch_size": 0, }, "public_keys": [""], "guest_passwd": "", "os_floating_ips": [], }
def get_from_state_file(cls, hostname): """ Returns a new MagicCastleConfiguration object with the configuration parsed from the terraform.tfstate file. Note: the `hieradata` field gets parsed from the main.tf.json file instead, because it is not available in the terraform.tfstate file. """ with open( get_cluster_path(hostname, TERRAFORM_STATE_FILENAME), "r" ) as terraform_state_file: state = json.load(terraform_state_file) parser = TerraformStateParser(state) configuration = parser.get_partial_configuration() # Add cluster_name and domain. When the terraform state file is empty, # these variables must still be parsed correctly to create a valid MagicCastleConfiguration object. [cluster_name, domain] = hostname.split(".", 1) configuration["cluster_name"] = cluster_name configuration["domain"] = domain # Add hieradata to configuration with open(get_cluster_path(hostname, MAIN_TERRAFORM_FILENAME), "r") as main_tf: main_tf_configuration = json.load(main_tf) if main_tf_configuration["module"]["openstack"].get("hieradata"): configuration["hieradata"] = main_tf_configuration["module"]["openstack"][ "hieradata" ] else: configuration["hieradata"] = "" return cls(configuration)
def get_from_main_tf_json_file(cls, hostname): """ Returns a new MagicCastleConfiguration object with the configuration parsed from the main.tf.json file. :param hostname: the hostname of the cluster. :return: The MagicCastleConfiguration object associated with the cluster. """ with open(get_cluster_path(hostname, MAIN_TERRAFORM_FILENAME), "r") as main_tf: main_tf_configuration = json.load(main_tf) configuration = main_tf_configuration["module"]["openstack"] for field in IGNORED_CONFIGURATION_FIELDS: configuration.pop(field, None) # "node" is the only instance category that is encapsulated in a list configuration["instances"]["node"] = configuration["instances"]["node"][0] # Try to parse the floating ips from terraform.tfstate try: with open( get_cluster_path(hostname, TERRAFORM_STATE_FILENAME), "r" ) as terraform_state_file: state = json.load(terraform_state_file) parser = TerraformStateParser(state) configuration["os_floating_ips"] = parser.get_os_floating_ips() except (json.JSONDecodeError, FileNotFoundError): if len(configuration["os_floating_ips"]) == 0: # When the floating ips is an empty list, it means it will be automatically allocated configuration["os_floating_ips"] = [AUTO_ALLOCATED_IP_LABEL] return cls(configuration)
def test_get_configuration_missing_nodes(missing_nodes_state): parser = TerraformStateParser(missing_nodes_state) assert parser.get_partial_configuration() == { "cluster_name": "missingnodes", "nb_users": 10, "guest_passwd": "password-123", "storage": { "type": "nfs", "home_size": 100, "scratch_size": 50, "project_size": 50, }, "instances": { "mgmt": { "type": "", "count": 0 }, "login": { "type": "", "count": 0 }, "node": { "type": "", "count": 0 }, }, "domain": "sub.example.com", "public_keys": ["ssh-rsa FAKE"], "image": "CentOS-7-x64-2019-07", "os_floating_ips": ["100.101.102.103"], }
def get_from_state_file(cls, hostname): """ Returns a new MagicCastleConfiguration object with the configuration parsed from the terraform.tfstate file. Note: the `hieradata` field gets parsed from the main.tf.json file instead, because it is not available in the terraform.tfstate file. """ with open( get_cluster_path(hostname, TERRAFORM_STATE_FILENAME), "r" ) as terraform_state_file: state = json.load(terraform_state_file) parser = TerraformStateParser(state) configuration = parser.get_partial_configuration() # Add hieradata to configuration with open(get_cluster_path(hostname, MAIN_TERRAFORM_FILENAME), "r") as main_tf: main_tf_configuration = json.load(main_tf) if main_tf_configuration["module"]["openstack"].get("hieradata"): configuration["hieradata"] = main_tf_configuration["module"]["openstack"][ "hieradata" ] else: configuration["hieradata"] = "" return cls(configuration)
def get_freeipa_passwd(self): if self.__is_busy(): return None try: with open(self.__get_cluster_path(TERRAFORM_STATE_FILENAME), "r") as terraform_state_file: state = json.load(terraform_state_file) return TerraformStateParser(state).get_freeipa_passwd() except FileNotFoundError: return None
def get_available_resources(self): if self.__is_busy(): raise BusyClusterException try: with open(self.__get_cluster_path(TERRAFORM_STATE_FILENAME), "r") as terraform_state_file: state = json.load(terraform_state_file) parser = TerraformStateParser(state) cloud_manager = CloudManager( pre_allocated_instance_count=parser.get_instance_count(), pre_allocated_ram=parser.get_ram(), pre_allocated_cores=parser.get_cores(), pre_allocated_volume_count=parser.get_volume_count(), pre_allocated_volume_size=parser.get_volume_size(), pre_allocated_floating_ips=parser.get_os_floating_ips(), ) except FileNotFoundError: cloud_manager = CloudManager() return cloud_manager.get_available_resources()
def test_get_ram_valid(valid_state): parser = TerraformStateParser(valid_state) assert parser.get_ram() == 6144 + 6144 + 3072
def test_get_os_floating_ips_empty(empty_state): parser = TerraformStateParser(empty_state) assert parser.get_os_floating_ips() == []
def test_get_os_floating_ips_valid(valid_state): parser = TerraformStateParser(valid_state) assert parser.get_os_floating_ips() == ["100.101.102.103"]
def test_get_volume_size_empty(empty_state): parser = TerraformStateParser(empty_state) assert parser.get_volume_size() == 0
def test_get_os_floating_ips_missing_nodes(missing_nodes_state): parser = TerraformStateParser(missing_nodes_state) assert parser.get_os_floating_ips() == ["100.101.102.103"]
def test_get_volume_count_missing_nodes(missing_nodes_state): parser = TerraformStateParser(missing_nodes_state) assert parser.get_volume_count() == 3
def test_get_volume_size_valid(valid_state): parser = TerraformStateParser(valid_state) assert parser.get_volume_size() == 230
def test_get_ram_missing_nodes(missing_nodes_state): parser = TerraformStateParser(missing_nodes_state) assert parser.get_ram() == 0
def test_get_volume_count_valid(valid_state): parser = TerraformStateParser(valid_state) assert parser.get_volume_count() == 6
def test_get_ram_empty(empty_state): parser = TerraformStateParser(empty_state) assert parser.get_ram() == 0
def test_get_volume_size_missing_nodes(missing_nodes_state): parser = TerraformStateParser(missing_nodes_state) assert parser.get_volume_size() == 200
def test_get_cores_empty(empty_state): parser = TerraformStateParser(empty_state) assert parser.get_cores() == 0
def test_get_cores_valid(valid_state): parser = TerraformStateParser(valid_state) assert parser.get_cores() == 4 + 4 + 2
def test_get_instance_count_empty(empty_state): parser = TerraformStateParser(empty_state) assert parser.get_instance_count() == 0