def read_config(ini_group=None):
env_conf = dict(DEFAULT_CONFIG)<EOL>for key in REQUIRED_CONFIG_KEYS.union(ALLOWED_CONFIG_KEYS):<EOL><INDENT>env_key = "<STR_LIT>".format(key.upper())<EOL>value = os.getenv(env_key)<EOL>if value:<EOL><INDENT>env_conf[key] = value<EOL><DEDENT><DEDENT>overrides = os.getenv('<STR_LIT>', '<STR_LIT>').strip()<EOL>if not overrides and set(env_conf).issuperset(REQUIRED_CONFIG_KEYS):<EOL><INDENT>return env_conf<EOL><DEDENT>ini_conf = read_config_from_ini(ini_group)<EOL>overrides = {s.lower() for s in re.split(r'<STR_LIT>', overrides)}<EOL>config = dict(dict(env_conf, **ini_conf),<EOL>**{k: v for k, v in env_conf.items() if k in overrides})<EOL>missings = REQUIRED_CONFIG_KEYS.difference(config)<EOL>if missings:<EOL><INDENT>raise ValueError("<STR_LIT>" +<EOL>"<STR_LIT:U+002CU+0020>".join(missings))<EOL><DEDENT>bool_keys = ('<STR_LIT>',)<EOL>for bool_key in bool_keys:<EOL><INDENT>if isinstance(config[bool_key], string_type):<EOL><INDENT>try:<EOL><INDENT>config[bool_key] = strtobool(config[bool_key])<EOL><DEDENT>except ValueError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>return config<EOL>
Read the configuration from the environment, or config.

First it try to go for the environment, then it overrides
those with the cloudstack.ini file.