Esempio n. 1
0
def handle_bulk_script_task(scriptpk, agentpks, args, timeout):
    script = Script.objects.get(pk=scriptpk)
    agents = Agent.objects.filter(pk__in=agentpks)

    agents_nats = [agent for agent in agents if agent.has_nats]
    agents_salt = [agent for agent in agents if not agent.has_nats]
    minions = [agent.salt_id for agent in agents_salt]

    if minions:
        Agent.salt_batch_async(
            minions=minions,
            func="win_agent.run_script",
            kwargs={
                "filepath": script.filepath,
                "filename": script.filename,
                "shell": script.shell,
                "timeout": timeout,
                "args": args,
                "bg": True
                if script.shell == "python" else False,  # salt bg script bug
            },
        )

    nats_data = {
        "func": "runscript",
        "timeout": timeout,
        "script_args": args,
        "payload": {
            "code": script.code,
            "shell": script.shell,
        },
    }
    for agent in agents_nats:
        asyncio.run(agent.nats_cmd(nats_data, wait=False))
Esempio n. 2
0
def handle_bulk_command_task(agentpks, cmd, shell, timeout):
    agents = Agent.objects.filter(pk__in=agentpks)

    agents_nats = [agent for agent in agents if agent.has_nats]
    agents_salt = [agent for agent in agents if not agent.has_nats]
    minions = [agent.salt_id for agent in agents_salt]

    if minions:
        Agent.salt_batch_async(
            minions=minions,
            func="cmd.run_bg",
            kwargs={
                "cmd": cmd,
                "shell": shell,
                "timeout": timeout,
            },
        )

    if agents_nats:
        nats_data = {
            "func": "rawcmd",
            "timeout": timeout,
            "payload": {
                "command": cmd,
                "shell": shell,
            },
        }
        for agent in agents_nats:
            asyncio.run(agent.nats_cmd(nats_data, wait=False))
Esempio n. 3
0
def add(request):
    data = request.data

    client = get_object_or_404(Client, pk=int(data["client"]))
    site = get_object_or_404(Site, pk=int(data["site"]))

    if not Agent.objects.filter(agent_id=data["agent_id"]).exists():
        agent = Agent(
            agent_id=data["agent_id"],
            hostname=data["hostname"],
            client=client.client,
            site=site.site,
            monitoring_type=data["monitoring_type"],
            description=data["description"],
            mesh_node_id=data["mesh_node_id"],
            last_seen=djangotime.now(),
        )

        agent.save()

        if agent.monitoring_type == "workstation":
            WinUpdatePolicy(agent=agent, run_time_days=[5, 6]).save()
        else:
            WinUpdatePolicy(agent=agent).save()

        return Response({"pk": agent.pk})
    else:
        return Response("err", status=status.HTTP_400_BAD_REQUEST)
Esempio n. 4
0
def get_all_agents_url():

    existing = [agent.url for agent in Agent.objects.all()]
    agents = []
    for c in string.ascii_uppercase:
        num = get_num_page(c)
        if num:
            page_num = (num - 1) / 50 + 1
            for page in range(1, page_num + 1):
                url = AGENTS_FIRSTNAME_URL + "/%c/%d" % (c, page) + "?items_per_page=50"
                agent_url_list = get_agent_url_list_from_url(url)
                for agent_url in agent_url_list:
                    if not (agent_url in existing):
                        agent = Agent(url=agent_url)
                        agent.save()
                    # agent = get_agent_by_url(HOST + agent_url)
                    # if agent is None:  # some error happens, try to process again
                    #     time.sleep(1)
                    #     agent = get_agent_by_url(HOST + agent_url)
                    # else:
                    #     agent.save()
                        agents.append(agent)
                time.sleep(1)
        logger.info("Get all agents with first_letter = %c done!" % c)
    logger.info("Get agents: %d" % (len(agents)))
    return agents
