Esempio n. 1
0
class TestForeman(object):
    def __init__(self):
        self.foreman = None

    def setup(self):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        self.foreman = Foreman(
            conf["foreman_api_url"],
            conf["ipmi_username"],
            conf["ipmi_password"],
            loop=loop,
        )

    def teardown(self):
        self.foreman.loop.close()

    def test_get_all_hosts(self):
        hosts = self.foreman.loop.run_until_complete(
            self.foreman.get_all_hosts())
        assert isinstance(hosts, dict)

    def test_get_broken_hosts(self):
        hosts = self.foreman.loop.run_until_complete(
            self.foreman.get_broken_hosts())
        assert isinstance(hosts, dict)
Esempio n. 2
0
class TestForeman(object):
    def setup(self):
        self.foreman = Foreman(
            conf["foreman_api_url"],
            conf["ipmi_username"],
            conf["ipmi_password"],
        )

    def test_get_all_hosts(self):
        hosts = self.foreman.get_all_hosts()
        assert isinstance(hosts, dict)

    def test_get_broken_hosts(self):
        hosts = self.foreman.get_broken_hosts()
        assert isinstance(hosts, dict)
Esempio n. 3
0
def available(search):
    models = search.data['model']

    if models:
        query = None
        for model in models:
            if query:
                query = query | Q(model=model.upper())
            else:
                query = Q(model=model.upper())

        hosts = Host.objects.filter(query)
    else:
        hosts = Host.objects().all()

    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    foreman = Foreman(
        conf["foreman_api_url"],
        conf["foreman_username"],
        conf["foreman_password"],
        loop=loop,
    )
    broken_hosts = loop.run_until_complete(foreman.get_broken_hosts())

    available_hosts = []
    start = datetime.combine(search.data['start'], time.min)
    end = datetime.combine(search.data['end'], time.min)

    if hosts:
        for host in hosts:
            if Schedule.is_host_available(
                    host=host["name"], start=start,
                    end=end) and not broken_hosts.get(host["name"], False):
                host_dict = {"name": host.name, "model": host.model}
                available_hosts.append(host_dict)

    return jsonify(available_hosts)
Esempio n. 4
0
def main():
    foreman = Foreman(
        conf["foreman_api_url"],
        conf["foreman_username"],
        conf["foreman_password"]
    )

    lines = []
    all_hosts = foreman.get_all_hosts()
    blacklist = re.compile("|".join([re.escape(word) for word in conf["exclude_hosts"].split("|")]))

    broken_hosts = foreman.get_broken_hosts()
    domain_broken_hosts = {
        host: properties
        for host, properties in broken_hosts.items()
        if conf["domain"] in host
    }

    mgmt_hosts = {}
    for host, properties in all_hosts.items():
        if not blacklist.search(host):
            mgmt_host = foreman.get_idrac_host_with_details(host)
            if mgmt_host:
                properties["host_ip"] = all_hosts.get(host, {"ip": None})["ip"]
                properties["host_mac"] = all_hosts.get(host, {"mac": None})["mac"]
                properties["ip"] = mgmt_host["ip"]
                properties["mac"] = mgmt_host["mac"]
                mgmt_hosts[mgmt_host["name"]] = properties

    lines.append("### **SUMMARY**\n")
    _summary = print_summary()
    lines.extend(_summary)
    details_header = ["\n", "### **DETAILS**\n", "\n"]
    lines.extend(details_header)
    summary_response = requests.get(os.path.join(API_URL, "summary"))
    _cloud_summary = []
    if summary_response.status_code == 200:
        _cloud_summary = summary_response.json()
    for cloud in [cloud for cloud in _cloud_summary if cloud["count"] > 0]:
        name = cloud["name"]
        owner = cloud["owner"]
        lines.append("### <a name=%s></a>\n" % name.strip())
        lines.append("### **%s : %s (%s) -- %s**\n\n" % (name.strip(), cloud["count"], cloud["description"], owner))
        lines.extend(print_header())
        _cloud_obj = Cloud.objects(name=name).first()
        _hosts = Host.objects(cloud=_cloud_obj)
        for host in _hosts:
            lines.extend(add_row(host))
        lines.append("\n")

    lines.extend(print_unmanaged(mgmt_hosts, domain_broken_hosts))
    lines.extend(print_faulty(domain_broken_hosts))

    _full_path = os.path.join(conf["wp_wiki_git_repo_path"], "assignments.md")

    if not os.path.exists(conf["wp_wiki_git_repo_path"]):
        pathlib.Path(conf["wp_wiki_git_repo_path"]).mkdir(parents=True, exist_ok=True)

    with open(_full_path, "w+") as _f:
        _f.seek(0)
        for cloud in lines:
            _line = cloud if cloud else ""
            _f.write(_line)

        _f.truncate()
