Example #1
0
async def main(_loop):
    no_extend_label = "CANNOT_EXTEND"
    extend_label = "CAN_EXTEND"

    try:
        jira = Jira(
            Config["jira_url"],
            loop=_loop,
        )
    except JiraException as ex:
        logger.error(ex)
        return 1

    tickets = await jira.get_pending_tickets()
    for ticket in tickets["issues"]:
        ticket_key = ticket.get("key").split("-")[-1]
        fields = ticket.get("fields")
        if fields:
            description = fields.get("description")
            try:
                cloud_field = description.split("\n")[1]
                cloud = cloud_field.split()[-1]
            except IndexError:
                logger.warning(
                    f"Could not retrieve cloud name from ticket {ticket_key}")

            cloud_obj = Cloud.objects(name=cloud).first()
            schedules = Schedule.current_schedule(cloud=cloud_obj)
            conflict = False
            for schedule in schedules:
                end_date = schedule.end + timedelta(weeks=2)
                available = Schedule.is_host_available(host=schedule.host.name,
                                                       start=schedule.end,
                                                       end=end_date)
                if not available:
                    conflict = True
                    await jira.add_label(ticket_key, no_extend_label)
                    logger.info(f"{cloud} labeled {no_extend_label}")
                    break

            if not conflict:
                await jira.add_label(ticket_key, extend_label)
                logger.info(f"{cloud} labeled {extend_label}")

            parent = fields.get("parent")
            if parent:
                p_ticket_key = parent.get("key").split("-")[-1]
                watchers = await jira.get_watchers(p_ticket_key)
                for watcher in watchers["watchers"]:
                    await jira.add_watcher(ticket_key, watcher["key"])
    return 0
Example #2
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)
Example #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()

    available_hosts = []
    start = datetime.combine(search.data["start"], time(hour=22))
    end = datetime.combine(search.data["end"], time(hour=22))

    if hosts:
        for host in hosts:
            if Schedule.is_host_available(host=host["name"],
                                          start=start,
                                          end=end):
                current = False
                if Schedule.current_schedule(host=host):
                    current = True
                host_dict = {
                    "name": host.name,
                    "cloud": host.cloud.name,
                    "model": host.model,
                    "current": current
                }
                available_hosts.append(host_dict)

    return jsonify(available_hosts)
Example #4
0
    def GET(self, **data):
        args = {}
        _cloud = None
        _host = None
        if "cloudonly" in data:
            _cloud = 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 = Host.objects(id=data["id"]).first()
            elif "name" in data:
                _host = Host.objects(name=data["name"]).first()
            elif "cloud" in data:
                _cloud = Cloud.objects(name=data["cloud"]).first()
                _host = Host.objects(cloud=_cloud)
            else:
                _host = 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 = 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 = Cloud.objects(id=data["id"]).first()
            elif "name" in data:
                _cloud = Cloud.objects(name=data["name"]).first()
            elif "owner" in data:
                _cloud = 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 = Host.objects().all()

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

        if self.name == "summary":
            _clouds = Cloud.objects().all()
            clouds_summary = []
            total_count = 0
            for cloud in _clouds:
                if cloud.name == "cloud01":
                    count = Host.objects(cloud=cloud,
                                         retired=False,
                                         broken=False).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 = Host.objects(retired=False, broken=False).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 = Cloud.objects().all()
            clouds_qinq = []
            for cloud in _clouds:
                _type = "Isolated"
                if cloud.qinq == 1:
                    _type = "Combined"
                qinq_value = f"{cloud.qinq} ({_type})"
                clouds_qinq.append({"name": cloud.name, "qinq": qinq_value})

            return json.dumps(clouds_qinq)

        if self.name == "broken":
            _hosts = self.model.objects(broken=True)
            broken = []
            for host in _hosts:
                broken.append(host.name)

            return json.dumps(broken)

        if self.name == "retired":
            hosts = [host.name for host in self.model.objects(retired=True)]
            return json.dumps(hosts)

        objs = self.model.objects(**args)
        if objs:
            return objs.to_json()
        else:
            return json.dumps({"result": ["No results."]})
Example #5
0
    def POST(self, **data):
        # make sure post data passed in is ready to pass to mongo engine
        result, data = 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")

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

        broken_hosts = Host.objects(broken=True)
        if _host_obj in broken_hosts:
            result.append(f"Host {_host_obj.name} is in broken state")

        # 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 = 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})

        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 Schedule.is_host_available(host=_host,
                                              start=_start,
                                              end=_end,
                                              exclude=schedule.index):
                    data["cloud"] = cloud_obj
                    notification_obj = 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 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 = Notification.objects(
                            cloud=cloud_obj, ticket=cloud_obj.ticket).first()
                        if notification_obj:
                            notification_obj.update(success=False)

                    schedule = 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})
Example #6
0
def report_available(_logger, _start, _end):
    start = _start.replace(hour=22, minute=0, second=0)
    end = _end.replace(hour=22, minute=0, second=0)
    next_sunday = start + timedelta(days=(6 - start.weekday()))

    hosts = Host.objects()

    _logger.info(f"QUADS report for {start.date()} to {end.date()}:")

    days = 0
    total_allocated_month = 0
    total_hosts = len(hosts)
    for _date in date_span(start, end):
        total_allocated_month += Schedule.current_schedule(date=_date).count()
        days += 1
    utilized = total_allocated_month * 100 // (total_hosts * days)
    _logger.info(f"Percentage Utilized: {utilized}%")

    schedules = Schedule.objects(build_start__ne=None, build_end__ne=None)
    total = timedelta()
    for schedule in schedules:
        total += schedule.build_end - schedule.build_start
    if schedules:
        average_build = total / len(schedules)
        _logger.info(f"Average build delta: {average_build}")

    hosts_summary = {}
    for host in hosts:
        host_type = host.name.split(".")[0].split("-")[-1]
        if not hosts_summary.get(host_type):
            hosts_summary[host_type] = []
        hosts_summary[host_type].append(host)

    headers = [
        "Server Type", "Total", "Free", "Scheduled", "2 weeks", "4 weeks"
    ]
    _logger.info(f"{headers[0]:<12}| "
                 f"{headers[1]:>5}| "
                 f"{headers[2]:>5}| "
                 f"{headers[3]:>9}| "
                 f"{headers[4]:>7}| "
                 f"{headers[5]:>7}")
    for host_type, _hosts in hosts_summary.items():
        scheduled_count = 0
        two_weeks_availability_count = 0
        four_weeks_availability_count = 0
        for host in _hosts:
            schedule = Schedule.current_schedule(host=host)
            if schedule:
                scheduled_count += 1

            two_weeks_availability = Schedule.is_host_available(
                host=host.name,
                start=next_sunday,
                end=next_sunday + timedelta(weeks=2))
            if two_weeks_availability:
                two_weeks_availability_count += 1

            four_weeks_availability = Schedule.is_host_available(
                host=host.name,
                start=next_sunday,
                end=next_sunday + timedelta(weeks=4))
            if four_weeks_availability:
                four_weeks_availability_count += 1

        free = len(_hosts) - scheduled_count
        schedule_percent = scheduled_count * 100 // len(_hosts)
        _logger.info(f"{host_type:<12}| "
                     f"{len(_hosts):>5}| "
                     f"{free:>5}| "
                     f"{schedule_percent:>8}%| "
                     f"{two_weeks_availability_count:>7}| "
                     f"{four_weeks_availability_count:>7}")