Esempio n. 5
0
def batch_sync_modules_task():
    # sync modules, split into chunks of 50 agents to not overload salt
    agents = Agent.objects.all()
    online = [i.salt_id for i in agents]
    chunks = (online[i:i + 50] for i in range(0, len(online), 50))
    for chunk in chunks:
        Agent.salt_batch_async(minions=chunk, func="saltutil.sync_modules")
        sleep(10)
Esempio n. 6
0
def batch_sysinfo_task():
    # update system info using WMI
    agents = Agent.objects.all()
    online = [
        i.salt_id for i in agents
        if not i.not_supported("0.11.0") and i.status == "online"
    ]
    chunks = (online[i:i + 30] for i in range(0, len(online), 30))
    for chunk in chunks:
        Agent.salt_batch_async(minions=chunk, func="win_agent.local_sys_info")
        sleep(10)
Esempio n. 7
0
def add(request):
    data = request.data
    agent_id = data["agentid"]
    hostname = data["hostname"]
    client = data["client"]
    site = data["site"]
    monitoring_type = data["monitoring_type"]
    description = data["description"]
    mesh_node_id = data["mesh_node_id"]

    if not Agent.objects.filter(agent_id=agent_id).exists():
        Agent(
            agent_id=agent_id,
            hostname=hostname,
            client=client,
            site=site,
            monitoring_type=monitoring_type,
            description=description,
            mesh_node_id=mesh_node_id,
        ).save()

        agent = get_object_or_404(Agent, agent_id=agent_id)
        MemoryHistory(agent=agent).save()
        CpuHistory(agent=agent).save()

        if agent.monitoring_type == "workstation":
            WinUpdatePolicy(agent=agent, run_time_days=[5, 6]).save()
        else:
            WinUpdatePolicy(agent=agent).save()

        return Response({"pk": agent.pk})
    else:
        return Response("err", status=status.HTTP_400_BAD_REQUEST)
Esempio n. 8
0
    def save_model(self, request, obj, form, change):
        if not change:
            # Django's PasswordResetForm won't let us reset an unusable
            # password. We set it above super() so we don't have to save twice.
            obj.set_password(get_random_string())
            reset_password = True
            import pdb
            pdb.set_trace()
        else:
            reset_password = False

        user = super(UserAdmin, self).save_model(request, obj, form, change)
        import pdb
        pdb.set_trace()
        # Create the Agent now
        facility = form.cleaned_data.get("facility")
        user = User.objects.get(email=form.cleaned_data.get("email"))
        Agent(user=user, facility=facility).save()
        import pdb
        pdb.set_trace()
        if reset_password:
            import pdb
            pdb.set_trace()
            reset_form = PasswordResetForm({'email': obj.email})
            assert reset_form.is_valid()
            if reset_password:
                reset_form = PasswordResetForm({'email': obj.email})
                assert reset_form.is_valid()
                reset_form.save(
                    request=request,
                    use_https=request.is_secure(),
                    subject_template_name='account_creation_subject.txt',
                    email_template_name='account_creation_email.html',
                )
Esempio n. 9
0
def service_action(hostname, action, service):
    return Agent.salt_api_cmd(
        hostname=hostname,
        timeout=30,
        func="cmd.script",
        arg="C:\\Program Files\\TacticalAgent\\nssm.exe",
        kwargs={"args": f"{action} {service}"},
    )
Esempio n. 10
0
def read_agent_list(input_path='agents/SalesPersons.xlsx'):

    book = xlrd.open_workbook(input_path)
    sheet = book.sheet_by_index(0)

    for row in range(2, sheet.nrows):
        reg_number = sheet.cell(row, 0).value
        name = sheet.cell(row, 1).value
        estate_name = sheet.cell(row, 2).value
        lic_number = sheet.cell(row, 3).value
        agent = Agent(reg_number=reg_number,
                      name=name,
                      estate_name=estate_name,
                      lic_number=lic_number)
        agent.save()
        print "done %d" % row
    print "done"
