Пример #1
0
        def get_secret(name):
            if is_fork:
                abort(400, 'Access to secret %s is not allowed from a fork' % name)

            for ev in secrets:
                if ev[0] == name:
                    return decrypt_secret(ev[1])
            return None
Пример #2
0
    def kube_job(self, job_id, cpu, mem, services=None):
        h = {'Authorization': 'Bearer %s' % self.args.token}

        job_token = encode_job_token(job_id).decode()

        env = [{
            'name': 'INFRABOX_JOB_ID',
            'value': job_id
        }, {
            'name': 'INFRABOX_JOB_TOKEN',
            'value': job_token
        }, {
            'name': 'INFRABOX_JOB_RESOURCES_LIMITS_MEMORY',
            'value': str(mem)
        }, {
            'name': 'INFRABOX_JOB_RESOURCES_LIMITS_CPU',
            'value': str(cpu)
        }]

        # Get ssh key for private repos
        cursor = self.conn.cursor()
        cursor.execute(
            '''
            SELECT p.type, p.id
            FROM project p
            JOIN job j
            ON j.project_id = p.id
            WHERE j.id = %s
        ''', [job_id])
        result = cursor.fetchone()
        cursor.close()

        project_type = result[0]
        project_id = result[1]

        private_key = ''
        if project_type == 'github':
            cursor = self.conn.cursor()
            cursor.execute(
                '''
                SELECT r.private_key
                FROM repository r
                WHERE r.project_id = %s
            ''', [project_id])
            result = cursor.fetchone()
            cursor.close()
            private_key = result[0]

            env += [{
                'name': 'INFRABOX_GIT_PORT',
                'value': '443'
            }, {
                'name': 'INFRABOX_GIT_HOSTNAME',
                'value': 'github.com'
            }]
        elif project_type == 'gerrit':
            with open('/tmp/gerrit/id_rsa') as key:
                env += [{
                    'name': 'INFRABOX_GIT_PORT',
                    'value': os.environ['INFRABOX_GERRIT_PORT']
                }, {
                    'name': 'INFRABOX_GIT_HOSTNAME',
                    'value': os.environ['INFRABOX_GERRIT_HOSTNAME']
                }]

                private_key = key.read()

        cursor = self.conn.cursor()
        cursor.execute(
            '''
            SELECT s.value
            FROM secret s
            JOIN sshkey k
            ON k.secret_id = s.id
            WHERE k.project_id = %s
            AND s.project_id = %s
        ''', [project_id, project_id])
        result = cursor.fetchall()
        cursor.close()

        for r in result:
            private_key = decrypt_secret(r[0])

        if private_key:
            env += [{'name': 'INFRABOX_GIT_PRIVATE_KEY', 'value': private_key}]

        root_url = os.environ['INFRABOX_ROOT_URL']

        if services:
            for s in services:
                if 'annotations' not in s['metadata']:
                    s['metadata']['annotations'] = {}

                s['metadata']['annotations']['infrabox.net/job-id'] = job_id
                s['metadata']['annotations'][
                    'infrabox.net/job-token'] = job_token
                s['metadata']['annotations'][
                    'infrabox.net/root-url'] = root_url

        job = {
            'apiVersion': 'core.infrabox.net/v1alpha1',
            'kind': 'IBPipelineInvocation',
            'metadata': {
                'name': job_id
            },
            'spec': {
                'pipelineName': 'infrabox-default-pipeline',
                'services': services,
                'steps': {
                    'run': {
                        'resources': {
                            'limits': {
                                'memory': '%sMi' % mem,
                                'cpu': cpu
                            }
                        },
                        'env': env,
                    }
                }
            }
        }

        r = requests.post(
            self.args.api_server +
            '/apis/core.infrabox.net/v1alpha1/namespaces/%s/ibpipelineinvocations'
            % self.namespace,
            headers=h,
            json=job,
            timeout=10)

        if r.status_code != 201:
            self.logger.warn(r.text)
            return False

        return True
Пример #3
0
        def get_secret(name, project_id=None):
            secret_type = get_secret_type(name)
            if secret_type == 'vault':
                vault = json.loads(name)
                vault_name = vault['$vault']
                secret_path = vault['$vault_secret_path']
                secret_key = vault['$vault_secret_key']

                if not project_id:
                    abort(
                        400,
                        "project_id is essential for getting Vault: '%s' " %
                        vault_name)

                result = g.db.execute_one(
                    """
                  SELECT url, version, token, ca, namespace, role_id, secret_id FROM vault WHERE name = %s and project_id = %s
                """, [vault_name, project_id])

                if not result:
                    abort(
                        400, "Cannot get Vault '%s' in project '%s' " %
                        (vault_name, project_id))

                url, version, token, ca, namespace, role_id, secret_id = result[
                    0], result[1], result[2], result[3], result[4], result[
                        5], result[6]
                if not namespace:
                    namespace = ''
                if version == 'v1':
                    url += '/v1/' + namespace + '/' + secret_path
                elif version == 'v2':
                    paths = secret_path.split('/')
                    url += '/v1/' + namespace + '/' + paths[
                        0] + '/data/' + '/'.join(paths[1:])
                # choose validate way
                validate_res = get_auth_type(result)
                if validate_res == 'token':
                    app.logger.info('validate way is token')
                elif validate_res == 'appRole':
                    app_role = {'role_id': role_id, 'secret_id': secret_id}
                    json_data = json.dumps(app_role)
                    app_role_url = result[
                        0] + '/v1/' + namespace + '/auth/approle/login'
                    res = requests.post(url=app_role_url,
                                        data=json_data,
                                        verify=False)
                    if res.status_code == 200:
                        json_res = json.loads(res.content)
                        token = json_res['auth']['client_token']
                    else:
                        abort(
                            400,
                            "Getting value from vault error: url is '%s', validate way is appRole "
                            % (url))
                else:
                    abort(
                        400, "Validate way is '%s' ! result is '%s' " %
                        (validate_res, result))

                if not ca:
                    res = requests.get(url=url,
                                       headers={'X-Vault-Token': token},
                                       verify=False)
                else:
                    with tempfile.NamedTemporaryFile(delete=False) as f:
                        f.write(ca)
                        f.flush()  # ensure all data written
                        res = requests.get(url=url,
                                           headers={'X-Vault-Token': token},
                                           verify=f.name)
                if res.status_code == 200:
                    json_res = json.loads(res.content)
                    if json_res['data'].get('data') and isinstance(
                            json_res['data'].get('data'), dict):
                        value = json_res['data'].get('data').get(secret_key)
                    else:
                        value = json_res['data'].get(secret_key)
                    return value
                else:
                    abort(
                        400,
                        "Getting value from vault error: url is '%s', token is '%s' "
                        % (url, result))
            else:
                if is_fork:
                    abort(
                        400, 'Access to secret %s is not allowed from a fork' %
                        name)

                for ev in secrets:
                    if ev[0] == name:
                        return decrypt_secret(ev[1])
                return None