Example #1
0
    def __init__(self, channel, jobName, parameters):

        self.slackConfig = SlackConfig()

        logging.basicConfig(
            filename='slack_jenkins.log',
            level=logging.INFO,
            format=
            '%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s',
            datefmt="%Y-%m-%d %H:%M:%S")  #INFO,WARNING

        self.app = Flask(__name__)
        self.slackDB = SlackDB(self.app)

        self.jobName = jobName
        self.parameters = parameters
        self.SLACK_BOT_TOKEN = self.slackConfig.get("SLACK_BOT_TOKEN")
        self.jenkinsUrl = self.slackConfig.get("jenkins_url")
        self.jenkinsUsername = self.slackConfig.get("jenkins_username")
        self.jenkinsPassword = self.slackConfig.get("jenkins_password")
        self.jenkinsWaitTries = self.slackConfig.get("jenkins_waitTries")

        self.server = jenkins.Jenkins(self.jenkinsUrl,
                                      username=self.jenkinsUsername,
                                      password=self.jenkinsPassword)

        self.slack_client = SlackClient(self.SLACK_BOT_TOKEN)
        self.channel = channel

        self.__renderParameter()

        self.parentUpstreamBuild = 0
Example #2
0
    def __init__(self, app, action, formJson, service, env):
        self.app = app

        logging.basicConfig(
            filename='restart.log',
            level=logging.INFO,
            format=
            '%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s',
            datefmt="%Y-%m-%d %H:%M:%S")  #INFO,WARNING

        self.slackConfig = SlackConfig()
        self.SLACK_BOT_TOKEN = self.slackConfig.get("SLACK_BOT_TOKEN")
        self.slack_client = SlackClient(self.SLACK_BOT_TOKEN)

        self.slack = Slack(self.app)
        self.auth = Auth(self.app)
        self.slackDB = SlackDB(self.app)

        self.formJson = formJson
        self.user = formJson["user"]["name"]
        self.channel = formJson["channel"]["name"]
        self.channelId = formJson["channel"]["id"]
        self.action = action
        self.service = service
        self.env = env

        self.headers = {
            'content-type': 'application/json',
        }

        if (not action == ""):
            function = "self." + action.encode('utf-8') + "()"
            output = eval(function)
Example #3
0
    def __init__(self, app):
        self.app = app
        self.headers = {
            'content-type': 'application/json',
        }

        slackConfig = SlackConfig()
        self.SLACK_BOT_TOKEN = slackConfig.get("SLACK_BOT_TOKEN")
        self.slack_client = SlackClient(self.SLACK_BOT_TOKEN)
Example #4
0
    def __init__(self,
                 app,
                 action,
                 formJson,
                 stage,
                 env,
                 version,
                 buildName=""):

        if (app == None):
            self.app = Flask(__name__)
        else:
            self.app = app

        logging.basicConfig(
            filename='teletraan.log',
            level=logging.INFO,
            format=
            '%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s',
            datefmt="%Y-%m-%d %H:%M:%S")  #INFO,WARNING

        self.maxDisplayAgents = 100
        self.slackConfig = SlackConfig()

        self.slack = Slack(self.app)
        self.auth = Auth(self.app)
        self.slackDB = SlackDB(self.app)

        self.formJson = formJson
        if (not self.formJson == {}):
            self.user = formJson["user"]["name"]
            self.channel = formJson["channel"]["name"]
            self.channelId = formJson["channel"]["id"]

        self.action = action

        self.stage = stage
        self.env = env
        self.version = version
        self.buildName = buildName

        self.SLACK_BOT_TOKEN = self.slackConfig.get("SLACK_BOT_TOKEN")
        self.slack_client = SlackClient(self.SLACK_BOT_TOKEN)
        self.teletraanUrl = self.slackConfig.get("teletraan_url")

        self.headers = {
            'content-type': 'application/json',
        }

        if (not action == ""):
            function = "self." + action.encode('utf-8') + "()"
            output = eval(function)
