def __init__(self) -> None:
    try:
      with open("config.json") as configFile:
        config = json.load(configFile)
        self.username = os.environ['AMZNFLEXUSERNAME']
        self.password = os.environ["AMZNFLEXPWD"]
        self.desiredWarehouses = config["desiredWarehouses"] if len(config["desiredWarehouses"]) >= 1 else None  # list of warehouse ids
        self.minBlockRate = config["minBlockRate"]
        self.arrivalBuffer = config["arrivalBuffer"]
        self.desiredStartHour = config["desiredStartHour"]  # start hour in military time
        self.desiredEndHour = config["desiredEndHour"]  # end hour in military time
        self.retryLimit = config["retryLimit"]  # number of jobs retrieval requests to perform
        self.twilioFromNumber = config["twilioFromNumber"]
        self.twilioToNumber = config["twilioToNumber"]
        self.__retryCount = 0
        self.__acceptedOffers = []
        self.__startTimestamp = time.time()
        self.__requestHeaders = FlexUnlimited.allHeaders.get("FlexCapacityRequest")
        self.__requestHeaders["x-amz-access-token"] = self.__getFlexRequestAuthToken()

        twilioAcctSid = config["twilioAcctSid"]
        twilioAuthToken = config["twilioAuthToken"]

        if twilioAcctSid != "" and twilioAuthToken != "" and self.twilioFromNumber != "" and self.twilioToNumber != "":
          self.twilioClient = Client(twilioAcctSid, twilioAuthToken)
        else:
          self.twilioClient = None
    except KeyError as nullKey:
      Log.error(f'{nullKey} was not set. Please setup FlexUnlimited as described in the README.')
      sys.exit()
    except FileNotFoundError:
      Log.error("Config file not found. Ensure a properly formatted 'config.json' file exists in the root directory.")
      sys.exit()
  def __acceptOffer(self, offer: Offer):
    self.__requestHeaders["X-Amz-Date"] = self.__getAmzDate()

    request = requests.post(
      FlexUnlimited.routes.get("AcceptOffer"),
      headers=self.__requestHeaders,
      json={"offerId": offer.id})

    if request.status_code == 200:
      self.__acceptedOffers.append(offer)
      if self.twilioClient is not None:
        self.twilioClient.messages.create(
          to=self.twilioToNumber,
          from_=self.twilioFromNumber,
          body=offer.toString())
      Log.info(f"Successfully accepted offer {offer.id}")
    else:
      Log.error(f"Unable to accept offer {offer.id}. Request returned status code {request.status_code}")
 def __getFlexRequestAuthToken(self) -> str:
   """
       Get authorization token for Flex Capacity requests
       Returns:
       An access token as a string
       """
   payload = {
     "requested_extensions": ["device_info", "customer_info"],
     "cookies": {
       "website_cookies": [],
       "domain": ".amazon.com"
     },
     "registration_data": {
       "domain": "Device",
       "app_version": "0.0",
       "device_type": "A3NWHXTQ4EBCZS",
       "os_version": "15.2",
       "device_serial": "B262D48AC3EA4671B288C20F406821B5",
       "device_model": "iPhone",
       "app_name": "Amazon Flex",
       "software_version": "1"
     },
     "auth_data": {
       "user_id_password": {
         "user_id": self.username,
         "password": self.password
       }
     },
     "user_context_map": {
       "frc": "AFgQ07+f4rZ1HkMDmsLeD9GlOFoIa9auy7p03s6CSDsZFiskgDYWhSIQyD7S8EUxSMGAGs1gf0e"
              "\/wlmnvGBZ2Jh7YkvVfXENXnwoQ12acgHysONHR\/oBMWPwNOBg+qY88UlNQ1RXNOv9fgMDJPjr5gvZJs3S5RY9RyAMg7H"
              "\/sSIEJ9j+TXIE+xnMZrT1lOpEMdQJHV53+pgcJEG2SB4kt8OraJqoZCt7A\/lyWO9RAL1gWlnhEHyEd3"
              "\/\/t8TNQBKXbjO2G9iFUQs\/s0VqVSchIVzOzT\/BRpe36iFW7XnbGU0N9Q5Y40m+M"
              "\/kxySQ3h5YWs9kl1PuLGTx3ql1ttSf7nSHLGj342KZJtK3oOjCxVrsjteGRyekpKe6Jagrssjq1QOVNIyRmU428fdl"
              "\/lWILDAnSFSMZNiOzzQ=="},
     "requested_token_type": ["bearer", "mac_dms", "website_cookies"]
   }
   try:
     response = requests.post(FlexUnlimited.routes.get("GetAuthToken"),
                              headers=FlexUnlimited.allHeaders.get("AmazonApiRequest"), json=payload).json()
     return response.get("response").get("success").get("tokens").get("bearer").get("access_token")
   except Exception as e:
     Log.error("Unable to authenticate to Amazon Flex. Please provide a valid Amazon Flex username and password.")
     sys.exit()
  def run(self):
    Log.info("Starting job search...")
    while self.__retryCount < self.retryLimit:
      if not self.__retryCount % 50:
        print(self.__retryCount, 'requests attempted\n\n')

      offersResponse = self.__getOffers()
      if offersResponse.status_code == 200:
        currentOffers = offersResponse.json().get("offerList")
        currentOffers.sort(key=lambda pay: int(pay['rateInfo']['priceAmount']),
                           reverse=True)
        for offer in currentOffers:
          offerResponseObject = Offer(offerResponseObject=offer)
          self.__processOffer(offerResponseObject)
        self.__retryCount += 1
      else:
        Log.error(offersResponse.json())
        break
    Log.info("Job search cycle ending...")
    Log.info(f"Accepted {len(self.__acceptedOffers)} offers in {time.time() - self.__startTimestamp} seconds")
