Example #1
0
def search_for_instances_in_instancepool():
    print("Checking for new instances.....")
    exo = exoscale.Exoscale(api_key=os.environ.get('EXOSCALE_KEY'),
                            api_secret=os.environ.get('EXOSCALE_SECRET'))
    zone_at = exo.compute.get_zone(os.environ.get('EXOSCALE_ZONE'))
    data = []

    for instance in exo.compute.list_instances(zone_at):

        #print(instance.instance_pool)

        if (instance.instance_pool is not None and instance.instance_pool.id
                == os.environ.get('EXOSCALE_INSTANCEPOOL_ID')):
            print("Found instance....")
            print("{name} {zone} {ip}".format(
                name=instance.name,
                zone=instance.zone.name,
                ip=instance.ipv4_address,
            ))
            data.append({
                'targets': [
                    "{ip}:{port}".format(ip=instance.ipv4_address,
                                         port=os.environ.get('TARGET_PORT'))
                ]
            })

    with open('/srv/service-discovery/config.json', 'w') as outfile:
        json.dump(data, outfile)
Example #2
0
def queryInstances(api_key, api_secret, exoscale_instancepool_id, target_port,
                   exoscale_zone):
    exo = exoscale.Exoscale(api_key=api_key, api_secret=api_secret)
    zone = exo.compute.get_zone(name=exoscale_zone)
    if not zone:
        pylogger.error("Invalid Zone -- cannot be empty")
        sys.exit(1)

    targetList = []
    for instance in exo.compute.list_instances(zone):
        try:
            instance_pool = instance.instance_pool
            if instance_pool and exoscale_instancepool_id == instance_pool.id:
                target = {
                    'targets': [instance.ipv4_address + ':' + target_port]
                }
                pylogger.info("Targets: {0}".format(target))
                targetList.append(target)
        except Exception:
            pylogger.error("Something went wrong", exc_info=True)

    pylogger.info("Write targets {0} into {1}".format(targetList,
                                                      service_config_file))
    with open(service_config_file, 'w') as outfile:
        pylogger.info(
            "Overwrite the config.json file with content: {0}".format(outfile))
        json.dump(targetList, outfile)
Example #3
0
def loop_service_discovery(key: str, secret: str, zone_name: str, pool_id: str,
                           port: int, file: str):
    global finished
    exo = exoscale.Exoscale(api_key=key, api_secret=secret, config_file="")

    zone = exo.compute.get_zone(zone_name)

    failed_sd = 0

    while not finished:
        if failed_sd > 10:
            raise Exception("Too many service discovery failures.")
        try:
            service_discovery(exo, zone, pool_id, port, file)
            failed_sd = 0
        except Exception as err:
            pprint.pprint(err)
            failed_sd = failed_sd + 1
        time.sleep(5)
