class CF_Secgroup_rule(object):

    def __init__(self, module):
        self.module = module
        admin_user = self.module.params['admin_user']
        admin_password = self.module.params['admin_password']
        api_url = self.module.params['api_url']
        self.name = self.module.params['name']
        try:
            self.cf = CF(api_url)
            self.cf.login(admin_user, admin_password)
        except CFException as e:
            self.module.fail_json(msg=str(e))
        except Exception as e:
            self.module.fail_json(msg="Exception: %s" % str(e))
        self.secg_name = self.module.params['sec_group']

    def run(self):
        state = self.module.params['state']
        try:
            sec_group = self.cf.search_secgroup(self.secg_name)
            if not sec_group:
                self.module.fail_json(msg='Security group not found')
            mode = state == "present"
            sec_group_guid = sec_group['metadata']['guid']
            result = self.set_sec_group_rule(sec_group_guid, mode)
        except CFException as e:
            self.module.fail_json(msg=str(e))
        except Exception as e:
            self.module.fail_json(msg="Exception: %s" % str(e))
        self.module.exit_json(**result)

    def set_sec_group_rule(self, guid, mode):
        rule = {
            'description': self.name,
            'destination': self.module.params['destination'],
            'protocol': self.module.params['protocol'],
            'log': self.module.params['log']
        }
        if self.module.params['ports'] is not None:
            rule['ports'] = self.module.params['ports']
        if self.module.params['code'] is not None:
            rule['code'] = self.module.params['code']
        if self.module.params['type'] is not None:
            rule['type'] = self.module.params['type']
        sec_group = self.cf.manage_secgroup_rule(guid, rule, mode)
        changed = False
        msg = "CF security group %s rules not updated" % (self.name)
        if sec_group is not None:
            changed = True
            msg = "CF security group %s rules updated" % (self.name)
        result = {
            'changed': changed,
            'msg': msg,
            'data': sec_group
        }
        return result
class CF_Config(object):

    def __init__(self, module):
        self.module = module
        admin_user = self.module.params['admin_user']
        admin_password = self.module.params['admin_password']
        api_url = self.module.params['api_url']
        self.name = self.module.params['name']
        try:
            self.cf = CF(api_url)
            self.cf.login(admin_user, admin_password)
        except CFException as e:
            self.module.fail_json(msg=str(e))
        except Exception as e:
            self.module.fail_json(msg="Exception: %s" % str(e))

    def run(self):
        state = self.module.params['state']
        config_type = self.module.params['type']
        mode = True if state == "present" else False
        try:
            if config_type == "feature_flag":
                if self.module.params['value'] is not None:
                    mode = self.module.boolean(self.module.params['value'])
                result = self.set_flag(mode)
            elif config_type == "env_var":
                if self.module.params['value'] is None:
                    self.module.fail_json(msg="No value for env var %s" % self.name)
                result = self.set_env(mode)
            elif config_type == "sec_group":
                result = self.set_sec_group(mode)
            else:
                self.module.fail_json(msg='Invalid type: %s' % config_type)
        except CFException as e:
            self.module.fail_json(msg=str(e))
        except Exception as e:
            self.module.fail_json(msg="Exception: %s" % str(e))
        self.module.exit_json(**result)

    def set_flag(self, status):
        flags = self.cf.get_feature_flags()
        for f in flags:
            if f['name'] == self.name:
                break
        else:
            msg = 'Feature flag not found: %s' % (self.name)
            self.module.fail_json(msg=msg)
        changed = self.cf.manage_feature_flags(self.name, status)
        result = {
            'changed': changed,
            'msg': "CF feature flag %s: %s" % (self.name, status)
        }
        return result

    def set_env(self, add):
        context = self.module.params['context']
        value = self.module.params['value']
        changed = self.cf.manage_variable_group(self.name, value, context, add)
        result = {
            'changed': changed,
            'msg': "CF environment variable group %s: %s" % (self.name, value)
        }
        return result

    def set_sec_group(self, add):
        sec_group = self.cf.search_secgroup(self.name)
        if sec_group is None:
            self.module.fail_json(msg="Security group %s not found" % self.name)
        sec_group_guid = sec_group['metadata']['guid']
        context = self.module.params['context']
        changed = self.cf.manage_secgroup_defaults(sec_group_guid, context, add)
        result = {
            'changed': changed,
            'msg': "CF sec group %s default %s group: %s" % (self.name, context, changed)
        }
        return result
