def validate(self, value):
     if utils.is_string_type(value):
         try:
             value = json.loads(value)
         except JSONDecodeError as e:
             return str(e)
     if isinstance(value, collections.Mapping):
         value = [value]
     if utils.is_list_type(value):
         if len(value) < self.length_min:
             return _('length[%(length)s] < minimum length[%(minimum)s]') % {
                 'length': len(value),
                 'minimum': self.length_min
             }
         if self.length_max is not None and len(value) > self.length_max:
             return _('length[%(length)s] > maximum length[%(maximum)s]') % {
                 'length': len(value),
                 'maximum': self.length_max
             }
         for idx, item in enumerate(value):
             try:
                 self.validate_func(self.rules, item, self.situation)
             except exceptions.Error as e:
                 return _('validate failed for index[%(index)s], because: %(msg)s' % {
                     'index': idx + 1,
                     'msg': str(e)
                 })
     else:
         return _('expected type of list/tuple/set, not %(type)s ') % {'type': type(value).__name__}
     return True
 def validate(self, value):
     if not utils.is_string_type(value):
         return _('expected string, not %(type)s ') % {'type': type(value).__name__}
     if self._minimum <= len(value) and len(value) <= self._maximum:
         return True
     return _('length required: %(min)d <= %(value)d <= %(max)d') % {
         'min': self._minimum,
         'value': len(value),
         'max': self._maximum
     }
 def validate(self, value):
     if utils.is_string_type(value):
         try:
             value = json.loads(value)
         except JSONDecodeError as e:
             return str(e)
     if not isinstance(value, collections.Mapping):
         return _('type invalid: %(type)s, expected: %(expected)s') % {'type': type(value), 'expected': 'dict'}
     try:
         self.validate_func(self.rules, value, self.situation)
     except exceptions.Error as e:
         return _('validate failed , because: %(msg)s' % {'msg': str(e)})
     return True
예제 #4
0
 def download_file(self, filepath, access_key, secret_key):
     secure = True if self.schema == 'https' else False
     ca_certs = os.environ.get('SSL_CERT_FILE') or certifi.where()
     http_client = urllib3.PoolManager(
         timeout=3,
         maxsize=10,
         cert_reqs='CERT_REQUIRED',
         ca_certs=ca_certs,
         retries=urllib3.Retry(total=1,
                               backoff_factor=0.2,
                               status_forcelist=[500, 502, 503, 504]))
     client = minio.Minio(self.host,
                          access_key,
                          secret_key,
                          secure=secure,
                          http_client=http_client)
     try:
         return client.fget_object(self.bucket, self.object_key, filepath)
     except Exception as e:
         raise exceptions.PluginError(message=_(
             'failed to download file[%(filepath)s] from s3: %(reason)s') %
                                      {
                                          'filepath': self.object_key,
                                          'reason': str(e)
                                      })
 def on_patch(self, req, resp, **kwargs):
     self._validate_method(req)
     self._validate_data(req)
     datas = req.json
     if not utils.is_list_type(datas):
         raise exceptions.BodyParseError(_('must be list type'))
     rets = []
     ex_rets = []
     for idx, data in enumerate(datas):
         try:
             res_instance = self.make_resource(req)
             if res_instance.primary_keys not in data:
                 raise exceptions.FieldRequired(
                     attribute=res_instance.primary_keys)
             rid = data.pop(res_instance.primary_keys)
             before_update, after_update = self.update(req, data, rid=rid)
             if after_update is None:
                 raise exceptions.NotFoundError(
                     resource='%s[%s]' % (self.resource.__name__, rid))
             rets.append(after_update)
         except exceptions.Error as e:
             ex_rets.append({'index': idx + 1, 'message': str(e)})
     if len(ex_rets):
         raise my_exceptions.BatchPartialError(
             num=len(ex_rets),
             action='update',
             exception_data={'data': ex_rets})
     resp.json = {
         'code': 200,
         'status': 'OK',
         'data': rets,
         'message': 'success'
     }
     resp.status = falcon.HTTP_200
 def on_delete(self, req, resp, **kwargs):
     self._validate_method(req)
     self._validate_data(req)
     datas = req.json
     if not utils.is_list_type(datas):
         raise exceptions.BodyParseError(_('must be list type'))
     rets = []
     ex_rets = []
     for idx, data in enumerate(datas):
         try:
             res_instance = self.make_resource(req)
             ref_count, ref_details = self.delete(req, rid=data)
             rets.append(ref_details[0])
         except exceptions.Error as e:
             ex_rets.append({'index': idx + 1, 'message': str(e)})
     if len(ex_rets):
         raise my_exceptions.BatchPartialError(
             num=len(ex_rets),
             action='delete',
             exception_data={'data': ex_rets})
     resp.json = {
         'code': 200,
         'status': 'OK',
         'data': rets,
         'message': 'success'
     }
     resp.status = falcon.HTTP_200
 def validate(self, value):
     if self.cls_res().count(filters={'id': value}) == 0:
         return _('reference of %(resource)s(%(id)s) not found') % {
             'resource': self.cls_res.__name__,
             'id': value
         }
     return True
 def on_post(self, req, resp, **kwargs):
     self._validate_method(req)
     self._validate_data(req)
     datas = req.json
     if not utils.is_list_type(datas):
         raise exceptions.PluginError(_('data must be list type'))
     rets = []
     ex_rets = []
     for idx, data in enumerate(datas):
         try:
             rets.append(self.create(req, data, **kwargs))
         except base_ex.Error as e:
             ex_rets.append({'index': idx + 1, 'message': str(e)})
     if len(ex_rets):
         raise exceptions.BatchPartialError(
             num=len(ex_rets),
             action='create',
             exception_data={'data': ex_rets})
     resp.json = {
         'code': 200,
         'status': 'OK',
         'data': rets,
         'message': 'success'
     }
     resp.status = falcon.HTTP_200