Example #4
0
def exo():
    import exoscale
    import requests_mock

    class ExoscaleMock(exoscale.Exoscale):
        def __init__(self, exo):
            self.exo = exo

            self.mocker = requests_mock.Mocker()
            self.mocker.start()

            self.boto_stub = Stubber(exo.storage.boto)
            self.boto_stub.activate()

        @property
        def compute(self):
            return self.exo.compute

        @property
        def iam(self):
            return self.exo.iam

        @property
        def dns(self):
            return self.exo.dns

        @property
        def storage(self):
            return self.exo.storage

        def mock_post(self, zone, url, resp):
            self.mocker.post(
                urljoin("https://api-{}.exoscale.com/v2/".format(zone), url),
                json=resp,
            )

        def mock_put(self, zone, url, resp):
            self.mocker.put(
                urljoin("https://api-{}.exoscale.com/v2/".format(zone), url),
                json=resp,
            )

        def mock_delete(self, zone, url, resp):
            self.mocker.delete(
                urljoin("https://api-{}.exoscale.com/v2/".format(zone), url),
                json=resp,
            )

        # FIXME: this method shall be renamed into mock_get() once we've finished
        # transitioning to the Public API V2.
        def mock_get_v2(self, zone, url, resp):
            self.mocker.get(
                urljoin("https://api-{}.exoscale.com/v2/".format(zone), url),
                json=resp,
            )

        def mock_get(self, url, resp, **kwargs):
            self.mocker.get(urljoin(self.exo.compute.endpoint, url),
                            json=resp,
                            headers={"Content-Type": "application/json"},
                            **kwargs)

        def mock_list(self, list_command, results=[]):
            resources = {
                "listAffinityGroups": {
                    "res_key": "listaffinitygroupsresponse",
                    "res_type": "affinitygroup",
                },
                "listApiKeys": {
                    "res_key": "listapikeysreponse",
                    "res_type": "apikey",
                },
                "listDnsDomainRecords": {
                    "res_key": "listdnsdomainrecordsreponse",
                    "res_type": "records",
                },
                "listDnsDomains": {
                    "res_key": "listdnsdomainsreponse",
                    "res_type": "dnsdomain",
                },
                "listNetworks": {
                    "res_key": "listnetworksresponse",
                    "res_type": "network",
                },
                "listNics": {
                    "res_key": "listnicsresponse",
                    "res_type": "nic",
                },
                "listPublicIpAddresses": {
                    "res_key": "listpublicipaddressesresponse",
                    "res_type": "ipaddress",
                },
                "listSecurityGroups": {
                    "res_key": "listsecuritygroupsresponse",
                    "res_type": "securitygroups",
                },
                "listServiceOfferings": {
                    "res_key": "listserviceofferingsresponse",
                    "res_type": "serviceoffering",
                },
                "listSnapshots": {
                    "res_key": "listsnapshotsresponse",
                    "res_type": "snapshot",
                },
                "listSSHKeyPairs": {
                    "res_key": "listsshkeypairsresponse",
                    "res_type": "sshkeypair",
                },
                "listTemplates": {
                    "res_key": "listtemplatesresponse",
                    "res_type": "template",
                },
                "listVirtualMachines": {
                    "res_key": "listvirtualmachinesreponse",
                    "res_type": "virtualmachine",
                },
                "listVolumes": {
                    "res_key": "listvolumesresponse",
                    "res_type": "volume",
                },
                "listZones": {
                    "res_key": "listzonesresponse",
                    "res_type": "zone",
                },
            }

            if list_command not in resources:
                raise Exception(
                    "{} command not supported".format(list_command))

            self.mock_get(
                "?command={}".format(list_command),
                {
                    resources[list_command]["res_key"]: {
                        "count": len(results),
                        resources[list_command]["res_type"]: results,
                    }
                },
            )

        def mock_query_async_job_result(self, result=None):
            self.mock_get(
                "?command=queryAsyncJobResult",
                {
                    "queryasyncjobresultresponse": {
                        "jobresult": result if result else {
                            "success": True
                        },
                        "jobresultcode": 0,
                        "jobstatus": 1,
                    }
                },
            )

        def mock_get_operation(self, zone, op_id, ref_id, result=None):
            self.mocker.get(
                "https://api-{}.exoscale.com/v2/operation/{}".format(
                    zone, op_id),
                json=result if result else {
                    "id": op_id,
                    "state": "success",
                    "reference": {
                        "id": ref_id
                    },
                },
            )

    return ExoscaleMock(exoscale.Exoscale(api_key="test", api_secret="test"))
Example #5
0

def getInstances(exo, zone, poolId):
    try:
        return exo.compute.get_instance_pool(poolId, zone).instances
    except:
        return []


exoscale_key = os.getenv('EXOSCALE_KEY')
exoscale_secret = os.getenv('EXOSCALE_SECRET')
exoscale_zone = os.getenv('EXOSCALE_ZONE')
exoscale_instancepool_id = os.getenv('EXOSCALE_INSTANCEPOOL_ID')
target_port = os.getenv('TARGET_PORT')

exo = exoscale.Exoscale(api_key=exoscale_key, api_secret=exoscale_secret)

print("exoscale_zone (should be zone): " + exoscale_zone, flush=True)
zone = exo.compute.get_zone(name=exoscale_zone)

while True:
    vms = getInstances(exo, zone, exoscale_instancepool_id)
    ips = []
    for vm in vms:
        print(vm.ipv4_address, flush=True)
        ips.append(vm.ipv4_address + ":" + target_port)

    # need array to get right format
    jsonObj = []
    jsonObj.append({"targets": ips, "labels": {}})