class CF_Config(object):
    def __init__(self, module):
        self.module = module
        admin_user = self.module.params['admin_user']
        admin_password = self.module.params['admin_password']
        api_url = self.module.params['api_url']
        self.name = self.module.params['name']
        try:
            self.cf = CF(api_url)
            self.cf.login(admin_user, admin_password)
        except CFException as e:
            self.module.fail_json(msg=str(e))
        except Exception as e:
            self.module.fail_json(msg="Exception: %s" % str(e))

    def run(self):
        state = self.module.params['state']
        config_type = self.module.params['type']
        mode = True if state == "present" else False
        try:
            if config_type == "feature_flag":
                if self.module.params['value'] is not None:
                    mode = self.module.boolean(self.module.params['value'])
                result = self.set_flag(mode)
            elif config_type == "env_var":
                if self.module.params['value'] is None:
                    self.module.fail_json(msg="No value for env var %s" %
                                          self.name)
                result = self.set_env(mode)
            elif config_type == "sec_group":
                result = self.set_sec_group(mode)
            else:
                self.module.fail_json(msg='Invalid type: %s' % config_type)
        except CFException as e:
            self.module.fail_json(msg=str(e))
        except Exception as e:
            self.module.fail_json(msg="Exception: %s" % str(e))
        self.module.exit_json(**result)

    def set_flag(self, status):
        flags = self.cf.get_feature_flags()
        for f in flags:
            if f['name'] == self.name:
                break
        else:
            msg = 'Feature flag not found: %s' % (self.name)
            self.module.fail_json(msg=msg)
        changed = self.cf.manage_feature_flags(self.name, status)
        result = {
            'changed': changed,
            'msg': "CF feature flag %s: %s" % (self.name, status)
        }
        return result

    def set_env(self, add):
        context = self.module.params['context']
        value = self.module.params['value']
        changed = self.cf.manage_variable_group(self.name, value, context, add)
        result = {
            'changed': changed,
            'msg': "CF environment variable group %s: %s" % (self.name, value)
        }
        return result

    def set_sec_group(self, add):
        sec_group = self.cf.search_secgroup(self.name)
        if sec_group is None:
            self.module.fail_json(msg="Security group %s not found" %
                                  self.name)
        sec_group_guid = sec_group['metadata']['guid']
        context = self.module.params['context']
        changed = self.cf.manage_secgroup_defaults(sec_group_guid, context,
                                                   add)
        result = {
            'changed':
            changed,
            'msg':
            "CF sec group %s default %s group: %s" %
            (self.name, context, changed)
        }
        return result
class CF_Secgroup(object):

    def __init__(self, module):
        self.module = module
        admin_user = self.module.params['admin_user']
        admin_password = self.module.params['admin_password']
        api_url = self.module.params['api_url']
        self.name = self.module.params['name']
        try:
            self.cf = CF(api_url)
            self.cf.login(admin_user, admin_password)
        except CFException as e:
            self.module.fail_json(msg=str(e))
        except Exception as e:
            self.module.fail_json(msg="Exception: %s" % str(e))

    def run(self):
        state = self.module.params['state']
        try:
            sec_group = self.cf.search_secgroup(self.name)
            if state == 'present':
                space_state = self.module.params['space_state']
                mode = True if space_state == "present" else False
                space_guid = None
                if self.module.params['organization'] is not None:
                    org = self.cf.search_org(self.module.params['organization'])
                    if not org:
                        self.module.fail_json(msg='Organization not found')
                    org_guid = org['metadata']['guid']
                    space_name = self.module.params['space']
                    space = self.cf.search_space(org_guid, space_name)
                    if not space:
                        self.module.fail_json(msg='Space not found')
                    space_guid = space['metadata']['guid']
                result = self.present(sec_group, space_guid, mode)
            elif state == 'absent':
                result = self.absent(sec_group)
            else:
                self.module.fail_json(msg='Invalid state: %s' % state)
        except CFException as e:
            self.module.fail_json(msg=str(e))
        except Exception as e:
            self.module.fail_json(msg="Exception: %s" % str(e))
        self.module.exit_json(**result)

    def absent(self, sec_group, async=False):
        changed = False
        if sec_group is not None:
            sec_group_guid = sec_group['metadata']['guid']
            changed = True
            if not self.module.check_mode:
                try:
                    self.cf.delete_secgroup(sec_group_guid, async)
                except CFException as e:
                    msg = 'Cannot delete security group %s: %s' % (self.name, str(e))
                    self.module.fail_json(msg=msg)
        result = {
            'changed': changed,
            'msg': "CF security group %s deleted" % (self.name)
        }
        return result