def ensure_url_cached(url):
    '''download file form url, use cached file if available

    :param url: file url
    :type url: str
    :raises OSError: if timeout waiting for lock
    :return: local file path, filename
    :rtype: tuple(str, str)
    '''
    cache_dir = CONF.pakcage_cache_dir
    # make dir if not exist
    if not os.path.exists(cache_dir):
        os.makedirs(cache_dir, exist_ok=True)
    filename = url.rsplit('/', 1)[-1]
    new_filename = hashlib.sha1(url.encode()).hexdigest() + '-' + filename
    cached_file_path = os.path.join(cache_dir, new_filename)
    with plugin_utils.lock(new_filename, timeout=300) as locked:
        if locked:
            if os.path.exists(cached_file_path):
                LOG.info('using cache: %s for package: %s', cached_file_path, url)
            else:
                with tempfile.TemporaryDirectory() as download_path:
                    LOG.info('download from: %s for pakcage: %s', url, url)
                    filepath = download_from_url(download_path, url)
                    LOG.info('download complete')
                    os.rename(filepath, cached_file_path)
        else:
            raise OSError(_('failed to acquire lock, package cache may not be available'))
    return cached_file_path, filename
 def list(self, filters=None, orders=None, offset=None, limit=None, hooks=None):
     results = []
     service_name = filters.get('serviceName', '') or ''
     if not service_name:
         raise exceptions.FieldRequired(
             message=_('missing query param: %(attribute)s, eg. /v1/api?%(attribute)s=value') %
             {'attribute': 'serviceName'})
     client = wecube.WeCubeClient(CONF.wecube.base_url)
     # subsys_token = cache.get_or_create(TOKEN_KEY, client.login_subsystem, expires=600)
     # client.token = subsys_token
     key = '/platform/v1/plugins/interfaces/enabled'
     cached = cache.get(key, 15)
     if cache.validate(cached):
         resp = cached
     else:
         resp = client.retrieve('/platform/v1/plugins/interfaces/enabled')
         cache.set(key, resp)
     for interface in resp['data']:
         if interface['serviceName'] == service_name:
             for param in interface['inputParameters']:
                 results.append({
                     'type': param['dataType'],
                     'name': param['name'],
                     'value': 'inputParams.' + param['name']
                 })
     return results
