Example #1
0
    def _check_tarfile(self, app_tarfile, app_name, app_version, operation):
        def _handle_upload_failure(reason):
            raise wsme.exc.ClientSideError(
                _("Application-{} rejected: ".format(operation) + reason))

        if app_tarfile:
            if cutils.is_url(app_tarfile):
                # For tarfile that is downloaded remotely, defer the checksum, manifest
                # and tarfile content validations to sysinv-conductor as download can
                # take some time depending on network traffic, target server and file
                # size.
                if not app_name:
                    app_name = self._make_db_placeholder(
                        constants.APP_NAME_PLACEHOLDER, app_tarfile)
                if not app_version:
                    app_version = self._make_db_placeholder(
                        constants.APP_VERSION_PLACEHOLDER, app_tarfile)
                mname = constants.APP_MANIFEST_NAME_PLACEHOLDER
                mfile = constants.APP_TARFILE_NAME_PLACEHOLDER
                return app_name, app_version, mname, mfile

            if not os.path.isfile(app_tarfile):
                _handle_upload_failure(
                    "application tar file {} does not exist.".format(
                        app_tarfile))
            if (not app_tarfile.endswith('.tgz')
                    and not app_tarfile.endswith('.tar.gz')):
                _handle_upload_failure(
                    "{} has unrecognizable tar file extension. Supported "
                    "extensions are: .tgz and .tar.gz.".format(app_tarfile))

            with cutils.TempDirectory() as app_path:
                if not cutils.extract_tarfile(app_path, app_tarfile):
                    _handle_upload_failure(
                        "failed to extract tar file {}.".format(
                            os.path.basename(app_tarfile)))

                # If checksum file is included in the tarball, verify its contents.
                if not cutils.verify_checksum(app_path):
                    _handle_upload_failure("checksum validation failed.")

                app_helper = KubeAppHelper(pecan.request.dbapi)
                try:
                    name, version, patches = app_helper._verify_metadata_file(
                        app_path, app_name, app_version)
                    mname, mfile = app_helper._find_manifest_file(app_path)
                    app_helper._extract_helm_charts(app_path)
                    LOG.info("Tar file of application %s verified." % name)
                    return name, version, mname, mfile
                except exception.SysinvException as e:
                    _handle_upload_failure(str(e))
        else:
            raise ValueError(
                _("Application-{} rejected: tar file must be specified.".
                  format(operation)))
Example #2
0
    def post(self, body):
        """Uploading an application to be deployed by Armada"""

        self._check_environment()
        name = body.get('name')
        tarfile = body.get('tarfile')

        try:
            objects.kube_app.get_by_name(pecan.request.context, name)
            raise wsme.exc.ClientSideError(
                _("Application-upload rejected: application {} already exists."
                  .format(name)))
        except exception.KubeAppNotFound:
            pass

        if not cutils.is_url(tarfile):
            mname, mfile = self._check_tarfile(name, tarfile)
        else:
            # For tarfile that is downloaded remotely, defer the checksum, manifest
            # and tarfile content validations to sysinv-conductor as download can
            # take some time depending on network traffic, target server and file
            # size.
            mname = constants.APP_MANIFEST_NAME_PLACEHOLDER
            mfile = constants.APP_TARFILE_NAME_PLACEHOLDER

        # Create a database entry and make an rpc async request to upload
        # the application
        app_data = {
            'name': name,
            'manifest_name': mname,
            'manifest_file': os.path.basename(mfile),
            'status': constants.APP_UPLOAD_IN_PROGRESS
        }
        try:
            new_app = pecan.request.dbapi.kube_app_create(app_data)
        except exception.SysinvException as e:
            LOG.exception(e)
            raise

        pecan.request.rpcapi.perform_app_upload(pecan.request.context, new_app,
                                                tarfile)
        return KubeApp.convert_with_links(new_app)
Example #3
0
 def test_is_valid_url(self):
     self.assertTrue(utils.is_url('http://controller'))
     self.assertTrue(utils.is_url('https://controller'))
     self.assertFalse(utils.is_url('https://'))
     self.assertFalse(utils.is_url('//controller'))
Example #4
0
def _validate_docker_proxy_address(name, value):
    """Check if proxy value is valid"""
    if not cutils.is_url(value):
        raise wsme.exc.ClientSideError(_(
            "Parameter '%s' must be a valid address." % name))
Example #5
0
    def post(self, body):
        """Uploading an application to be deployed by Armada"""
        tarfile_path = body.get('tarfile')
        tarfile_binary = body.get('binary_data', '')
        name = body.get('name', '')
        version = body.get('app_version', '')
        images = body.get('images', False)

        if not cutils.is_url(tarfile_path) and not os.path.exists(
                tarfile_path):
            path_tarballs = '/tmp/tarball_uploads'
            if not os.path.exists(path_tarballs):
                os.makedirs(path_tarballs)
                uid, gid = pwd.getpwnam('sysinv').pw_uid, pwd.getpwnam(
                    'sysinv').pw_uid
                os.chown(path_tarballs, uid, gid)

            # Keep unique tarball name to avoid conflicts
            tarball_name = '{}-{}'.format(time.time(),
                                          os.path.basename(tarfile_path))
            tarfile_path = os.path.join(path_tarballs, tarball_name)
            try:
                with open(tarfile_path, 'wb') as f:
                    f.write(base64.urlsafe_b64decode(tarfile_binary))
            except Exception as e:
                LOG.exception('Error: writing the tarfile: {}'.format(e))
                raise wsme.exc.ClientSideError(
                    _("Could not save the application on path {}".format(
                        tarfile_path)))

        name, version, mname, mfile = self._check_tarfile(
            tarfile_path, name, version, constants.APP_UPLOAD_OP)

        try:
            objects.kube_app.get_by_name(pecan.request.context, name)
            raise wsme.exc.ClientSideError(
                _("Application-upload rejected: application {} already exists."
                  .format(name)))
        except exception.KubeAppNotFound:
            pass

        # Create a database entry and make an rpc async request to upload
        # the application
        app_data = {
            'name': name,
            'app_version': version,
            'manifest_name': mname,
            'manifest_file': os.path.basename(mfile),
            'status': constants.APP_UPLOAD_IN_PROGRESS
        }
        try:
            new_app = pecan.request.dbapi.kube_app_create(app_data)
        except exception.SysinvException as e:
            LOG.exception(e)
            raise

        lifecycle_hook_info = LifecycleHookInfo()
        lifecycle_hook_info.mode = constants.APP_LIFECYCLE_MODE_MANUAL

        pecan.request.rpcapi.perform_app_upload(
            pecan.request.context,
            new_app,
            tarfile_path,
            lifecycle_hook_info=lifecycle_hook_info,
            images=images)
        return KubeApp.convert_with_links(new_app)