Hi Amit,

This issue is likely due to multiple tenant security being enabled on the 
tower server. The custom inventory script (few lines of bash) gets executed 
in a proot, which hides most of the filesystem, and that’s why Python can’t 
open inventory.py.

Could you please replace the contents of the custom inventory script in 
tower with the contents of the all-in-one.py file attached here? Current 
content that will need to be replace should be:
#!/bin/bash

if [ "$1" == "--list" ]; then
   python /var/lib/awx/scalr/inventory.py $SCALR_API_URL $SCALR_API_KEY_ID 
$SCALR_API_KEY_SECRET $SCALR_ENV_ID $SCALR_FARM_ID
else
   echo '{}'
fi
) 

Many thanks,
Wm. Marc O'Brien
Scalr Technical Support


On Thursday, November 10, 2016 at 10:17:59 AM UTC-7, Amit Saini wrote:
>
> Hi Marc,
>
> I did change in first line ( marked bold) of following script. Now not 
> getting this error 
>
>  failed (rc=2) with output: python: can't open file [Errno 2] No such 
> file or directory
>
> ***************************************
>
> *#!usr/bin/bash/python2.7 *
>
> if [ "$1" == "--list" ]; then
>
>    python /var/lib/awx/scalr/scalr-ansible-tower/inventory.py 
> $SCALR_API_URL $SCALR_API_KEY_ID $SCALR_API_KEY_SECRET $SCALR_ENV_ID 
> $SCALR_FARM_ID
>
> else
>
>    echo '{}'
>
> fi
>
> ************************************
>
>  
>
>
> *But  New Error is came  :(*
>
> 2.248 INFO Updating inventory 4: Scalr Inventory 2.277 INFO Reading 
> executable JSON source: /tmp/ansible_tower_launch_8bq4Ga/tmpy0MuDU 2.301 
> ERROR Failed to load JSON from: Traceback (most recent call last): File 
> "/usr/bin/tower-manage", line 9, in <module> 
> load_entry_point('ansible-tower==3.0.3', 'console_scripts', 
> 'tower-manage')() File "/lib/python2.7/site-packages/awx/__init__.py", line 
> 103, in manage File 
> "/var/lib/awx/venv/tower/lib/python2.7/site-packages/django/core/management/__init__.py",
>  
> line 354, in execute_from_command_line utility.execute() File 
> "/var/lib/awx/venv/tower/lib/python2.7/site-packages/django/core/management/__init__.py",
>  
> line 346, in execute 
> self.fetch_command(subcommand).run_from_argv(self.argv) File 
> "/var/lib/awx/venv/tower/lib/python2.7/site-packages/django/core/management/base.py",
>  
> line 394, in run_from_argv self.execute(*args, **cmd_options) File 
> "/var/lib/awx/venv/tower/lib/python2.7/site-packages/django/core/management/base.py",
>  
> line 445, in execute output = self.handle(*args, **options) File 
> "/var/lib/awx/venv/tower/lib/python2.7/site-packages/django/core/management/base.py",
>  
> line 661, in handle return self.handle_noargs(**options) File 
> "/lib/python2.7/site-packages/awx/main/management/commands/inventory_import.py",
>  
> line 1285, in handle_noargs File 
> "/lib/python2.7/site-packages/awx/main/management/commands/inventory_import.py",
>  
> line 499, in load_inventory_source File 
> "/lib/python2.7/site-packages/awx/main/management/commands/inventory_import.py",
>  
> line 503, in load_inventory_source File 
> "/lib/python2.7/site-packages/awx/main/management/commands/inventory_import.py",
>  
> line 393, in load File 
> "/lib/python2.7/site-packages/awx/main/management/commands/inventory_import.py",
>  
> line 381, in command_to_json RuntimeError: ['proot', '-v', '0', '-r', '/', 
> '-b', '/tmp/ansible_tower_launch_8bq4Ga/tmp_P6tYy:/etc/tower', '-b', 
> '/tmp/ansible_tower_launch_8bq4Ga/tmpI8YWHM:/tmp', '-b', 
> '/tmp/ansible_tower_launch_8bq4Ga/tmpzmar2T:/var/lib/awx', '-b', 
> '/tmp/ansible_tower_launch_8bq4Ga/tmp91ioqa:/var/lib/awx/job_status', '-b', 
> '/tmp/ansible_tower_launch_8bq4Ga/tmpAB66lA:/var/lib/awx/projects', '-b', 
> '/tmp/ansible_tower_launch_8bq4Ga/tmp0gB6tg:/var/log', '-b', 
> '/tmp/ansible_tower_launch_8bq4Ga:/tmp/ansible_tower_launch_8bq4Ga', '-b', 
> '/var/lib/awx/venv/ansible:/var/lib/awx/venv/ansible', '-b', 
> '/var/lib/awx/venv/tower:/var/lib/awx/venv/tower', '-w', 
> '/tmp/ansible_tower_launch_8bq4Ga', 
> '/tmp/ansible_tower_launch_8bq4Ga/tmpy0MuDU', '--list'] failed (rc=1) with 
> output: proot error: execve("/tmp/ansible_tower_launch_8bq4Ga/tmpy0MuDU"): 
> No such file or directory proot info: possible causes: * the program is a 
> script but its interpreter (eg. /bin/sh) was not found; * the program is an 
> ELF but its interpreter (eg. ld-linux.so) was not found; * the program is a 
> foreign binary but qemu was not specified; * qemu does not work correctly 
> (if specified); * the loader was not found or doesn't work. fatal error: 
> see `proot --help`. proot error: can't chmod '/tmp/proot-14165-FKg5i0': No 
> such file or directory
>
>
> On Wednesday, November 9, 2016 at 11:45:52 AM UTC-5, Amit Saini wrote:
>>
>>
>> Thanks Marc for replying 
>>
>> Yes I am following Scalr document 
>> <https://scalr-wiki.atlassian.net/wiki/display/docs/Step+1+-+Synchronising+Scalr+Servers+with+an+Ansible+inventory>.
>>  
>> I have copy the content of *scalr-ansible-tower* to */var/lib/awx/scalr* 
>>  ( Refer the Image4 ) but still I am getting the same error ( Refer 
>> job_477.txt )
>>
>>  
>>
>>  Please help me!!!
>>
>> On Tuesday, November 8, 2016 at 4:05:04 PM UTC-5, Marc O'Brien wrote:
>>>
>>> Hi Amit,
>>>
>>> Are you following our Ansible Tower with Scalr Tutorial 
>>> <https://scalr-wiki.atlassian.net/wiki/display/docs/Step+1+-+Synchronising+Scalr+Servers+with+an+Ansible+inventory>?
>>>   
>>> If so, it appears that when you run "git clone 
>>> https://github.com/scalr-tutorials/scalr-ansible-tower.git"; there is an 
>>> additional level in the directory tree.  Do you see any change to behavior 
>>> if you move the contents of scalr-ansible-tower to /var/lib/awx/scalr, or 
>>> update the path in the Ansible script to include the scalr-ansible-tower 
>>> folder in the directory path to inventory.py?  This should resolve the "no 
>>> such file" error that you are experiencing.
>>>
>>> Many thanks,
>>> Wm. Marc O'Brien
>>> Scalr Technical Support
>>>
>>>
>>>
>>> On Tuesday, November 8, 2016 at 1:44:30 PM UTC-7, Amit Saini wrote:
>>>>
>>>> Hi Team,
>>>>
>>>> While Integration of Ansible Tower with Scalr and I configure the 
>>>> custom script ansible tower's Inventory (Refer Image 1) and try to Sync-up 
>>>> with Scalr but got the error  ( Refer text file job_419) with message 
>>>> *'/var/lib/awx/scalr/inventory.py': 
>>>> [Errno 2] No such file or directory*
>>>>
>>>>
>>>> While I have SSH ansible tower machine and found that there is not 
>>>> *inventory.py* file available on the following path */var/lib/awx/scalr/  
>>>> (Refer Image3). *I found *scalr-ansible-tower* file over there
>>>>
>>>> Please help me!!!
>>>>
>>>

-- 
You received this message because you are subscribed to the Google Groups 
"scalr-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import base64
import datetime
import hashlib
import hmac
import json
import logging
import os
import pytz
import random
import requests
import requests.auth
import requests.exceptions
import sys
import urllib
import urlparse
from collections import Mapping, Iterable


class ScalrApiClient(object):
    def __init__(self, api_url, key_id, key_secret):
        self.api_url = api_url
        self.key_id = key_id
        self.key_secret = key_secret
        self.logger = logging.getLogger("api[{0}]".format(self.api_url))
        self.logger.addHandler(logging.StreamHandler())
        self.session = ScalrApiSession(self)

    def list(self, path, **kwargs):
        data = []
        ident = False
        while path is not None:
            if ident:
                print
            body = self.session.get(path, **kwargs).json()
            data.extend(body["data"])
            path = body["pagination"]["next"]
            ident = True
        return data

    def create(self, *args, **kwargs):
        self._fuzz_ids(kwargs.get("json", {}))
        return self.session.post(*args, **kwargs).json().get("data")

    def fetch(self, *args, **kwargs):
        return self.session.get(*args, **kwargs).json()["data"]

    def delete(self, *args, **kwargs):
        self.session.delete(*args, **kwargs)

    def post(self, *args, **kwargs):
        return self.session.post(*args, **kwargs).json()["data"]


class ScalrApiSession(requests.Session):
    def __init__(self, client):
        self.client = client
        super(ScalrApiSession, self).__init__()

    def prepare_request(self, request):
        if not request.url.startswith(self.client.api_url):
            request.url = "".join([self.client.api_url, request.url])
        request = super(ScalrApiSession, self).prepare_request(request)

        now = datetime.datetime.now(tz=pytz.timezone(os.environ.get("TZ", "UTC")))
        date_header = now.isoformat()

        url = urlparse.urlparse(request.url)

        # TODO - Spec isn't clear on whether the sorting should happen prior or after encoding
        if url.query:
            pairs = urlparse.parse_qsl(url.query, keep_blank_values=True, strict_parsing=True)
            pairs = [map(urllib.quote, pair) for pair in pairs]
            pairs.sort(key=lambda pair: pair[0])
            canon_qs = "&".join("=".join(pair) for pair in pairs)
        else:
            canon_qs = ""

        # Authorize
        sts = "\n".join([
            request.method,
            date_header,
            url.path,
            canon_qs,
            request.body if request.body is not None else ""
        ])

        sig = " ".join([
            "V1-HMAC-SHA256",
            base64.b64encode(hmac.new(str(self.client.key_secret), sts, hashlib.sha256).digest())
        ])

        request.headers.update({
            "X-Scalr-Key-Id": self.client.key_id,
            "X-Scalr-Signature": sig,
            "X-Scalr-Date": date_header,
            "X-Scalr-Debug": "1"
        })

        self.client.logger.debug("URL: %s", request.url)
        self.client.logger.debug("StringToSign: %s", repr(sts))
        self.client.logger.debug("Signature: %s", repr(sig))

        return request

    def request(self, *args, **kwargs):
        res = super(ScalrApiSession, self).request(*args, **kwargs)
        self.client.logger.info("%s - %s", " ".join(args), res.status_code)
        try:
            errors = res.json().get("errors", None)
            if errors is not None:
                for error in errors:
                    self.client.logger.warning("API Error (%s): %s", error["code"], error["message"])
        except ValueError:
            self.client.logger.error("Received non-JSON response from API!")
        res.raise_for_status()
        self.client.logger.debug("Received response: %s", res.text)
        return res

def get_env_servers(client, envId):
    servers_path = '/api/v1beta0/user/{envId}/servers/?status=running'.format(envId=envId)
    servers = client.list(servers_path)

    farmIds = []
    farmRoleIds = []
    for s in servers:
        farmIds.append(s['farm']['id'])
        farmRoleIds.append(s['farmRole']['id'])
    farmIds = set(farmIds)
    farmRoleIds = set(farmRoleIds)

    farms = {}
    farm_path = '/api/v1beta0/user/{envId}/farms/{farmId}/'
    for farmId in farmIds:
        path = farm_path.format(envId=envId, farmId=farmId)
        farms[farmId] = client.fetch(path)

    farmRoles = {}
    farmRole_path = '/api/v1beta0/user/{envId}/farm-roles/{farmRoleId}/'
    for farmRoleId in farmRoleIds:
        path = farmRole_path.format(envId=envId, farmRoleId=farmRoleId)
        farmRoles[farmRoleId] = client.fetch(path)

    result = {'_meta' : 
                {'hostvars': {}}
             }
    for farmId, farm in farms.iteritems():
        result[farm['name']] = {'vars': {
                                        'id': farmId,
                                        'project': farm['project']['id'],
                                        'owner': farm['owner']['id']
                                    }, 
                                'children': []}
        for farmRoleId, farmRole in farmRoles.iteritems():
            if farmRole['farm']['id'] != farmId:
                continue
            farmRoleGroupId = 'farm-role-' + str(farmRoleId) + '-' + farmRole['alias']
            result[farm['name']]['children'].append(farmRoleGroupId)
            result[farmRoleGroupId] = {'hosts': [], 'vars': {
                                        'id': farmRoleId,
                                        'platform': farmRole['platform'],
                                        'roleId': farmRole['role']['id']
                                      }}
            for server in servers:
                if server['farmRole']['id'] != farmRoleId:
                    continue
                if len(server['publicIp']) == 0:
                    # Server has no public IP
                    continue
                result[farmRoleGroupId]['hosts'].append(server['publicIp'][0])
                result['_meta']['hostvars'][server['publicIp'][0]] = {'hostname': server['hostname']}
    print json.dumps(result, indent=2)

def get_farm_servers(client, envId, farmId):
    servers_path = '/api/v1beta0/user/{envId}/farms/{farmId}/servers/?status=running'.format(envId=envId, farmId=farmId)
    servers = client.list(servers_path)

    farmRoleIds = []
    for s in servers:
        farmRoleIds.append(s['farmRole']['id'])
    farmRoleIds = set(farmRoleIds)

    farm_path = '/api/v1beta0/user/{envId}/farms/{farmId}/'.format(envId=envId, farmId=farmId)
    farm = client.fetch(farm_path)

    farmRoles = {}
    farmRole_path = '/api/v1beta0/user/{envId}/farm-roles/{farmRoleId}/'
    for farmRoleId in farmRoleIds:
        path = farmRole_path.format(envId=envId, farmRoleId=farmRoleId)
        farmRoles[farmRoleId] = client.fetch(path)

    result = {'_meta' : 
                {'hostvars': {}}
             }

    for farmRoleId, farmRole in farmRoles.iteritems():
        farmRoleGroupId = 'farm-role-' + str(farmRoleId) + '-' + farmRole['alias']
        result[farmRoleGroupId] = {'hosts': [], 'vars': {
                                    'id': farmRoleId,
                                    'platform': farmRole['platform'],
                                    'roleId': farmRole['role']['id']
                                  }}
        for server in servers:
            if server['farmRole']['id'] != farmRoleId:
                continue
            if len(server['publicIp']) == 0:
                # Server has no public IP
                continue
            result[farmRoleGroupId]['hosts'].append(server['publicIp'][0])
            result['_meta']['hostvars'][server['publicIp'][0]] = {'hostname': server['hostname']}
    print json.dumps(result, indent=2)


def main():
    api_url = os.environ.get('SCALR_API_URL')
    api_key_id = os.environ.get('SCALR_API_KEY_ID')
    api_key_secret = os.environ.get('SCALR_API_KEY_SECRET')
    env_id = os.environ.get('SCALR_ENV_ID')
    farm_id = os.environ.get('SCALR_FARM_ID')

    if not api_url:
        print 'API URL not specified, exiting.'
        return
    if not api_key_id:
        print 'API Key ID not specified, exiting.'
        return
    if not api_key_secret:
        print 'API Key Secret not specified, exiting.'
        return
    if not env_id:
        print 'Scalr Environment ID not specified, exiting.'
        return

    client = ScalrApiClient(api_url.rstrip("/"), api_key_id, api_key_secret)
    if farm_id:
        get_farm_servers(client, env_id, farm_id)
    else:
        get_env_servers(client, env_id)


if __name__ == "__main__":
    if len(sys.argv) >= 2 and sys.argv[1] == '--list':
        main()
    else:
        print '{}'

Reply via email to