Esempio n. 11
0
    def post(self, request):
        from logs.models import AuditLog

        """ Creates the agent """

        if Agent.objects.filter(agent_id=request.data["agent_id"]).exists():
            return notify_error(
                "Agent already exists. Remove old agent first if trying to re-install"
            )

        agent = Agent(
            agent_id=request.data["agent_id"],
            hostname=request.data["hostname"],
            site_id=int(request.data["site"]),
            monitoring_type=request.data["monitoring_type"],
            description=request.data["description"],
            mesh_node_id=request.data["mesh_node_id"],
            last_seen=djangotime.now(),
        )
        agent.save()
        agent.salt_id = f"{agent.hostname}-{agent.pk}"
        agent.save(update_fields=["salt_id"])

        user = User.objects.create_user(  # type: ignore
            username=request.data["agent_id"],
            agent=agent,
            password=User.objects.make_random_password(60),  # type: ignore
        )

        token = Token.objects.create(user=user)

        if agent.monitoring_type == "workstation":
            WinUpdatePolicy(agent=agent, run_time_days=[5, 6]).save()
        else:
            WinUpdatePolicy(agent=agent).save()

        reload_nats()

        # create agent install audit record
        AuditLog.objects.create(
            username=request.user,
            agent=agent.hostname,
            object_type="agent",
            action="agent_install",
            message=f"{request.user} installed new agent {agent.hostname}",
            after_value=Agent.serialize(agent),
        )

        return Response(
            {
                "pk": agent.pk,
                "saltid": f"{agent.hostname}-{agent.pk}",
                "token": token.key,
            }
        )
Esempio n. 12
0
def get_agents_by_html(source_code):  # care only about 1st page of results
    tree = html.fromstring(source_code)
    rows = tree.xpath('//tbody/tr')
    agents = []
    for row in rows:
        agents.append(
            Agent(reg_number=row.xpath('td/a/text()'),
                  name=row.xpath('td/span/text()')))
    logger.info("get %d agents." % len(agents))
    if len(agents) > 0:
        logger.info(agents[0])
    return agents
Esempio n. 13
0
def send_agent_update_task(pks, version):
    assert isinstance(pks, list)
    ver = version.split("winagent-v")[1]
    q = Agent.objects.only("pk").filter(pk__in=pks)

    agents = [
        i
        for i in q
        if pyver.parse(i.version) < pyver.parse(ver) and i.status == "online"
    ]

    if agents:
        for agent in agents:
            agent.update_pending = True
            agent.save(update_fields=["update_pending"])

        minions = [i.salt_id for i in agents]

        r = Agent.get_github_versions()
        git_versions = r["versions"]
        data = r["data"]  # full response from github
        versions = {}

        for i, release in enumerate(data):
            versions[i] = release["name"]

        key = [k for k, v in versions.items() if v == version][0]

        download_url = data[key]["assets"][0]["browser_download_url"]

        # split into chunks to not overload salt
        chunks = (minions[i : i + 30] for i in range(0, len(minions), 30))

        for chunk in chunks:
            r = Agent.salt_batch_async(
                minions=chunk,
                func="win_agent.do_agent_update",
                kwargs={"version": ver, "url": download_url},
            )
            sleep(5)
Esempio n. 14
0
def uninstall_agent_task(salt_id):
    attempts = 0
    error = False

    while 1:
        try:
            r = Agent.salt_api_cmd(hostname=salt_id,
                                   timeout=10,
                                   func="win_agent.uninstall_agent")
            ret = r.json()["return"][0][salt_id]
        except Exception:
            attempts += 1
        else:
            if ret != "ok":
                attempts += 1
            else:
                attempts = 0

        if attempts >= 10:
            error = True
            break
        elif attempts == 0:
            break

    if error:
        logger.error(f"{salt_id} uninstall failed")
    else:
        logger.info(f"{salt_id} was successfully uninstalled")

    try:
        r = requests.post(
            f"http://{settings.SALT_HOST}:8123/run",
            json=[{
                "client": "wheel",
                "fun": "key.delete",
                "match": salt_id,
                "username": settings.SALT_USERNAME,
                "password": settings.SALT_PASSWORD,
                "eauth": "pam",
            }],
            timeout=30,
        )
    except Exception:
        logger.error(f"{salt_id} unable to remove salt-key")

    return "ok"