예제 #11
0
 def _before_update(self, rid, resource, validate):
     super()._before_update(rid, resource, validate)
     if 'content_field' in resource and not resource[
             'content_field'] and 'endpoint_field' in resource and not resource[
                 'endpoint_field']:
         raise exceptions.ValidationError(
             attribute='content_field and endpoint_field',
             msg=_('specify at least one field content'))
예제 #12
0
 def __init__(self, url):
     self.url = url
     m = R_S3_ENDPOINT.match(url)
     if m:
         result = m.groupdict()
         self.schema = result['schema']
         self.host = result['host']
         self.bucket = result['bucket']
         self.object_key = result['object_key']
     else:
         raise ValueError(_('invalid s3 endpoint url, eg: schema://host[:port]/bucket/object'))
 def validate(self, value):
     choices = ['?', '+', '*']
     if utils.is_string_type(value):
         if value not in choices:
             return _('expected %(choices)s, not %(value)s') % {
                 'choices': choices,
                 'value': value
             }
     elif isinstance(value, int):
         if value < 1:
             return _('value should be >= 1, not %(value)s') % {
                 'value': value
             }
     else:
         return _(
             'expected string in %(choices)s or int(>=1), not %(type)s '
         ) % {
             'choices': choices,
             'type': type(value).__name__
         }
     return True
 def on_post(self, req, resp, **kwargs):
     download_url = req.params.get('downloadUrl', None)
     if not download_url:
         raise exceptions.ValidationError(
             message=_('missing query: downloadUrl'))
     form = cgi.FieldStorage(fp=req.stream, environ=req.env)
     resp.json = {
         'code': 200,
         'status': 'OK',
         'data': self.upload(req, download_url, **kwargs),
         'message': 'success'
     }
 def process_post(self, req, data, **kwargs):
     result = {
         'resultCode': '0',
         'resultMessage': 'success',
         'results': {
             'outputs': []
         }
     }
     is_item_error = False
     error_indexes = []
     try:
         clean_data = crud.ColumnValidator.get_clean_data(
             self._param_rules, data, 'check')
         reqid = clean_data.get('requestId', None) or 'N/A'
         operator = clean_data.get('operator', None) or 'N/A'
         for idx, item in enumerate(clean_data['inputs']):
             single_result = {
                 'callbackParameter': item.get('callbackParameter', None),
                 'errorCode': '0',
                 'errorMessage': 'success'
             }
             try:
                 validate_item_func = getattr(
                     self, 'validate_item_' + self._default_action,
                     self.validate_item)
                 clean_item = validate_item_func(idx, item)
                 process_func = getattr(self, self._default_action,
                                        self.process)
                 process_result = process_func(reqid, operator, idx,
                                               clean_item, **kwargs)
                 if process_result:
                     single_result.update(process_result)
                 result['results']['outputs'].append(single_result)
             except Exception as e:
                 LOG.exception(e)
                 single_result['errorCode'] = '1'
                 single_result['errorMessage'] = str(e)
                 result['results']['outputs'].append(single_result)
                 is_item_error = True
                 error_indexes.append(str(idx + 1))
     except Exception as e:
         LOG.exception(e)
         result['resultCode'] = '1'
         result['resultMessage'] = str(e)
     if is_item_error:
         result['resultCode'] = '1'
         result['resultMessage'] = _(
             'Fail to process [%(num)s] record, detail error in the data block'
         ) % dict(num=','.join(error_indexes))
     return result
 def remove(self, data):
     cluster_info = db_resource.Cluster().list({'name': data['cluster']})
     if not cluster_info:
         raise exceptions.ValidationError(attribute='cluster',
                                          msg=_('name of cluster(%(name)s) not found' % {'name': data['cluster']}))
     cluster_info = cluster_info[0]
     k8s_auth = k8s.AuthToken(cluster_info['api_server'], cluster_info['token'])
     k8s_client = k8s.Client(k8s_auth)
     resource_name = api_utils.escape_name(data['name'])
     exists_resource = k8s_client.get_service(resource_name, data['namespace'])
     if exists_resource is not None:
         k8s_client.delete_service(resource_name, data['namespace'])
     # TODO: k8s为异步接口,是否需要等待真正执行完毕
     return {'id': '', 'name': '', 'correlation_id': ''}