Exemple #5
0
class ZenStatus(IZen, Client):

	down = []

	hosts = {}

	log = None

	def __init__(self):
		zen = ConfUtil.zen()

		conf = ConfUtil.zen(__file__)

		conf['localhost'] = zen['localhost']

		self.conf = conf

		daemon = Util.filename(__file__)

		self.log = Log(daemon)

		Client.__init__(self, daemon, self.log)

	def mail(self, host, success):
		status = 'up' if success else 'down'

		mail = DictUtil.copy(self.conf['mail'])

		mail['subject'] %= status.upper()
		mail['body'] %= host

		debug = DebugUtil.mail(self.conf['localhost']['name'], mail)

		if Mail.sendraw(mail):
			self.log.info('Mail sent %s' % debug)
		else:
			self.log.critical('Mail not sent %s' % debug)

	def start(self, ip):
		up = False

		host = Util.hostname(ip)

		for _ in range(self.conf['start']['retries']):
			if 'backup' in self.hosts[host] and self.hosts[host]['backup']:
				up = True

				break

			cmd = ['ssh', ip, 'service', 'serviced', 'start']

			check_call(cmd, stderr=PIPE)

			cmd = ['ssh', ip, 'service', 'serviced', 'status']

			output = check_output(cmd, stderr=PIPE)

			if 'running' not in output:
				sleep(self.conf['start']['timeout'])

				continue

			cmd = ['ssh', ip, 'serviced', 'service', 'start', 'Zenoss.core']

			output = check_output(cmd)

			if 'started' not in output:
				sleep(self.conf['start']['timeout'])

				continue

			up = True

			break

		if host in self.down:
			if up:
				self.mail(host, True)

				self.down.remove(host)
		else:
			if not up:
				self.mail(host, False)

				self.down.append(host)

		return up

	def status(self):
		_hosts = self.hosts.keys()

		hosts = {h: {} for h in _hosts}

		for host in sorted(_hosts):
			if not self.hosts[host]['ping']:
				hosts[host]['status'] = False

				self.log.error(host)

				continue

			if self.start(self.hosts[host]['ip']):
				hosts[host]['status'] = True

				self.log.success(host)
			else:
				hosts[host]['status'] = False

				self.log.error(host)

		d = {'hosts': hosts}

		self.send(d)

	def run(self):
		try:
			worker = None

			self.log.clear()

			while True:
				packet = self.recv()

				self.hosts = packet['hosts']

				if worker is not None and worker.is_alive():
					continue

				self.log.clear()

				worker = Thread(target=self.status)

				worker.start()
		except KeyboardInterrupt:
			pass
Exemple #6
0
class ZenPing(IZen, Client):

	hosts = {}

	mails = {
		'up'	: [],
		'down'	: []
	}

	down = []

	log = None

	@staticmethod
	def ping(ip):
		try:
			cmd = ['ping', '-c', '1', '-w', '1', '-q', ip]

			output = check_output(cmd)

			return ' 0% packet loss' in output
		except CalledProcessError:
			return False

	def __init__(self):
		zen = ConfUtil.zen()

		conf = ConfUtil.zen(__file__)

		conf['localhost'] = zen['localhost']

		self.conf = conf

		daemon = Util.filename(__file__)

		self.log = Log(daemon)

		Client.__init__(self, daemon, self.log)

	def mail(self, up):
		status = 'up' if up else 'down'

		mail = DictUtil.copy(self.conf['mail'])

		mail['subject'] %= status.upper()

		body = self.mails[status].pop()

		if len(self.mails[status]) > 0:
			hosts = ', '.join(self.mails[status])

			body = '%s & %s' % (hosts, body)

		mail['body'] %= body

		debug = DebugUtil.mail(self.conf['localhost']['name'], mail)

		if Mail.sendraw(mail):
			self.log.info('Mail sent %s' % debug)
		else:
			self.log.critical('Mail not sent %s' % debug)

	def run(self):
		try:
			self.log.clear()

			packet = self.recv()

			self.hosts = packet['hosts']

			hosts = {h: {} for h in self.hosts.keys()}

			while True:
				for host in sorted(self.hosts):
					if ZenPing.ping(self.hosts[host]['ip']):
						if host in self.down:
							self.down.remove(host)

							self.mails['up'].append(host)

						hosts[host]['ping'] = True

						self.log.success(host)
					else:
						if host not in self.down:
							self.down.append(host)

							self.mails['down'].append(host)

						hosts[host]['ping'] = False

						self.log.error(host)

				if len(self.mails['down']) > 0:
					self.mail(False)

					self.mails['down'] = []

				if len(self.mails['up']) > 0:
					self.mail(True)

					self.mails['up'] = []

				d = {'hosts': hosts}

				self.send(d)

				sleep(self.conf['sleep'])

				self.log.clear()
		except KeyboardInterrupt:
			pass