Esempio n. 15
0
def get_agent_by_url(url):
    logger.info("get agent by url, url = %s" % url)
    try:
        source_code = get_page(url)
        tree = html.fromstring(source_code.text)
        # Get detail information about the agent
        summary1 = tostring(tree.cssselect('div.summary1')[0])
        summary2 = tostring(tree.cssselect('div.summary2')[0])
        name = html.fromstring(summary1).cssselect('h1.summarytitle a')[0].text.encode('ascii', 'ignore').decode('ascii').strip()
        try:
            estate_name = html.fromstring(summary1).cssselect('div.summary1 span.greytext')[0].text.strip()
        except IndexError:
            estate_name = None
        phone_number = html.fromstring(summary2).cssselect('span.orangebold')[0].text.strip()
        cea = html.fromstring(summary2).cssselect('div.top15 a')
        try:
            lic_number = cea[0].text.strip()
        except IndexError:
            lic_number = None
        try:
            reg_number = cea[1].text.strip()
        except IndexError:
            reg_number = None
        agent = Agent(name=name, estate_name=estate_name, phone_number=phone_number, lic_number=lic_number, reg_number=reg_number)
        logger.info(agent)
        return agent
    except requests.exceptions.HTTPError as e:
        logger.error("HTTPError: " + str(e))
        return None
    except requests.exceptions.ConnectionError as e:
        logger.error(str(e))
        return None
    except IndexError as e:
        logger.error(str(e))
        with open("error_page.html", "w") as f:
            f.write(source_code.text.encode('utf-8'))
        return None
    except AttributeError as e:
        logger.error(str(e))
        return None
Esempio n. 16
0
def cancel_pending_action_task(data):

    if data["action_type"] == "schedreboot" and data["status"] == "pending":

        from agents.models import Agent

        task_name = data["details"]["taskname"]
        try:
            resp = Agent.salt_api_cmd(
                hostname=data["salt_id"],
                timeout=45,
                func="task.delete_task",
                arg=[f"name={task_name}"],
            )
        except Exception as e:
            logger.error(
                f"Unable to contact {data['salt_id']}. Task {task_name} will need to cancelled manually."
            )
        else:
            logger.info(f"Scheduled reboot cancellled: {resp.json()}")

    return "ok"
Esempio n. 17
0
def signup_agent(request):
    if not request.user.is_authenticated():
        if request.method == 'POST':
            form = SignUpAgentForm(request.POST)
            if form.is_valid():
                user = form.save()
                user.save()
                password = form.cleaned_data.get('password1')
                user = authenticate(username=user.username, password=password)
                agent = Agent()
                agent.agent_id = user
                agent.total_transaction = 0
                agent.save()

                auth_login(request, user)
                return HttpResponseRedirect(reverse('catalog:index'))
            else:
                return render(request, 'del3/signupagent.html', {'form': form})
        else:
            form = SignUpAgentForm()
            return render(request, 'del3/signupagent.html', {'form': form})
    else:
        return HttpResponseRedirect(reverse('index'))
