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)))
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)
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'))
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))
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)