예제 #17
0
 def _json_or_error(url, **kwargs):
     try:
         try:
             return func(url, **kwargs)
         except requests.ConnectionError as e:
             LOG.error('http error: %s %s, reason: %s', func.__name__.upper(), url, str(e))
             raise base_ex.CallBackError(message={
                 'code': 50002,
                 'title': _('Connection Error'),
                 'description': _('Failed to establish a new connection')
             })
         except requests.Timeout as e:
             LOG.error('http error: %s %s, reason: %s', func.__name__.upper(), url, str(e))
             raise base_ex.CallBackError(message={
                 'code': 50004,
                 'title': _('Timeout Error'),
                 'description': _('Server do not respond')
             })
         except requests.HTTPError as e:
             LOG.error('http error: %s %s, reason: %s', func.__name__.upper(), url, str(e))
             code = int(e.response.status_code)
             message = RestfulJson.get_response_json(e.response, default={'code': code})
             if code == 401:
                 raise base_ex.AuthError()
             if code == 404:
                 message['title'] = _('Not Found')
                 message['description'] = _('The resource you request not exist')
             # 如果后台返回的数据不符合要求,强行修正
             if 'code' not in message:
                 message['code'] = code
             if 'title' not in message:
                 message['title'] = message.get('title', e.response.reason)
             if 'description' not in message:
                 message['description'] = message.get('message', str(e))
             raise base_ex.CallBackError(message=message)
         except Exception as e:
             LOG.error('http error: %s %s, reason: %s', func.__name__.upper(), url, str(e))
             message = RestfulJson.get_response_json(e.response,
                                                     default={
                                                         'code': 500,
                                                         'title': _('Server Error'),
                                                         'description': str(e)
                                                     })
             if 'code' not in message:
                 message['code'] = 500
             if 'title' not in message:
                 message['title'] = message.get('title', str(e))
             if 'description' not in message:
                 message['description'] = message.get('message', str(e))
             raise base_ex.CallBackError(message=message)
     except base_ex.CallBackError as e:
         raise exceptions.PluginError(message=e.message, error_code=e.code)
예제 #18
0
 def _addtional_validation(self, resource):
     if resource['effect_on'] == 'param' and resource['match_type'] not in (
             'filter', ):
         raise exceptions.ValidationError(
             attribute='match_type',
             msg=_(
                 '%(value)s is not acceptable, use %(fixed_value)s instead')
             % {
                 'value': resource['match_type'],
                 'fixed_value': 'filter'
             })
     if resource['effect_on'] == 'script' and resource[
             'match_type'] not in ('cli', 'sql', 'text', 'fulltext'):
         raise exceptions.ValidationError(
             attribute='match_type',
             msg=_(
                 '%(value)s is not acceptable, use %(fixed_value)s instead')
             % {
                 'value': resource['match_type'],
                 'fixed_value': ('cli', 'sql', 'text', 'fulltext')
             })
     if resource['effect_on'] == 'script' and resource[
             'match_type'] == 'cli' and not resource['match_param_id']:
         raise exceptions.FieldRequired(attribute='match_param_id')
    def script_check(self, data, boxes=None):
        '''run boxes rule check

        :param data: see function check
        :type data: dict
        :param boxes: box ids
        :type boxes: list
        :return: see function check
        :rtype: see function check
        '''
        # check box is enabled
        filters = {'policy.enabled': 1, 'subject.enabled': 1, 'enabled': 1}
        if boxes:
            filters['id'] = boxes
        refs = self.list(filters)
        results = self.check(data, boxes=refs, without_subject_test=False)
        associate_instances = data['entityInstances']
        text_output = ''
        if results:
            table = texttable.Texttable(max_width=120)
            # {
            # 'lineno': [start, end], 'level': level of rule,
            # 'content': content, 'message': rule name, 'script_name': script name
            # }
            table.set_cols_align(["l", "c", "l", "l", "l"])
            table.set_cols_valign(["m", "m", "m", "m", "m"])
            table.header([_("Instance Ids"), _("Line"), _("Content"), _("Message"), _('Source Script')])
            for ret in results:
                associate_ids = ','.join([(inst.get('displayName', '') or '#' + str(inst.get('id', '')))
                                          for inst in associate_instances])
                table.add_row([
                    associate_ids,
                    '%s-%s' % (ret['lineno'][0], ret['lineno'][1]), ret['content'], ret['message'], ret['script_name']
                ])
            text_output = table.draw()
        return {'text': text_output, 'data': results}