Esempio n. 5
0
    def POST(self, **data):
        # make sure post data passed in is ready to pass to mongo engine
        result, data = model.Schedule.prep_data(data)

        _start = None
        _end = None

        if "start" in data:
            _start = datetime.datetime.strptime(data["start"],
                                                '%Y-%m-%d %H:%M')

        if "end" in data:
            _end = datetime.datetime.strptime(data["end"], '%Y-%m-%d %H:%M')

        # check for broken hosts from foreman
        # to enable checking foreman host health before scheduling
        # set foreman_check_host_health: true in conf/quads.yml
        if conf["foreman_check_host_health"]:
            foreman = Foreman(conf["foreman_api_url"],
                              conf["foreman_username"],
                              conf["foreman_password"])
            broken_hosts = foreman.get_broken_hosts()
            if broken_hosts.get(data['host'], False):
                result.append("Host %s is in broken state" % data['host'])

        # Check if there were data validation errors
        if result:
            result = ['Data validation failed: %s' % ', '.join(result)]
            cherrypy.response.status = "400 Bad Request"
            return json.dumps({'result': result})

        cloud_obj = None
        if "cloud" in data:
            cloud_obj = model.Cloud.objects(name=data["cloud"]).first()
            if not cloud_obj:
                result.append("Provided cloud does not exist")
                cherrypy.response.status = "400 Bad Request"
                return json.dumps({'result': result})

        _host = data["host"]
        _host_obj = model.Host.objects(name=_host).first()

        if "index" in data:
            data["host"] = _host_obj
            schedule = self.model.objects(index=data["index"],
                                          host=data["host"]).first()
            if schedule:
                if not _start:
                    _start = schedule.start
                if not _end:
                    _end = schedule.end
                if not cloud_obj:
                    cloud_obj = schedule.cloud
                if model.Schedule.is_host_available(host=_host,
                                                    start=_start,
                                                    end=_end,
                                                    exclude=schedule.index):
                    data["cloud"] = cloud_obj
                    schedule.update(**data)
                    result.append('Updated %s %s' %
                                  (self.name, schedule.index))
                else:
                    result.append(
                        "Host is not available during that time frame")
        else:
            try:
                schedule = model.Schedule()
                if model.Schedule.is_host_available(host=_host,
                                                    start=_start,
                                                    end=_end):
                    data["cloud"] = cloud_obj
                    schedule.insert_schedule(**data)
                    cherrypy.response.status = "201 Resource Created"
                    result.append('Added schedule for %s on %s' %
                                  (data["host"], cloud_obj.name))
                else:
                    result.append(
                        "Host is not available during that time frame")

            except Exception as e:
                # TODO: make sure when this is thrown the output
                #       points back to here and gives the end user
                #       enough information to fix the issue
                cherrypy.response.status = "500 Internal Server Error"
                result.append('Error: %s' % e)
        return json.dumps({'result': result})