Example #5
0
class SlackJenkins(object):
    def __init__(self, channel, jobName, parameters):

        self.slackConfig = SlackConfig()

        logging.basicConfig(
            filename='slack_jenkins.log',
            level=logging.INFO,
            format=
            '%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s',
            datefmt="%Y-%m-%d %H:%M:%S")  #INFO,WARNING

        self.app = Flask(__name__)
        self.slackDB = SlackDB(self.app)

        self.jobName = jobName
        self.parameters = parameters
        self.SLACK_BOT_TOKEN = self.slackConfig.get("SLACK_BOT_TOKEN")
        self.jenkinsUrl = self.slackConfig.get("jenkins_url")
        self.jenkinsUsername = self.slackConfig.get("jenkins_username")
        self.jenkinsPassword = self.slackConfig.get("jenkins_password")
        self.jenkinsWaitTries = self.slackConfig.get("jenkins_waitTries")

        self.server = jenkins.Jenkins(self.jenkinsUrl,
                                      username=self.jenkinsUsername,
                                      password=self.jenkinsPassword)

        self.slack_client = SlackClient(self.SLACK_BOT_TOKEN)
        self.channel = channel

        self.__renderParameter()

        self.parentUpstreamBuild = 0
        #last_build_number = self.server.get_job_info(jobName)['lastBuild']['number']
        #print self.server.get_build_info(jobName,61,1)["result"]
        #print self.server.get_build_info(jobName,61,1)["actions"][1]['causes'][0]['upstreamBuild']
        #sys.exit()

    def __renderParameter(self):

        buildParameters = []
        for key, value in self.parameters.items():
            buildParameters.append({"name": key, "value": value})

        self.parameters = buildParameters

    def __slackPost(self, text, type="default"):

        if (type == "default"):
            color = "#7CD197"
        elif (type == "alert"):
            color = "#F35A00"

        attachments = [{
            "color": color,
            "attachment_type": "default",
            "mrkdwn_in": ["text", "title"],
            "text": text
        }]

        response = self.slack_client.api_call("chat.postMessage",
                                              channel=self.channel,
                                              mrkdwn=True,
                                              attachments=attachments)

    def __getupstreamBuild(self, jobName):

        buildNumber = self.server.get_job_info(jobName)['lastBuild']['number']
        buildInfo = self.server.get_build_info(jobName, buildNumber, 1)

        if ("actions" in buildInfo):

            for buildAction in buildInfo["actions"]:
                if ("causes" in buildAction):
                    for buildCauses in buildAction["causes"]:
                        if ("upstreamBuild" in buildCauses):
                            logging.info("__getupstreamBuild={}".format(
                                buildCauses["upstreamBuild"]))
                            return (buildCauses["upstreamBuild"])

        return (0)

    def __waitForTriggeredBuild(self, jobName):

        tries = 0
        while True:

            triggeredBuildNumber = self.server.get_job_info(
                jobName)['lastBuild']['number']

            if (self.parentUpstreamBuild > 0 and triggeredBuildNumber > 0):

                upstreamBuild = self.__getupstreamBuild(jobName)

                logging.info("upstreamBuild={}".format(upstreamBuild))
                if (upstreamBuild == self.parentUpstreamBuild):
                    logging.info(
                        "triggeredBuildNumber={}".format(triggeredBuildNumber))
                    return (triggeredBuildNumber)
            time.sleep(2)
            tries += 1
            if (tries > 20):
                return (0)

    def __getJobOutput(self, jobName, triggeredBuildNumber=0):

        self.__slackPost("Waiting for jenkins job `" + jobName + "`....",
                         "default")
        logging.info("__getJobOutput:{} {}".format(jobName,
                                                   triggeredBuildNumber))
        if (not triggeredBuildNumber > 0):
            triggeredBuildNumber = self.__getBuildNumber(jobName)

        #wait for job
        #self.__slackPost( "Waiting for jenkins job `" + jobName + "`...." ,"default")
        self.__getBuildHistory(triggeredBuildNumber, jobName)
        time.sleep(2)

        #reconnect to jenkins
        self.server = None
        gc.collect()
        self.server = jenkins.Jenkins(self.jenkinsUrl,
                                      username=self.jenkinsUsername,
                                      password=self.jenkinsPassword)
        jobInfo = self.server.get_job_info(jobName)

        logging.info("jobname: {} getting build info {}".format(
            jobName, triggeredBuildNumber))

        tries = 0
        while True:
            lastBuildNumber = self.server.get_job_info(
                jobName)['lastBuild']['number']
            logging.info(
                "jobname: {} , tries: {} , last build: {} nextBuildNumber: {}".
                format(jobName, tries, lastBuildNumber, triggeredBuildNumber))

            if (lastBuildNumber < triggeredBuildNumber):
                tries += 1
                time.sleep(2)
            else:
                break

            if (tries >= self.jenkinsWaitTries):
                self.__slackPost("Error: could not find jenkins job", "alert")
                return ("")

        tries = 0
        while self.server.get_build_info(jobName, triggeredBuildNumber,
                                         1)["building"] == True:
            tries += 1
            time.sleep(2)
            if (tries >= self.jenkinsWaitTries):
                self.__slackPost("Error: timeout waiting for jenkins job",
                                 "alert")
                return ("")

            if (tries > 1 and tries % 30 == 0):
                self.__slackPost("Still waiting for jenkins job to finish ...")

        self.parentUpstreamBuild = triggeredBuildNumber
        time.sleep(2)
        logging.info("jobname: {} , job output finished {}".format(
            jobName, triggeredBuildNumber))
        return (self.server.get_build_console_output(jobName,
                                                     triggeredBuildNumber))

    def getJobStatus(self, buildNumber):

        self.output = self.__getJobOutput(self.jobName, buildNumber)
        triggeredJob = ""
        jobName = self.jobName
        jobStatus = 0

        while True:

            if ("Finished: SUCCESS" in self.output):
                self.__slackPost(
                    "@channel *build " + jobName + " finished: `SUCCESS`*",
                    "default")
                jobStatus = 0

            if ("Finished: FAILURE" in self.output):
                self.__slackPost(
                    "@channel *build " + jobName + " finished: `FAILURE`*",
                    "alert")
                jobStatus = 1

            if ("Triggering a new build of" in self.output):
                pos1 = self.output.index("Triggering a new build of")
                triggeredJob = self.output[pos1 +
                                           len("Triggering a new build of") +
                                           1:]
                pos2 = triggeredJob.index("\n")
                triggeredJob = triggeredJob[:pos2]
                jobName = triggeredJob

                self.__slackPost(
                    "Build *" + jobName + "* triggering a new build of *" +
                    triggeredJob + "*", "default")
                triggeredBuildNumber = self.__waitForTriggeredBuild(jobName)
                self.output = self.__getJobOutput(triggeredJob,
                                                  triggeredBuildNumber)

            else:
                triggeredJob = ""

            if (triggeredJob == ""):
                break

        return (jobStatus)

    def __getBuildHistory(self, nextBuildNumber, jobName):

        if (nextBuildNumber > 1):
            buildInfo = self.server.get_build_info(jobName,
                                                   nextBuildNumber - 1, 1)
            duration = float(buildInfo["duration"]) / 60000

            if (buildInfo["result"] == "SUCCESS"):
                if (float(duration) < 1):
                    self.__slackPost(
                        "Last task duration was {} seconds".format(
                            int(60 * duration)), "default")
                else:
                    minutes = int(duration)
                    seconds = duration - minutes
                    seconds = int(seconds * 60)
                    self.__slackPost(
                        "Last task duration was {} minutes {} seconds".format(
                            minutes, seconds), "default")

    def __getBuildNumber(self, jobName):
        return (self.server.get_job_info(jobName)['nextBuildNumber'])

    def displayJobOutput(self):
        self.output = self.__getJobOutput(self.jobName)
        print self.output

        return
        startDisplay = False
        for line in self.output.split("\n"):

            if (startDisplay == True and not line[0:1] == "+"):
                print "`" + line + "`"

            if (line.find("[workspace]") > -1):
                startDisplay = True

    def buildJob(self):

        self.nextBuildNumber = self.server.get_job_info(
            self.jobName)['nextBuildNumber']

        url = "{}/job/{}/build/api/json".format(self.jenkinsUrl, self.jobName)

        data = {"json": json.dumps({"parameter": self.parameters})}
        result = requests.post(url,
                               auth=(self.jenkinsUsername,
                                     self.jenkinsPassword),
                               data=data)

        if (not result.status_code == 201 and not result.status_code == 200):
            self.__slackPost(
                "Failed to trigger Build *{}* error {}".format(
                    self.jobName, result.status_code), "alert")
            return (1)

        self.parentUpstreamBuild = self.nextBuildNumber
        return (self.nextBuildNumber)