def convert_env(items):
    # convert envs
    rets = []
    for idx, item in enumerate(items):
        if 'valueRef' not in item:
            item['valueRef'] = None
        if 'valueFrom' not in item or not item['valueFrom']:
            item['valueFrom'] = 'value'
        if item['valueRef'] is None and item['valueFrom'] != 'value':
            raise exceptions.ValidationError(
                attribute='envs[%s]' % (idx + 1),
                msg=_('valueRef is NULL, while valueFrom is %(value)s') %
                {'value': item['valueFrom']})
        if item['valueFrom'] == 'value':
            rets.append({'name': item['name'], 'value': item['value']})
        elif item['valueFrom'] == 'configMap':
            rets.append({
                'name': item['name'],
                'valueFrom': {
                    'configMapKeyRef': {
                        'name': item['valueRef']['name'],
                        'key': item['valueRef']['value']
                    }
                }
            })
        elif item['valueFrom'] == 'secretKey':
            rets.append({
                'name': item['name'],
                'valueFrom': {
                    'secretKeyRef': {
                        'name': item['valueRef']['name'],
                        'key': item['valueRef']['value']
                    }
                }
            })
        elif item['valueFrom'] == 'fieldRef':
            rets.append({
                'name': item['name'],
                'valueFrom': {
                    'fieldRef': {
                        'fieldPath': item['valueRef']['name']
                    }
                }
            })
    return rets
 def on_patch(self, req, resp, **kwargs):
     self._validate_method(req)
     self._validate_data(req)
     data = req.json
     if data is not None and not isinstance(data, dict):
         raise exceptions.PluginError(_('data must be dict type'))
     ref_before, ref_after = self.update(req, data, **kwargs)
     if ref_after is not None:
         resp.json = {
             'code': 200,
             'status': 'OK',
             'data': ref_after,
             'message': 'success'
         }
     else:
         raise exceptions.NotFoundError(
             resource='%s[%s]' %
             (self.resource.__name__, kwargs.get('rid', '-')))