Esempio n. 6
0
    def GET(self, **data):
        args = {}
        _cloud = None
        _host = None
        if "cloudonly" in data:
            _cloud = model.Cloud.objects(cloud=data["cloudonly"])
            if not _cloud:
                cherrypy.response.status = "404 Not Found"
                return json.dumps({"result": "Cloud %s Not Found" % data["cloudonly"]})
            else:
                return _cloud.to_json()
        if self.name == "host":
            if "id" in data:
                _host = model.Host.objects(id=data["id"]).first()
            elif "name" in data:
                _host = model.Host.objects(name=data["name"]).first()
            elif "cloud" in data:
                _cloud = model.Cloud.objects(name=data["cloud"]).first()
                _host = model.Host.objects(cloud=_cloud)
            else:
                _host = model.Host.objects()
            if not _host:
                return json.dumps({"result": ["Nothing to do."]})
            return _host.to_json()
        if self.name == "ccuser":
            _clouds = self.model.objects().all()
            clouds_summary = []
            for cloud in _clouds:
                count = model.Schedule.current_schedule(cloud=cloud).count()
                clouds_summary.append(
                    {
                        "name": cloud.name,
                        "count": count,
                        "description": cloud.description,
                        "owner": cloud.owner,
                        "ticket": cloud.ticket,
                        "ccuser": cloud.ccuser,
                        "provisioned": cloud.provisioned,
                    }
                )

            return json.dumps(clouds_summary)
        if self.name == "cloud":
            if "id" in data:
                _cloud = model.Cloud.objects(id=data["id"]).first()
            elif "name" in data:
                _cloud = model.Cloud.objects(name=data["name"]).first()
            elif "owner" in data:
                _cloud = model.Cloud.to_json(owner=data["owner"]).first()
            if _cloud:
                return _cloud.to_json()
        if self.name == "available":

            _start = _end = datetime.datetime.now()
            if "start" in data:
                _start = datetime.datetime.strptime(data["start"], "%Y-%m-%dT%H:%M:%S")

            if "end" in data:
                _end = datetime.datetime.strptime(data["end"], "%Y-%m-%dT%H:%M:%S")

            available = []
            all_hosts = model.Host.objects().all()
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            foreman = Foreman(
                conf["foreman_api_url"],
                conf["foreman_username"],
                conf["foreman_password"],
                loop=loop,
            )
            broken_hosts = loop.run_until_complete(foreman.get_broken_hosts())

            for host in all_hosts:
                if model.Schedule.is_host_available(
                    host=host["name"], start=_start, end=_end
                ) and not broken_hosts.get(host["name"], False):
                    available.append(host["name"])
            return json.dumps(available)

        if self.name == "summary":
            _clouds = model.Cloud.objects().all()
            clouds_summary = []
            total_count = 0
            for cloud in _clouds:
                if cloud.name == "cloud01":
                    count = model.Host.objects(cloud=cloud).count()
                else:
                    date = datetime.datetime.now()
                    if "date" in data:
                        date = datetime.datetime.strptime(data["date"], "%Y-%m-%dT%H:%M:%S")
                    count = self.model.current_schedule(cloud=cloud, date=date).count()
                    total_count += count
                clouds_summary.append(
                    {
                        "name": cloud.name,
                        "count": count,
                        "description": cloud.description,
                        "owner": cloud.owner,
                        "ticket": cloud.ticket,
                        "ccuser": cloud.ccuser,
                        "provisioned": cloud.provisioned,
                        "validated": cloud.validated,
                    }
                )
            if "date" in data:
                host_count = model.Host.objects().count()
                for cloud in clouds_summary:
                    if cloud["name"] == "cloud01":
                        cloud["count"] = host_count - total_count

            return json.dumps(clouds_summary)

        if self.name == "qinq":
            _clouds = model.Cloud.objects().all()
            clouds_qinq = []
            for cloud in _clouds:
                if cloud.qinq:
                    qinq_value = "0 (Isolated)"
                else:
                    qinq_value = "1 (Combined)"
                clouds_qinq.append(
                    {
                        "name": cloud.name,
                        "qinq": qinq_value,
                    }
                )

            return json.dumps(clouds_qinq)

        objs = self.model.objects(**args)
        if objs:
            return objs.to_json()
        else:
            return json.dumps({"result": ["No results."]})