Example #6
0
from slackclient import SlackClient
import json
import sys
import os,subprocess,time
import re
import pickle
import utils
import functions
from slack import Slack
from auth import Auth
from slack_db import SlackDB
from threading import Thread
from slack_config import SlackConfig


slackConfig=SlackConfig()
SLACK_BOT_TOKEN = slackConfig.get("SLACK_BOT_TOKEN")
rootMenuUrl=slackConfig.get("root_menu_url")

# Slack client for Web API requests
slack_client = SlackClient(SLACK_BOT_TOKEN)

# Flask webserver for incoming traffic from Slack
app = Flask(__name__)
homeDir=os.path.dirname(os.path.realpath(__file__))

mainMenu="main"


class SlackMenu(object):
Example #7
0
#!/usr/bin/python

import jenkins
import sys
import time
import consul
import boto3

from slack_config import SlackConfig
from slackclient import SlackClient
import utils


consulUrls={ "like": "consul-like.matomy.local" , "prod": "consul.matomy.local" }

slackConfig=SlackConfig()
SLACK_BOT_TOKEN = slackConfig.get("SLACK_BOT_TOKEN")
slack_client = SlackClient(SLACK_BOT_TOKEN)

class EcsStatus(object):

    def __init__(self,env,formJson):

        self.awsAccessKeyId = ""
        self.awsSecretAccessKey = ""
        self.env=env
        self.__getAwsKeys()
        self.ecsClient = boto3.client('ecs',region_name="us-east-1", aws_access_key_id=self.awsAccessKeyId, aws_secret_access_key=self.awsSecretAccessKey)
        self.ec2Client = boto3.client('ec2',region_name="us-east-1", aws_access_key_id=self.awsAccessKeyId, aws_secret_access_key=self.awsSecretAccessKey)
        self.ec2Resource = boto3.resource('ec2',region_name="us-east-1", aws_access_key_id=self.awsAccessKeyId, aws_secret_access_key=self.awsSecretAccessKey)