Example #6
0
def exo():
    import exoscale

    return exoscale.Exoscale()
Example #7
0
        return instancePool.instances
    except:
        return list()


def signalHandler(signum, frame):
    sys.exit(0)


signal.signal(signal.SIGINT, signalHandler)
signal.signal(signal.SIGTERM, signalHandler)

apiKey = os.getenv('EXOSCALE_KEY')
apiSecret = os.getenv('EXOSCALE_SECRET')
zone = os.getenv('EXOSCALE_ZONE')
poolId = os.getenv('EXOSCALE_INSTANCEPOOL_ID')
targetPort = os.getenv('TARGET_PORT')

directory = '/srv/service-discovery'
filename = 'config.json'
pollingInterval = 15

exo = exoscale.Exoscale(api_key=apiKey, api_secret=apiSecret)
exoZone = exo.compute.get_zone(zone)

while True:
    runningInstances = getRunningInstances(exo, exoZone, poolId)
    jsonData = mapRunningInstancesToJSON(runningInstances, targetPort)
    printJSONObjectToFile(directory, filename, jsonData)
    time.sleep(pollingInterval)
Example #8
0
class SignalHandler:
    termSignal = False

    def __init__(self):
        signal.signal(signal.SIGTERM, self.exitProcess)

    def exitProcess(self):
        self.termSignal = True


handler = SignalHandler

while not handler.termSignal:
    # Get Exoscale instance
    exoscaleConnection = exoscale.Exoscale()
    exoscaleZone = exoscaleConnection.compute.get_zone(zone)

    instances = list(
        exoscaleConnection.compute.get_instance_pool(instancePoolId,
                                                     exoscaleZone).instances)
    instanceIPv4Addresses = list()

    for instance in instances:
        if instance.state == "running":
            instanceIPv4Addresses.append("\"" + instance.ipv4_address + ":" +
                                         str(targetPort) + "\"")

    # Write file for prometheus targets
    targetsFile = open("/prometheus/targets.json", "w")
    targetsFile.write("[{\"targets\": [" + (", ".join(instanceIPv4Addresses)) +
Example #9
0
import exoscale
from ssh2.session import Session
import os
import socket

exo = exoscale.Exoscale()


# connection to an instance via SSH and execute command
def exec_ssh_cmd(cmd, host):
    username = '******'

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host, 22))

    session = Session()
    session.handshake(sock)
    session.agent_auth(username)

    session = Session()
    session.userauth_publickey_fromfile(username, '~/.ssh/keys/exoscale')
    channel = session.open_session()
    channel.execute(cmd)

    size, data = channel.read()

    while size > 0:
        print(data)
        size, data = channel.read()
    channel.close()
    print("Exit status: %s" % channel.get_exit_status())
Example #10
0
import exoscale

if __name__ == "__main__":
    exo = exoscale.Exoscale(api_key="api-key-here",
                            api_secret="api-secret-here",
                            config_file="")

    zone = exo.compute.get_zone("zone-name-here")

    ip = exo.compute.get_instance_pool("instance-pool-id-here", zone=zone)
    ip.scale(ip.size + 1)
Example #11
0
import http.server
import socketserver
import os
import signal
from http import HTTPStatus

import exoscale

api_key = os.environ["EXOSCALE_KEY"]
api_secret = os.environ["EXOSCALE_SECRET"]
api_zone = os.environ["EXOSCALE_ZONE"]
instance_pool_id = os.environ["EXOSCALE_INSTANCEPOOL_ID"]
listen_port = int(os.environ["LISTEN_PORT"])

exo = exoscale.Exoscale(api_key=api_key, api_secret=api_secret, config_file="")
zone = exo.compute.get_zone(api_zone)


class WebhookHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        global exo
        global zone
        instance_pool = exo.compute.get_instance_pool(instance_pool_id,
                                                      zone=zone)
        if self.path == '/up':
            instance_pool.scale(instance_pool.size + 1)
            self.send_response(HTTPStatus.OK)
        elif self.path == '/down':
            if instance_pool.size > 1:
                instance_pool.scale(instance_pool.size - 1)
            self.send_response(HTTPStatus.OK)