def check_license(self): license_info = get_licenser().validate() local_license_type = license_info.get('license_type', 'UNLICENSED') if local_license_type == 'UNLICENSED': logger.error(LICENSE_NON_EXISTANT_MESSAGE) raise PermissionDenied('No license found!') elif local_license_type == 'open': return instance_count = license_info.get('instance_count', 0) free_instances = license_info.get('free_instances', 0) time_remaining = license_info.get('time_remaining', 0) automated_count = license_info.get('automated_instances', 0) hard_error = license_info.get('trial', False) is True or license_info['instance_count'] == 10 if time_remaining <= 0: if hard_error: logger.error(LICENSE_EXPIRED_MESSAGE) raise PermissionDenied("Subscription has expired!") else: logger.warning(LICENSE_EXPIRED_MESSAGE) if free_instances < 0: d = { 'new_count': automated_count, 'instance_count': instance_count, } if hard_error: logger.error(LICENSE_MESSAGE % d) raise PermissionDenied('Subscription count exceeded!') else: logger.warning(LICENSE_MESSAGE % d)
def finalize_response(self, request, response, *args, **kwargs): ''' Log warning for 400 requests. Add header with elapsed time. ''' if response.status_code >= 400: status_msg = "status %s received by user %s attempting to access %s from %s" % \ (response.status_code, request.user, request.path, request.META.get('REMOTE_ADDR', None)) if hasattr(self, '__init_request_error__'): response = self.handle_exception(self.__init_request_error__) if response.status_code == 401: response.data['detail'] += ' To establish a login session, visit /api/login/.' logger.info(status_msg) else: logger.warning(status_msg) response = super(APIView, self).finalize_response(request, response, *args, **kwargs) time_started = getattr(self, 'time_started', None) response['X-API-Product-Version'] = get_awx_version() response['X-API-Product-Name'] = 'AWX' if isinstance(get_licenser(), StubLicense) else 'Red Hat Ansible Tower' response['X-API-Node'] = settings.CLUSTER_HOST_ID if time_started: time_elapsed = time.time() - self.time_started response['X-API-Time'] = '%0.3fs' % time_elapsed if getattr(settings, 'SQL_DEBUG', False): queries_before = getattr(self, 'queries_before', 0) q_times = [float(q['time']) for q in connection.queries[queries_before:]] response['X-API-Query-Count'] = len(q_times) response['X-API-Query-Time'] = '%0.3fs' % sum(q_times) if getattr(self, 'deprecated', False): response['Warning'] = '299 awx "This resource has been deprecated and will be removed in a future release."' # noqa return response
def handle(self, *args, **options): super(Command, self).__init__() license = get_licenser().validate() if options.get('data'): if license.get('license_key', '') != 'UNLICENSED': license['license_key'] = '********' return json.dumps(license) return license.get('license_type', 'none')
def finalize_response(self, request, response, *args, **kwargs): ''' Log warning for 400 requests. Add header with elapsed time. ''' # # If the URL was rewritten, and we get a 404, we should entirely # replace the view in the request context with an ApiErrorView() # Without this change, there will be subtle differences in the BrowseableAPIRenderer # # These differences could provide contextual clues which would allow # anonymous users to determine if usernames were valid or not # (e.g., if an anonymous user visited `/api/v2/users/valid/`, and got a 404, # but also saw that the page heading said "User Detail", they might notice # that's a difference in behavior from a request to `/api/v2/users/not-valid/`, which # would show a page header of "Not Found"). Changing the view here # guarantees that the rendered response will look exactly like the response # when you visit a URL that has no matching URL paths in `awx.api.urls`. # if response.status_code == 404 and 'awx.named_url_rewritten' in request.environ: self.headers.pop('Allow', None) response = super(APIView, self).finalize_response(request, response, *args, **kwargs) view = ApiErrorView() setattr(view, 'request', request) response.renderer_context['view'] = view return response if response.status_code >= 400: status_msg = "status %s received by user %s attempting to access %s from %s" % \ (response.status_code, request.user, request.path, request.META.get('REMOTE_ADDR', None)) if hasattr(self, '__init_request_error__'): response = self.handle_exception(self.__init_request_error__) if response.status_code == 401: response.data['detail'] += ' To establish a login session, visit /api/login/.' logger.info(status_msg) else: logger.warning(status_msg) response = super(APIView, self).finalize_response(request, response, *args, **kwargs) time_started = getattr(self, 'time_started', None) response['X-API-Product-Version'] = get_awx_version() response['X-API-Product-Name'] = 'AWX' if isinstance(get_licenser(), StubLicense) else 'Red Hat Ansible Tower' response['X-API-Node'] = settings.CLUSTER_HOST_ID if time_started: time_elapsed = time.time() - self.time_started response['X-API-Time'] = '%0.3fs' % time_elapsed if getattr(settings, 'SQL_DEBUG', False): queries_before = getattr(self, 'queries_before', 0) q_times = [float(q['time']) for q in connection.queries[queries_before:]] response['X-API-Query-Count'] = len(q_times) response['X-API-Query-Time'] = '%0.3fs' % sum(q_times) if getattr(self, 'deprecated', False): response['Warning'] = '299 awx "This resource has been deprecated and will be removed in a future release."' # noqa return response
def update_webhook_status(self, status): if not self.webhook_credential: return status_api = self.extra_vars_dict.get('awx_webhook_status_api') if not status_api: logger.debug("Webhook event did not have a status API endpoint associated, skipping.") return service_header = { 'github': ('Authorization', 'token {}'), 'gitlab': ('PRIVATE-TOKEN', '{}'), } service_statuses = { 'github': { 'pending': 'pending', 'successful': 'success', 'failed': 'failure', 'canceled': 'failure', # GitHub doesn't have a 'canceled' status :( 'error': 'error', }, 'gitlab': { 'pending': 'pending', 'running': 'running', 'successful': 'success', 'failed': 'failed', 'error': 'failed', # GitLab doesn't have an 'error' status distinct from 'failed' :( 'canceled': 'canceled', }, } statuses = service_statuses[self.webhook_service] if status not in statuses: logger.debug("Skipping webhook job status change: '{}'".format(status)) return try: license_type = get_licenser().validate().get('license_type') data = { 'state': statuses[status], 'context': 'ansible/awx' if license_type == 'open' else 'ansible/tower', 'target_url': self.get_ui_url(), } k, v = service_header[self.webhook_service] headers = {k: v.format(self.webhook_credential.get_input('token')), 'Content-Type': 'application/json'} response = requests.post(status_api, data=json.dumps(data), headers=headers, timeout=30) except Exception: logger.exception("Posting webhook status caused an error.") return if response.status_code < 400: logger.debug("Webhook status update sent.") else: logger.error("Posting webhook status failed, code: {}\n" "{}\n" "Payload sent: {}".format(response.status_code, response.text, json.dumps(data)))
def check_org_host_limit(self): license_info = get_licenser().validate() if license_info.get('license_type', 'UNLICENSED') == 'open': return org = self.inventory.organization if org is None or org.max_hosts == 0: return active_count = Host.objects.org_active_count(org.id) if active_count > org.max_hosts: raise PermissionDenied('Host limit for organization exceeded!')
def _get_validated_license_data(): from awx.main.utils import get_licenser return get_licenser().validate()
def handle(self, *args, **options): super(Command, self).__init__() return get_licenser().validate().get('license_type', 'none')
def handle(self, *args, **options): super(Command, self).__init__() license = get_licenser().validate() if options.get('data'): return json.dumps(license) return license.get('license_type', 'none')