Esempio n. 18
0
def update_agent_task(pk, version):

    agent = Agent.objects.get(pk=pk)

    errors = []
    file = f"/srv/salt/scripts/{version}.exe"
    ver = version.split("winagent-v")[1]

    # download the release from github if the file doesn't already exist in /srv
    if not os.path.exists(file):
        r = Agent.get_github_versions()
        git_versions = r["versions"]
        data = r["data"]  # full response from github
        versions = {}

        for i, release in enumerate(data):
            versions[i] = release["name"]

        key = [k for k, v in versions.items() if v == version][0]

        download_url = data[key]["assets"][0]["browser_download_url"]

        p = subprocess.run(["wget", download_url, "-O", file],
                           capture_output=True)

    app_dir = "C:\\Program Files\\TacticalAgent"
    temp_dir = "C:\\Windows\\Temp"

    logger.info(
        f"{agent.hostname} is attempting update from version {agent.version} to {ver}"
    )

    # send the release to the agent
    r = agent.salt_api_cmd(
        hostname=agent.salt_id,
        timeout=300,
        func="cp.get_file",
        arg=[f"salt://scripts/{version}.exe", temp_dir],
    )
    # success return example: {'return': [{'HOSTNAME': 'C:\\Windows\\Temp\\winagent-v0.1.12.exe'}]}
    # error return example: {'return': [{'HOSTNAME': ''}]}
    if not r.json()["return"][0][agent.salt_id]:
        agent.is_updating = False
        agent.save(update_fields=["is_updating"])
        logger.error(
            f"{agent.hostname} update failed to version {ver} (unable to copy installer)"
        )
        return f"{agent.hostname} update failed to version {ver} (unable to copy installer)"

    services = (
        "tacticalagent",
        "checkrunner",
    )

    for svc in services:
        r = service_action(agent.salt_id, "stop", svc)
        # returns non 0 if error
        if r.json()["return"][0][agent.salt_id]["retcode"]:
            errors.append(f"failed to stop {svc}")
            logger.error(
                f"{agent.hostname} was unable to stop service {svc}. Update cancelled"
            )

    # start the services if some of them failed to stop, then don't continue
    if errors:
        agent.is_updating = False
        agent.save(update_fields=["is_updating"])
        for svc in services:
            service_action(agent.salt_id, "start", svc)
        return "stopping services failed. started again"

    # install the update
    # success respose example: {'return': [{'HOSTNAME': {'retcode': 0, 'stderr': '', 'stdout': '', 'pid': 3452}}]}
    # error response example: {'return': [{'HOSTNAME': 'The minion function caused an exception: Traceback...'}]}
    try:
        r = agent.salt_api_cmd(
            hostname=agent.salt_id,
            timeout=200,
            func="cmd.script",
            arg=f"{temp_dir}\\{version}.exe",
            kwargs={"args": "/VERYSILENT /SUPPRESSMSGBOXES"},
        )
    except Exception:
        agent.is_updating = False
        agent.save(update_fields=["is_updating"])
        return (
            f"TIMEOUT: failed to run inno setup on {agent.hostname} for version {ver}"
        )

    if "minion function caused an exception" in r.json()["return"][0][
            agent.salt_id]:
        agent.is_updating = False
        agent.save(update_fields=["is_updating"])
        return (
            f"EXCEPTION: failed to run inno setup on {agent.hostname} for version {ver}"
        )

    if r.json()["return"][0][agent.salt_id]["retcode"]:
        agent.is_updating = False
        agent.save(update_fields=["is_updating"])
        logger.error(
            f"failed to run inno setup on {agent.hostname} for version {ver}")
        return f"failed to run inno setup on {agent.hostname} for version {ver}"

    # update the version in the agent's local database
    r = agent.salt_api_cmd(
        hostname=agent.salt_id,
        timeout=45,
        func="sqlite3.modify",
        arg=[
            "C:\\Program Files\\TacticalAgent\\agentdb.db",
            f'UPDATE agentstorage SET version = "{ver}"',
        ],
    )
    # success return example: {'return': [{'FSV': True}]}
    # error return example: {'return': [{'HOSTNAME': 'The minion function caused an exception: Traceback...'}]}
    sql_ret = r.json()["return"][0][agent.salt_id]
    if not isinstance(sql_ret, bool) and isinstance(sql_ret, str):
        if "minion function caused an exception" in sql_ret:
            logger.error(f"failed to update {agent.hostname} local database")

    if not sql_ret:
        logger.error(
            f"failed to update {agent.hostname} local database to version {ver}"
        )

    # start the services
    for svc in services:
        service_action(agent.salt_id, "start", svc)

    agent.is_updating = False
    agent.save(update_fields=["is_updating"])
    logger.info(f"{agent.hostname} was successfully updated to version {ver}")
    return f"{agent.hostname} was successfully updated to version {ver}"