Example #8
0
class Restart(object):
    def __init__(self, app, action, formJson, service, env):
        self.app = app

        logging.basicConfig(
            filename='restart.log',
            level=logging.INFO,
            format=
            '%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s',
            datefmt="%Y-%m-%d %H:%M:%S")  #INFO,WARNING

        self.slackConfig = SlackConfig()
        self.SLACK_BOT_TOKEN = self.slackConfig.get("SLACK_BOT_TOKEN")
        self.slack_client = SlackClient(self.SLACK_BOT_TOKEN)

        self.slack = Slack(self.app)
        self.auth = Auth(self.app)
        self.slackDB = SlackDB(self.app)

        self.formJson = formJson
        self.user = formJson["user"]["name"]
        self.channel = formJson["channel"]["name"]
        self.channelId = formJson["channel"]["id"]
        self.action = action
        self.service = service
        self.env = env

        self.headers = {
            'content-type': 'application/json',
        }

        if (not action == ""):
            function = "self." + action.encode('utf-8') + "()"
            output = eval(function)

    def __slackPost(self, text, title="", type="default", update=False, ts=0):

        if (type == "default"):
            color = "#7CD197"
        elif (type == "alert"):
            color = "#F35A00"

        if (text.find("*") == -1):
            if (text.find("http") == -1):
                text = "*" + text + "*"
            else:
                text = "*" + text
                text = text.replace("http", '* http')

        attachments = [{
            "color": color,
            "attachment_type": "default",
            "mrkdwn_in": ["text", "title"],
            "title": title,
            "text": text
        }]

        if (update == True and not ts == 0):
            response = self.slack_client.api_call("chat.update",
                                                  ts=ts,
                                                  channel=self.channelId,
                                                  mrkdwn=True,
                                                  attachments=attachments)

        else:
            response = self.slack_client.api_call("chat.postMessage",
                                                  channel=self.channelId,
                                                  mrkdwn=True,
                                                  attachments=attachments)

        return (response)

    def __ecsRestart(self, env, service):

        parameters = {
            "Cluster_name": "RtbMicroservices",
            "profile": env,
            "Service_name": service
        }
        slackJenkins = SlackJenkins(self.channel,
                                    "Microservice_restart_service", parameters)
        slackJenkins.buildJob()
        jobStatus = slackJenkins.getJobStatus()

    def clearHistory(self):
        logging.info("Clearing menu history")

        if (os.path.isfile("menu/restart_services_services.db")):
            os.remove("menu/restart_services_services.db")

        if (os.path.isfile("menu/restart_env_envs.db")):
            os.remove("menu/restart_env_envs.db")

    def restart(self):
        logging.info("restart {} {}".format(self.service, self.env))
        self.__slackPost("@{} restarting {} , environment ,{}".format(
            self.user, self.service, self.env))
        servicesMap = utils.readJson("services_map.json")
        teletraanServices = ""

        services = self.service.split(",")
        for service in services:
            for serviceMap in servicesMap["services"]:

                if (service.lower() == serviceMap["name"]):
                    if (self.env in serviceMap
                            and len(serviceMap[self.env]) > 0):

                        if (serviceMap["type"] == "teletraan"):
                            if (self.env in serviceMap):
                                for envs in serviceMap[self.env]:
                                    if ("envs" in envs):
                                        for env in envs["envs"].split(","):
                                            (output, status) = utils.runCmd(
                                                "./teletraan.py restart \"{}\" {} {} {}"
                                                .format(
                                                    self.formJson, env,
                                                    service.lower(),
                                                    "restart"))
                            else:
                                (output, status) = utils.runCmd(
                                    "./teletraan.py restart \"{}\" {} {} {}".
                                    format(self.formJson, self.env,
                                           service.lower(), "restart"))

                    elif (serviceMap["type"] == "ecs"):
                        self.__ecsRestart(self.env, service)

        self.clearHistory()
        self.__slackPost("@{} restart of {} , environment ,{} finished".format(
            self.user, self.service, self.env))