예제 #22
0
 def create(self, req, data):
     result = {'resultCode': '0', 'resultMessage': 'success', 'results': {'outputs': []}}
     is_error = False
     error_indexes = []
     try:
         clean_data = crud.ColumnValidator.get_clean_data(self.param_rules, data, 'check')
         operator = clean_data.get('operator', None) or 'N/A'
         for idx, item in enumerate(clean_data['inputs']):
             single_result = {
                 'callbackParameter': item.get('callbackParameter', None),
                 'errorCode': '0',
                 'errorMessage': 'success',
                 'guid': None,
                 'deploy_package_url': None
             }
             try:
                 clean_item = crud.ColumnValidator.get_clean_data(self.input_rules, item, 'check')
                 package = plugin_api.Package().create_from_image_name(clean_item['image_name'], clean_item['tag'],
                                                                       clean_item.get('namespace', None),
                                                                       clean_item.get('md5', None),
                                                                       clean_item.get('nexus_url', None),
                                                                       clean_item.get('connector_port', None),
                                                                       clean_item['unit_design'],
                                                                       clean_item.get('baseline_package',
                                                                                      None), operator)
                 single_result.update(package)
                 result['results']['outputs'].append(single_result)
             except Exception as e:
                 single_result['errorCode'] = '1'
                 single_result['errorMessage'] = str(e)
                 result['results']['outputs'].append(single_result)
                 is_error = True
                 error_indexes.append(str(idx + 1))
     except Exception as e:
         result['resultCode'] = '1'
         result['resultMessage'] = str(e)
     if is_error:
         result['resultCode'] = '1'
         result['resultMessage'] = _('Fail to %(action)s [%(num)s] record, detail error in the data block') % dict(
             action='process', num=','.join(error_indexes))
     return result
 def apply(self, data):
     resource_id = data['correlation_id']
     cluster_info = db_resource.Cluster().list({'name': data['cluster']})
     if not cluster_info:
         raise exceptions.ValidationError(attribute='cluster',
                                          msg=_('name of cluster(%(name)s) not found' % {'name': data['cluster']}))
     cluster_info = cluster_info[0]
     k8s_auth = k8s.AuthToken(cluster_info['api_server'], cluster_info['token'])
     k8s_client = k8s.Client(k8s_auth)
     k8s_client.ensure_namespace(data['namespace'])
     resource_name = api_utils.escape_name(data['name'])
     exists_resource = k8s_client.get_deployment(resource_name, data['namespace'])
     if exists_resource is None:
         exists_resource = k8s_client.create_deployment(data['namespace'], self.to_resource(k8s_client, data))
     else:
         exists_resource = k8s_client.update_deployment(resource_name, data['namespace'],
                                                        self.to_resource(k8s_client, data))
     # TODO: k8s为异步接口,是否需要等待真正执行完毕
     return {
         'id': exists_resource.metadata.uid,
         'name': exists_resource.metadata.name,
         'correlation_id': resource_id
     }
예제 #24
0
 def __call__(self, req, resp, package_name, entity_name, action_name):
     server = CONF.wecube.server
     token = req.auth_token
     client = wecube.WeCubeClient(server, token)
     url = '/platform/v1/packages/%(package_name)s/entities/%(entity_name)s/%(action_name)s' % {
         'package_name': package_name,
         'entity_name': entity_name,
         'action_name': action_name,
     }
     if action_name == 'retrieve':
         url = '/%(package_name)s/entities/%(entity_name)s/query' % {
             'package_name': package_name,
             'entity_name': entity_name
         }
         data = client.retrieve(url)
         resp.json = {
             'code': 200,
             'status': 'OK',
             'data': data['data'],
             'message': 'success'
         }
     elif action_name == 'update':
         data = client.update(url, req.json)
         resp.json = {
             'code': 200,
             'status': 'OK',
             'data': data['data'],
             'message': 'success'
         }
     else:
         raise exceptions.NotFoundError(
             _('%(action_name)s for %(package_name)s:%(entity_name)s not supported'
               ) % {
                   'package_name': package_name,
                   'entity_name': entity_name,
                   'action_name': action_name,
               })
 def update(self, req, data, **kwargs):
     operation = req.params.get('operation', None)
     if not operation:
         raise exceptions.ValidationError(message=_(
             'missing query: operation, eg. ?operation=confirm/discard'))
     return self.make_resource(req).update_state(data, operation)
 def message_format(self):
     return _(
         'fail to %(action)s [%(num)s] record, detail error in the data block'
     )
 def title(self):
     return _('Batch Operation Partial Error')
 def message_format(self):
     return _('the resource(%(resource)s) you request not found')
 def message_format(self):
     return _('column %(attribute)s validate failed, because: %(msg)s')
 def title(self):
     return _('Validation Error')