Esempio n. 19
0
    def patch(self, request):
        """ Creates the agent """

        if Agent.objects.filter(agent_id=request.data["agent_id"]).exists():
            return notify_error(
                "Agent already exists. Remove old agent first if trying to re-install"
            )

        client = get_object_or_404(Client, pk=int(request.data["client"]))
        site = get_object_or_404(Site, pk=int(request.data["site"]))

        agent = Agent(
            agent_id=request.data["agent_id"],
            hostname=request.data["hostname"],
            client=client.client,
            site=site.site,
            monitoring_type=request.data["monitoring_type"],
            description=request.data["description"],
            mesh_node_id=request.data["mesh_node_id"],
            last_seen=djangotime.now(),
        )
        agent.save()
        agent.salt_id = f"{agent.hostname}-{agent.pk}"
        agent.save(update_fields=["salt_id"])

        if agent.monitoring_type == "workstation":
            WinUpdatePolicy(agent=agent, run_time_days=[5, 6]).save()
        else:
            WinUpdatePolicy(agent=agent).save()

        # Generate policies for new agent
        agent.generate_checks_from_policies()
        agent.generate_tasks_from_policies()

        return Response({"pk": agent.pk, "saltid": f"{agent.hostname}-{agent.pk}"})
Esempio n. 20
0
        'name': 'CMIS Rest API',
        'is_active': True,
        'script': 'agents.lib.cmis_rest_agent.CmisRestAgent',
        'description': (
            'Tests availability and performance of Alfresco '
            'CMIS Rest API endpoints.'
        ),
    },
    {
        'name': 'JMXDump',
        'is_active': True,
        'script': 'agents.lib.jmxdump_agent.JmxDumpAgent',
        'description': (
            'Stores all settings of a running Alfresco system '
            'for archival purposes.'
        ),
    },
]


if __name__ == '__main__':

    for agent in agent_list:
        a = Agent()
        for k, v in agent.items():
            setattr(a, k, v)
        try:
            a.save()
        except IntegrityError:
            print('Agent already exists.')
Esempio n. 21
0
 def new_method(handler, request, *args, **kwargs):
     if request.POST.get('crypto_v1', None):
         from agents.CryptoLib_v1 import crypto, CryptoLib, aggregatorKey, aes_decrypt
     else:
         from agents.CryptoLib import crypto, CryptoLib, aggregatorKey, aes_decrypt
     aes_key = None
     agent = None
     
     key = request.POST.get('key', None)
     message = request.POST.get('msg', None)
     agent_id = request.POST.get('agentID', None)
     
     # If key is not provided, then agent_id must be present.
     if key is None:
         assert agent_id
         
         agent = Agent.get_agent(agent_id)
         aes_key = agent.AESKey
     else:
         aes_key = crypto.decodeRSAPrivateKey(key, aggregatorKey)
     
     
     aes_key, msg_obj = aes_decrypt(message,
                                    self.message_type,
                                    aes_key=aes_key)
     
     # get software version information
     # TODO: CACHE the desktop and mobile latest versions so we don't need
     # to reach out to the datastore to get that upon every api request.
     software_version = None
     if agent is not None:
         if agent.agent_type == 'DESKTOP':
             software_version = DesktopAgentVersion.getLastVersionNo()
         elif agent.agent_type == 'MOBILE':
             software_version = MobileAgentVersion.getLastVersionNo()
         else:
             logging.error("Unknown agent type '%s' - Agent %s" % \
                             ( agent.agent_type, agent))
     
     # get lastest test id
     # TODO: Cache the latest test version to avoid going to datastore on
     # every api request
     test_version = Test.get_test_version(agent)
     
     response = None
     if self.response_type is not None:
         response = self.response_type()
         
         if getattr(response, "header", False):
             response.header.currentVersionNo = software_version.version if software_version is not None else 0
             response.header.currentTestVersionNo = test_version
     
     response = method(handler,
                           request,
                           msg_obj,
                           aes_key,
                           agent,
                           software_version,
                           test_version,
                           response,
                           *args, **kwargs)
     
     # Need to encrypt and return the response now
     return crypto.encodeAES(response, aes_key)