Example #9
0
class Teletraan(object):
    def __init__(self,
                 app,
                 action,
                 formJson,
                 stage,
                 env,
                 version,
                 buildName=""):

        if (app == None):
            self.app = Flask(__name__)
        else:
            self.app = app

        logging.basicConfig(
            filename='teletraan.log',
            level=logging.INFO,
            format=
            '%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s',
            datefmt="%Y-%m-%d %H:%M:%S")  #INFO,WARNING

        self.maxDisplayAgents = 100
        self.slackConfig = SlackConfig()

        self.slack = Slack(self.app)
        self.auth = Auth(self.app)
        self.slackDB = SlackDB(self.app)

        self.formJson = formJson
        if (not self.formJson == {}):
            self.user = formJson["user"]["name"]
            self.channel = formJson["channel"]["name"]
            self.channelId = formJson["channel"]["id"]

        self.action = action

        self.stage = stage
        self.env = env
        self.version = version
        self.buildName = buildName

        self.SLACK_BOT_TOKEN = self.slackConfig.get("SLACK_BOT_TOKEN")
        self.slack_client = SlackClient(self.SLACK_BOT_TOKEN)
        self.teletraanUrl = self.slackConfig.get("teletraan_url")

        self.headers = {
            'content-type': 'application/json',
        }

        if (not action == ""):
            function = "self." + action.encode('utf-8') + "()"
            output = eval(function)

    def __loadVars(self):

        self.feature = self.slackDB.get("feature")
        self.plan = self.slackDB.get("plan")
        self.qa_approved = self.slackDB.get('qa_approved')
        self.release_manager_approved = self.slackDB.get(
            'release_manager_approved')
        self.original_user = self.slackDB.get('original_user')
        self.finished = self.slackDB.get('finished')
        self.started = self.slackDB.get('started')
        self.email = self.slackDB.get('email')

        #admin
        self.admin_started = self.slackDB.get('admin_started')
        self.admin_finished = self.slackDB.get('admin_finished')
        self.bluetogreen = self.slackDB.get('bluetogreen')
        self.sanitypass = self.slackDB.get('sanitypass')

        #ecs
        self.ecs_started = self.slackDB.get('ecs_started')
        self.ecs_finished = self.slackDB.get('ecs_finished')
        self.ecs_sanitypass = self.slackDB.get('ecs_sanitypass')

    def __slackPostStatus(self,
                          success,
                          failed,
                          total,
                          acceptanceStatus,
                          title="",
                          ts=0):

        fields = []
        fields.append({
            "title": "Success",
            "value": str(success),
            "short": True
        })
        fields.append({"title": "Failed", "value": str(failed), "short": True})
        fields.append({
            "title": "Status",
            "value": acceptanceStatus,
            "short": True
        })
        fields.append({"title": "Total", "value": str(total), "short": True})

        color = "#7CD197"
        attachments = [{
            "color": color,
            "attachment_type": "default",
            "text": "",
            "title": title,
            "unfurl_media": False,
            "short": True,
            "mrkdwn_in": ["text", "title"],
            "fields": fields
        }]

        if (ts > 0):
            chat = "chat.update"
        else:
            chat = "chat.postMessage"

        response = self.slack_client.api_call(chat,
                                              channel=self.channelId,
                                              mrkdwn=True,
                                              attachments=attachments,
                                              ts=ts)

        #logging.info("_slackPostStatus: {}".format(response))
        return (response)

    def __slackPost(self, text, title="", type="default", update=False, ts=0):

        if (type == "default"):
            color = "#7CD197"
        elif (type == "alert"):
            color = "#F35A00"

        if (text.find("*") == -1):
            if (text.find("http") == -1):
                text = "*" + text + "*"
            else:
                text = "*" + text
                text = text.replace("http", '* http')

        attachments = [{
            "color": color,
            "attachment_type": "default",
            "mrkdwn_in": ["text", "title"],
            "title": title,
            "text": text
        }]

        if (update == True and not ts == 0):
            response = self.slack_client.api_call("chat.update",
                                                  ts=ts,
                                                  channel=self.channelId,
                                                  mrkdwn=True,
                                                  attachments=attachments)

        else:
            response = self.slack_client.api_call("chat.postMessage",
                                                  channel=self.channelId,
                                                  mrkdwn=True,
                                                  attachments=attachments)

        return (response)

    def restart(self):

        self.app.logger.debug("restarting {},{}".format(self.stage, self.env))
        self.__slackPost("restarting teletraan {},{}".format(
            self.stage, self.env))

        url = "{}/v1/envs/{}/{}/deploys/current/actions?actionType=RESTART".format(
            self.teletraanUrl, self.env, self.stage)
        result = requests.post(url, headers=self.headers)
        resultJson = result.json()
        if ("code" in resultJson and not resultJson["code"] == 200):
            self.__slackPost("<@{}> Teletraan restart failed: `{}` ".format(
                self.user, resultJson["message"]),
                             type="alert")
            return (1)

        self.deployId = resultJson["id"]
        self.getDeployStatus()

    def getStages(self):

        stages = []
        url = self.teletraanUrl + "/v1/envs?envName=" + self.env
        result = requests.get(url, headers=self.headers)
        resultJson = result.json()

        self.app.logger.debug(resultJson)

        for env in resultJson:
            if ("stageName" in env):
                self.app.logger.debug(env["stageName"])
                stages.append({
                    "value": env["stageName"],
                    "text": env["stageName"],
                    "label": env["stageName"]
                })

        return (stages)

    def getBuilds(self):

        url = self.teletraanUrl + "/v1/builds/names"
        result = requests.get(url, headers=self.headers)
        resultJson = result.json()

        builds = []
        for build in resultJson:
            self.app.logger.debug(build)
            builds.append({"value": build, "text": build, "label": build})

        self.app.logger.debug(builds)
        return (builds)

    def getBuildVersions(self):

        url = self.teletraanUrl + "/v1/builds?name=" + self.env
        result = requests.get(url, headers=self.headers)
        resultJson = result.json()

        versions = []
        for build in resultJson:

            if (utils.daysCompare(build["commitDate"]) < 30):
                print build["branch"], utils.convertToDate(
                    build["commitDate"]), utils.convertDisplayTime(
                        build["commitDate"])

                self.app.logger.debug(build["branch"],
                                      utils.convertToDate(build["commitDate"]))

                value = build["branch"] + "-" + utils.convertDisplayTime(
                    build["commitDate"])
                versions.append({
                    "value": value,
                    "text": value,
                    "label": value
                })

        return (versions)

    def __getBuildId(self):

        if (self.buildName == ""):
            url = self.teletraanUrl + "/v1/builds?name=" + self.env
        else:
            url = self.teletraanUrl + "/v1/builds?name=" + self.buildName

        result = requests.get(url, headers=self.headers)
        resultJson = result.json()

        foundBuildId = ""
        latestTime = 0

        for build in resultJson:

            menuValue = ""
            branch = ""
            branchTime = 0

            if ("branch" in build):
                branch = os.path.basename(build["branch"])
                branchTime = utils.convertTime(build["commitDate"])
                menuValue = build["branch"] + "-" + utils.convertDisplayTime(
                    build["commitDate"])

            #find build id from menu
            if (menuValue == self.version):
                return (build["id"])

            #get last build id based on branch
            if (branch == self.version and branchTime >= latestTime):
                latestTime = branchTime
                foundBuildId = build["id"]

        return (foundBuildId)

    def deploy(self):

        self.buildId = self.__getBuildId()

        if (self.buildId == ""):
            self.__slackPost(
                "<@{}> Teletraan deployment didnt find build id for version `{}` {}"
                .format(self.user, self.version, self.env),
                type="alert")
            return

        payload = {'buildId': self.buildId}
        url = self.teletraanUrl + "/v1/envs/{}/{}/deploys?buildId={}".format(
            self.env, self.stage, self.buildId)

        result = requests.post(url,
                               data=json.dumps(payload),
                               headers=self.headers)
        resultJson = result.json()
        self.app.logger.debug(resultJson)

        if ("code" in resultJson and not resultJson["code"] == 200):
            self.__slackPost("<@{}> Teletraan deployment failed: `{}` ".format(
                self.user, resultJson["message"]),
                             type="alert")
            return (1)

        self.deployId = resultJson["id"]
        self.__slackPost("<@{}> deployment {} status `{}` ".format(
            self.user, self.version.replace("-", " "),
            resultJson["acceptanceStatus"]),
                         title=self.env + " " + self.stage + " deployment")
        deployStatus = self.getDeployStatus()

        return (deployStatus)

    def __getDeployState(self):

        url = self.teletraanUrl + "/v1/deploys/{}".format(self.deployId)
        result = requests.get(url, headers=self.headers)
        resultJson = result.json()
        #logging.info(resultJson)
        return (resultJson["state"], resultJson["successTotal"],
                resultJson["failTotal"], resultJson["acceptanceStatus"])

    def getDeployStatus(self):

        deployState = ""
        count = 0
        totalDeloyed = 0
        agentsCount = 1
        successTotal = 0
        failTotal = 0
        ts = 0
        deployStatus = 0
        agentsTs = {}
        acceptanceStatus = ""

        while (agentsCount > 0
               and not agentsCount == (successTotal + failTotal)):

            url = self.teletraanUrl + "/v1/envs/{}/{}/deploys/current/progress".format(
                self.env, self.stage)
            result = requests.put(url, headers=self.headers)
            resultJson = result.json()
            #logging.info(resultJson)

            #print self.env,self.stage,self.version.replace("-"," ")

            deployState, successTotal, failTotal, acceptanceStatus = self.__getDeployState(
            )

            if ("agents" in resultJson):

                agentsCount = len(resultJson["agents"])

                for agent in resultJson["agents"]:

                    if [agent["status"] == "SUCCEEDED"]:
                        msgType = "default"
                    else:
                        msgType = "alert"

                    if (agentsCount < self.maxDisplayAgents):

                        if (self.action == "restart"):
                            title = self.env + " " + self.stage + " agent restart"
                        else:
                            title = self.env + " " + self.stage + " agent deployment version {}".format(
                                self.version.replace("-", " "))

                        if (ts == 0):
                            response = self.__slackPostStatus(
                                successTotal, failTotal, agentsCount,
                                acceptanceStatus, title)
                        else:
                            response = self.__slackPostStatus(
                                successTotal, failTotal, agentsCount,
                                acceptanceStatus, title, ts)

                        logging.info("{} {} {} {}".format(
                            ts, successTotal, failTotal, agentsCount))

                        if ("ts" in response and "hostId" in agent):

                            ts = response["ts"]
                            logging.info("getting ts=" + response["ts"] +
                                         ",hostid=" + str(agent["hostId"]))

                            if (not agent["hostId"] in agentsTs):
                                agentsTs[agent["hostId"]] = ts

            logging.info(
                "**** deployState {},agentsCount {},successTotal {},failTotal {}"
                .format(deployState, agentsCount, successTotal, failTotal))

            time.sleep(5)

        if (failTotal > 0):
            msgType = "alert"
            deployStatus = 1
            deployIcon = ":x:"
        else:
            msgType = "default"
            deployIcon = ":white_check_mark:"

        if (self.action == "restart"):
            action = "Restart"

        else:
            action = "Deployment"

        self.__slackPost(
            "<@{}> Success: `{}` Failed: `{}` ".format(self.user, successTotal,
                                                       failTotal),
            title="{} {} {} {} finished {}".format(deployIcon, action,
                                                   self.env, self.stage,
                                                   deployState),
            type=msgType)

        return (deployStatus)