Esempio n. 7
0
    def POST(self, **data):
        # make sure post data passed in is ready to pass to mongo engine
        result, data = model.Schedule.prep_data(data)

        _start = None
        _end = None

        if "start" in data:
            _start = datetime.datetime.strptime(data["start"], "%Y-%m-%d %H:%M")

        if "end" in data:
            _end = datetime.datetime.strptime(data["end"], "%Y-%m-%d %H:%M")

        # check for broken hosts from foreman
        # to enable checking foreman host health before scheduling
        # set foreman_check_host_health: true in conf/quads.yml
        if conf["foreman_check_host_health"]:

            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            foreman = Foreman(
                conf["foreman_api_url"],
                conf["foreman_username"],
                conf["foreman_password"],
                loop=loop,
            )
            broken_hosts = loop.run_until_complete(foreman.get_broken_hosts())
            if broken_hosts.get(data["host"], False):
                result.append("Host %s is in broken state" % data["host"])

        # Check if there were data validation errors
        if result:
            result = ["Data validation failed: %s" % ", ".join(result)]
            cherrypy.response.status = "400 Bad Request"
            return json.dumps({"result": result})

        cloud_obj = None
        if "cloud" in data:
            cloud_obj = model.Cloud.objects(name=data["cloud"]).first()
            if not cloud_obj:
                result.append("Provided cloud does not exist")
                cherrypy.response.status = "400 Bad Request"
                return json.dumps({"result": result})

        _host = data["host"]
        _host_obj = model.Host.objects(name=_host).first()

        if "index" in data:
            data["host"] = _host_obj
            schedule = self.model.objects(
                index=data["index"], host=data["host"]
            ).first()
            if schedule:
                if not _start:
                    _start = schedule.start
                if not _end:
                    _end = schedule.end
                if not cloud_obj:
                    cloud_obj = schedule.cloud
                if model.Schedule.is_host_available(
                    host=_host, start=_start, end=_end, exclude=schedule.index
                ):
                    data["cloud"] = cloud_obj
                    notification_obj = model.Notification.objects(
                        cloud=cloud_obj, ticket=cloud_obj.ticket
                    ).first()
                    if notification_obj:
                        notification_obj.update(
                            one_day=False,
                            three_days=False,
                            five_days=False,
                            seven_days=False,
                        )
                    schedule.update(**data)
                    result.append("Updated %s %s" % (self.name, schedule.index))
                else:
                    result.append("Host is not available during that time frame")
        else:
            try:
                if model.Schedule.is_host_available(host=_host, start=_start, end=_end):

                    if self.model.current_schedule(cloud=cloud_obj) and cloud_obj.validated:
                        if not cloud_obj.wipe:
                            _host_obj.update(validated=True)
                        notification_obj = model.Notification.objects(
                            cloud=cloud_obj,
                            ticket=cloud_obj.ticket
                        ).first()
                        if notification_obj:
                            notification_obj.update(success=False)

                    schedule = model.Schedule()
                    data["cloud"] = cloud_obj
                    schedule.insert_schedule(**data)
                    cherrypy.response.status = "201 Resource Created"
                    result.append(
                        "Added schedule for %s on %s" % (data["host"], cloud_obj.name)
                    )
                else:
                    result.append("Host is not available during that time frame")

            except Exception as e:
                # TODO: make sure when this is thrown the output
                #       points back to here and gives the end user
                #       enough information to fix the issue
                cherrypy.response.status = "500 Internal Server Error"
                result.append("Error: %s" % e)
        return json.dumps({"result": result})