Esempio n. 22
0
    def handle(self, *args, **kwargs):
        # sync modules. split into chunks of 30 agents to not overload the salt master
        agents = Agent.objects.all()
        online = [i.salt_id for i in agents if i.status == "online"]

        chunks = (online[i:i + 30] for i in range(0, len(online), 30))

        self.stdout.write(self.style.SUCCESS("Syncing agent modules..."))
        for chunk in chunks:
            r = Agent.salt_batch_async(minions=chunk,
                                       func="saltutil.sync_modules")
            sleep(5)

        has_old_config = True
        rmm_conf = "/etc/nginx/sites-available/rmm.conf"
        if os.path.exists(rmm_conf):
            with open(rmm_conf) as f:
                for line in f:
                    if "location" and "builtin" in line:
                        has_old_config = False
                        break

        if has_old_config:
            new_conf = """
            location /builtin/ {
                internal;
                add_header "Access-Control-Allow-Origin" "https://rmm.yourwebsite.com";
                alias /srv/salt/scripts/;
            }
            """

            after_this = """
            location /saltscripts/ {
                internal;
                add_header "Access-Control-Allow-Origin" "https://rmm.yourwebsite.com";
                alias /srv/salt/scripts/userdefined/;
            }
            """

            self.stdout.write(self.style.ERROR("*" * 100))
            self.stdout.write("\n")
            self.stdout.write(
                self.style.ERROR(
                    "WARNING: A recent update requires you to manually edit your nginx config"
                ))
            self.stdout.write("\n")
            self.stdout.write(
                self.style.ERROR("Please add the following location block to ")
                + self.style.WARNING(rmm_conf))
            self.stdout.write(self.style.SUCCESS(new_conf))
            self.stdout.write("\n")
            self.stdout.write(
                self.style.ERROR(
                    "You can paste the above right after the following block that's already in your nginx config:"
                ))
            self.stdout.write(after_this)
            self.stdout.write("\n")
            self.stdout.write(
                self.style.ERROR(
                    "Make sure to replace rmm.yourwebsite.com with your domain"
                ))
            self.stdout.write(
                self.style.ERROR(
                    "After editing, restart nginx with the command ") +
                self.style.WARNING("sudo systemctl restart nginx"))
            self.stdout.write("\n")
            self.stdout.write(self.style.ERROR("*" * 100))
            input("Press Enter to continue...")

        # install go
        if not os.path.exists("/usr/local/rmmgo/"):
            self.stdout.write(self.style.SUCCESS("Installing golang"))
            subprocess.run("sudo mkdir -p /usr/local/rmmgo", shell=True)
            tmpdir = tempfile.mkdtemp()
            r = subprocess.run(
                f"wget https://golang.org/dl/go1.15.linux-amd64.tar.gz -P {tmpdir}",
                shell=True,
            )

            gotar = os.path.join(tmpdir, "go1.15.linux-amd64.tar.gz")

            subprocess.run(f"tar -xzf {gotar} -C {tmpdir}", shell=True)

            gofolder = os.path.join(tmpdir, "go")
            subprocess.run(f"sudo mv {gofolder} /usr/local/rmmgo/", shell=True)
            shutil.rmtree(tmpdir)
Esempio n. 23
0
    def handle(self, *args, **kwargs):

        if not os.path.exists("/usr/local/bin/goversioninfo"):
            self.stdout.write(self.style.ERROR("*" * 100))
            self.stdout.write("\n")
            self.stdout.write(
                self.style.ERROR(
                    "ERROR: New update script available. Delete this one and re-download."
                ))
            self.stdout.write("\n")
            sys.exit(1)

        # 10-16-2020 changed the type of the agent's 'disks' model field
        # from a dict of dicts, to a list of disks in the golang agent
        # the following will convert dicts to lists for agent's still on the python agent
        agents = Agent.objects.all()
        for agent in agents:
            if agent.disks is not None and isinstance(agent.disks, dict):
                new = []
                for k, v in agent.disks.items():
                    new.append(v)

                agent.disks = new
                agent.save(update_fields=["disks"])
                self.stdout.write(
                    self.style.SUCCESS(f"Migrated disks on {agent.hostname}"))

        # sync modules. split into chunks of 60 agents to not overload the salt master
        agents = Agent.objects.all()
        online = [i.salt_id for i in agents if i.status == "online"]

        chunks = (online[i:i + 60] for i in range(0, len(online), 60))

        self.stdout.write(self.style.SUCCESS("Syncing agent modules..."))
        for chunk in chunks:
            r = Agent.salt_batch_async(minions=chunk,
                                       func="saltutil.sync_modules")
            sleep(5)

        has_old_config = True
        rmm_conf = "/etc/nginx/sites-available/rmm.conf"
        if os.path.exists(rmm_conf):
            with open(rmm_conf) as f:
                for line in f:
                    if "location" and "builtin" in line:
                        has_old_config = False
                        break

        if has_old_config:
            new_conf = """
            location /builtin/ {
                internal;
                add_header "Access-Control-Allow-Origin" "https://rmm.yourwebsite.com";
                alias /srv/salt/scripts/;
            }
            """

            after_this = """
            location /saltscripts/ {
                internal;
                add_header "Access-Control-Allow-Origin" "https://rmm.yourwebsite.com";
                alias /srv/salt/scripts/userdefined/;
            }
            """

            self.stdout.write(self.style.ERROR("*" * 100))
            self.stdout.write("\n")
            self.stdout.write(
                self.style.ERROR(
                    "WARNING: A recent update requires you to manually edit your nginx config"
                ))
            self.stdout.write("\n")
            self.stdout.write(
                self.style.ERROR("Please add the following location block to ")
                + self.style.WARNING(rmm_conf))
            self.stdout.write(self.style.SUCCESS(new_conf))
            self.stdout.write("\n")
            self.stdout.write(
                self.style.ERROR(
                    "You can paste the above right after the following block that's already in your nginx config:"
                ))
            self.stdout.write(after_this)
            self.stdout.write("\n")
            self.stdout.write(
                self.style.ERROR(
                    "Make sure to replace rmm.yourwebsite.com with your domain"
                ))
            self.stdout.write(
                self.style.ERROR(
                    "After editing, restart nginx with the command ") +
                self.style.WARNING("sudo systemctl restart nginx"))
            self.stdout.write("\n")
            self.stdout.write(self.style.ERROR("*" * 100))
            input("Press Enter to continue...")

        # install go
        if not os.path.exists("/usr/local/rmmgo/"):
            self.stdout.write(self.style.SUCCESS("Installing golang"))
            subprocess.run("sudo mkdir -p /usr/local/rmmgo", shell=True)
            tmpdir = tempfile.mkdtemp()
            r = subprocess.run(
                f"wget https://golang.org/dl/go1.15.linux-amd64.tar.gz -P {tmpdir}",
                shell=True,
            )

            gotar = os.path.join(tmpdir, "go1.15.linux-amd64.tar.gz")

            subprocess.run(f"tar -xzf {gotar} -C {tmpdir}", shell=True)

            gofolder = os.path.join(tmpdir, "go")
            subprocess.run(f"sudo mv {gofolder} /usr/local/rmmgo/", shell=True)
            shutil.rmtree(tmpdir)

        # load community scripts into the db
        Script.load_community_scripts()