def update_instance(self, instance_id, **kwargs): """Update an Instance status Args: instance_id (str): The Instance ID Keyword Args: new_status (str): The new status metadata (dict): Will be added to existing instance metadata Returns: Instance: The updated Instance """ operations = [] new_status = kwargs.pop("new_status", None) metadata = kwargs.pop("metadata", {}) if new_status: operations.append(PatchOperation("replace", "/status", new_status)) if metadata: operations.append(PatchOperation("update", "/metadata", metadata)) return self.client.patch_instance( instance_id, SchemaParser.serialize_patch(operations, many=True))
def update_request(self, request_id, status=None, output=None, error_class=None): """Set various fields on a request by PATCHing :param request_id: The ID of the request to update :param status: The new status :param output: The new output :param error_class: The new error class :return: The response """ operations = [] if status: operations.append(PatchOperation('replace', '/status', status)) if output: operations.append(PatchOperation('replace', '/output', output)) if error_class: operations.append( PatchOperation('replace', '/error_class', error_class)) response = self.client.patch_request( request_id, self.parser.serialize_patch(operations, many=True)) if response.ok: return self.parser.parse_request(response.json()) else: self._handle_response_failure(response, default_exc=SaveError)
def update_request(self, request_id, status=None, output=None, error_class=None): """Update a Request Args: request_id (str): The Request ID status (Optional[str]): New Request status output (Optional[str]): New Request output error_class (Optional[str]): New Request error class Returns: Response: The updated response """ operations = [] if status: operations.append(PatchOperation("replace", "/status", status)) if output: operations.append(PatchOperation("replace", "/output", output)) if error_class: operations.append( PatchOperation("replace", "/error_class", error_class)) return self.client.patch_request( request_id, self.parser.serialize_patch(operations, many=True))
class TestPatchOperation(object): @pytest.fixture def patch_operation(self): return PatchOperation(operation="op", path="path", value="value") @pytest.mark.parametrize( "operation,expected", [ (lazy_fixture("patch_operation"), "op, path, value"), (PatchOperation(operation="op"), "op, None, None"), ], ) def test_str(self, operation, expected): assert expected == str(operation) @pytest.mark.parametrize( "operation,expected", [ ( lazy_fixture("patch_operation"), "<Patch: operation=op, path=path, value=value>", ), ( PatchOperation(operation="op"), "<Patch: operation=op, path=None, value=None>", ), ], ) def test_repr(self, operation, expected): assert expected == repr(operation)
def test_patch_role_description( self, http_client, base_url, mongo_role, operation, value, expected_value, succeed, ): mongo_role.save() body = PatchOperation(operation=operation, path="/description", value=value) request = HTTPRequest( base_url + "/api/v1/roles/" + str(mongo_role.id), method="PATCH", headers={"content-type": "application/json"}, body=SchemaParser.serialize_patch(body), ) response = yield http_client.fetch(request, raise_error=False) if succeed: assert response.code == 200 updated = SchemaParser.parse_role(response.body.decode("utf-8"), from_string=True) assert updated.description == expected_value else: assert response.code >= 400
def stop_instance(client, instance, timeout=1, max_delay=1): response = client.client.patch_instance( instance.id, client.parser.serialize_patch(PatchOperation('stop'))) if 400 <= response.status_code < 500: raise ValidationError(response.json()) elif response.status_code >= 500: raise SaveError(response.json()) else: instance = client.parser.parse_instance(response.json()) instance = get_instance(client, instance.id) delay_time = 0.01 total_wait_time = 0 while instance.status not in ['DEAD', 'STOPPED', 'UNRESPONSIVE']: if timeout and total_wait_time > timeout: raise TimeoutError("Timed out waiting for instance to stop") time.sleep(delay_time) total_wait_time += delay_time delay_time = min(delay_time * 2, max_delay) instance = get_instance(client, instance.id) return instance
def test_patch_add_role(self, http_client, base_url, mongo_principal, mongo_role): mongo_role.save() mongo_principal.save() new_role = Role(name="new_role", description="Some desc", roles=[], permissions=["bg-all"]) new_role.save() body = PatchOperation(operation="add", path="/roles", value="new_role") url = base_url + "/api/v1/users/" + str(mongo_principal.id) request = HTTPRequest( url, method="PATCH", headers={"content-type": "application/json"}, body=SchemaParser.serialize_patch(body), ) response = yield http_client.fetch(request, raise_error=False) assert response.code == 200 updated = SchemaParser.parse_principal(response.body.decode("utf-8"), from_string=True) assert len(updated.roles) == 2
def test_update_garden_connection_info(self): child_garden_json = self.parser.serialize_garden( self._get_child_garden(), to_string=False) child_garden_json["connection_type"] = "STOMP" child_garden_json["connection_params"] = { "stomp": { "host": "activemq", "port": 61613, "send_destination": "Beer_Garden_Operations_Parent", "subscribe_destination": "Beer_Garden_Events_Parent", "username": "******", "password": "******", "ssl": { "use_ssl": False }, } } patch = PatchOperation(operation="config", path="", value=child_garden_json) payload = self.parser.serialize_patch(patch) updated_response = self.easy_client.client.session.patch( self.easy_client.client.base_url + "api/v1/gardens/" + self.child_garden_name, data=payload, headers=self.easy_client.client.JSON_HEADERS, ) assert updated_response.ok
def update_system(self, system_id, new_commands=None, **kwargs): """Update a System Args: system_id (str): The System ID new_commands (Optional[List[Command]]): New System commands Keyword Args: add_instance (Instance): An Instance to append metadata (dict): New System metadata description (str): New System description display_name (str): New System display name icon_name (str): New System icon name template (str): New System template Returns: System: The updated system """ operations = [] if new_commands is not None: commands = SchemaParser.serialize_command(new_commands, to_string=False, many=True) operations.append(PatchOperation("replace", "/commands", commands)) add_instance = kwargs.pop("add_instance", None) if add_instance: instance = SchemaParser.serialize_instance(add_instance, to_string=False) operations.append(PatchOperation("add", "/instance", instance)) metadata = kwargs.pop("metadata", {}) if metadata: operations.append(PatchOperation("update", "/metadata", metadata)) # The remaining kwargs are all strings # Sending an empty string (instead of None) ensures they're actually cleared for key, value in kwargs.items(): operations.append( PatchOperation("replace", "/%s" % key, value or "")) return self.client.patch_system( system_id, SchemaParser.serialize_patch(operations, many=True))
def rescan(self): """Rescan local plugin directory Returns: bool: True if rescan was successful """ return self.client.patch_admin(payload=SchemaParser.serialize_patch( PatchOperation(operation="rescan")))
class TestPatchOperation(object): @pytest.fixture def patch_operation(self): return PatchOperation(operation='op', path='path', value='value') @pytest.mark.parametrize('operation,expected', [ (lazy_fixture('patch_operation'), 'op, path, value'), (PatchOperation(operation='op'), 'op, None, None'), ]) def test_str(self, operation, expected): assert expected == str(operation) @pytest.mark.parametrize('operation,expected', [ (lazy_fixture('patch_operation'), '<Patch: operation=op, path=path, value=value>'), (PatchOperation(operation='op'), '<Patch: operation=op, path=None, value=None>'), ]) def test_repr(self, operation, expected): assert expected == repr(operation)
def pause_job(self, job_id): """Pause a Job by ID. Args: job_id: The ID of the job to pause. Returns: A copy of the job. """ self._patch_job(job_id, [PatchOperation('update', '/status', 'PAUSED')])
def resume_job(self, job_id): """Resume a job by ID. Args: job_id: The ID of the job to resume. Returns: A copy of the job. """ self._patch_job(job_id, [PatchOperation('update', '/status', 'RUNNING')])
def resume_job(self, job_id): """Resume a Job Args: job_id (str): The Job ID Returns: Job: The updated Job """ self._patch_job(job_id, [PatchOperation("update", "/status", "RUNNING")])
def pause_job(self, job_id): """Pause a Job Args: job_id (str): The Job ID Returns: Job: The updated Job """ self._patch_job(job_id, [PatchOperation("update", "/status", "PAUSED")])
def update_system(self, system_id, new_commands=None, **kwargs): """Update a system by PATCHing :param system_id: The ID of the system to update :param new_commands: The new commands :Keyword Arguments: * *metadata* (``dict``) The updated metadata for the system * *description* (``str``) The updated description for the system * *display_name* (``str``) The updated display_name for the system * *icon_name* (``str``) The updated icon_name for the system :return: The response """ operations = [] metadata = kwargs.pop("metadata", {}) if new_commands: operations.append( PatchOperation( 'replace', '/commands', self.parser.serialize_command(new_commands, to_string=False, many=True))) if metadata: operations.append(PatchOperation('update', '/metadata', metadata)) for attr, value in kwargs.items(): if value is not None: operations.append( PatchOperation('replace', '/%s' % attr, value)) response = self.client.patch_system( system_id, self.parser.serialize_patch(operations, many=True)) if response.ok: return self.parser.parse_system(response.json()) else: self._handle_response_failure(response, default_exc=SaveError)
def initialize_instance(self, instance_id): """Start an Instance Args: instance_id (str): The Instance ID Returns: Instance: The updated Instance """ return self.client.patch_instance( instance_id, self.parser.serialize_patch(PatchOperation("initialize")))
def instance_heartbeat(self, instance_id): """Send an Instance heartbeat Args: instance_id (str): The Instance ID Returns: bool: True if the heartbeat was successful """ return self.client.patch_instance( instance_id, self.parser.serialize_patch(PatchOperation("heartbeat")))
def instance_heartbeat(self, instance_id): """Send heartbeat for health and status :param instance_id: The ID of the instance :return: The response """ payload = PatchOperation('heartbeat') response = self.client.patch_instance( instance_id, self.parser.serialize_patch(payload)) if response.ok: return True else: self._handle_response_failure(response, default_exc=SaveError)
def initialize_instance(self, instance_id): """Start an instance by PATCHing :param instance_id: The ID of the instance to start :return: The start response """ response = self.client.patch_instance( instance_id, self.parser.serialize_patch(PatchOperation('initialize'))) if response.ok: return self.parser.parse_instance(response.json()) else: self._handle_response_failure(response, default_exc=SaveError)
def test_patch_commands( self, http_client, base_url, mongo_system, system_id, bg_command, field, value, dev, succeed, ): if dev: mongo_system.version += ".dev" mongo_system.deep_save() # Make changes to the new command if field: if field == "parameters": value = [value] setattr(bg_command, field, value) # Also delete the id, otherwise mongo gets really confused delattr(bg_command, "id") body = PatchOperation( operation="replace", path="/commands", value=SchemaParser.serialize_command( [bg_command], to_string=False, many=True ), ) request = HTTPRequest( base_url + "/api/v1/systems/" + system_id, method="PATCH", headers={"content-type": "application/json"}, body=SchemaParser.serialize_patch(body), ) response = yield http_client.fetch(request, raise_error=False) if succeed: assert response.code == 200 updated = SchemaParser.parse_system( response.body.decode("utf-8"), from_string=True ) assert_command_equal(bg_command, updated.commands[0]) else: assert response.code == 400
def update_system(self, system_id, new_commands=None, **kwargs): """Update a System Args: system_id (str): The System ID new_commands (Optional[List[Command]]): New System commands Keyword Args: metadata (dict): New System metadata description (str): New System description display_name (str): New System display name icon_name (str) The: New System icon name Returns: System: The updated system """ operations = [] metadata = kwargs.pop("metadata", {}) if new_commands: commands = self.parser.serialize_command(new_commands, to_string=False, many=True) operations.append(PatchOperation("replace", "/commands", commands)) if metadata: operations.append(PatchOperation("update", "/metadata", metadata)) for key, value in kwargs.items(): if value is not None: operations.append(PatchOperation("replace", "/%s" % key, value)) return self.client.patch_system( system_id, self.parser.serialize_patch(operations, many=True))
def update_instance_status(self, instance_id, new_status): """Update an instance by PATCHing :param instance_id: The ID of the instance to start :param new_status: The updated status :return: The start response """ payload = PatchOperation('replace', '/status', new_status) response = self.client.patch_instance( instance_id, self.parser.serialize_patch(payload)) if response.ok: return self.parser.parse_instance(response.json()) else: self._handle_response_failure(response, default_exc=SaveError)
def update_instance_status(self, instance_id, new_status): """Update an Instance status Args: instance_id (str): The Instance ID new_status (str): The new status Returns: Instance: The updated Instance """ return self.client.patch_instance( instance_id, self.parser.serialize_patch( PatchOperation("replace", "/status", new_status)), )
def test_run_sync(self): # Give BG a second to setup connection time.sleep(5) patch = PatchOperation(operation="sync", path='') payload = self.parser.serialize_patch(patch) response = self.easy_client.client.session.patch( self.easy_client.client.base_url + "api/v1/gardens/" + self.child_garden_name, data=payload, headers=self.easy_client.client.JSON_HEADERS) assert response.ok # Give BG a sync time.sleep(5)
def initialize_instance(self, instance_id, runner_id=None): """Start an Instance Args: instance_id (str): The Instance ID runner_id (str): The PluginRunner ID, if any Returns: Instance: The updated Instance """ return self.client.patch_instance( instance_id, SchemaParser.serialize_patch( PatchOperation(operation="initialize", value={"runner_id": runner_id})), )
def test_patch_password_update(self, http_client, base_url, mongo_principal, mongo_role): mongo_role.save() mongo_principal.save() body = PatchOperation(operation="update", path="/password", value="new_password") url = base_url + "/api/v1/users/" + str(mongo_principal.id) request = HTTPRequest( url, method="PATCH", headers={"content-type": "application/json"}, body=SchemaParser.serialize_patch(body), ) response = yield http_client.fetch(request, raise_error=False) assert response.code == 200
def test_update_garden_connection_info(self): child_garden = Garden(name=self.child_garden_name) payload = self.parser.serialize_garden(child_garden) response = self.easy_client.client.session.post( self.easy_client.client.base_url + "api/v1/gardens", data=payload, headers=self.easy_client.client.JSON_HEADERS) assert response.ok created_child = response.json() print(created_child) created_child['connection_type'] = "STOMP" created_child['connection_params'] = { "stomp": { "host": "activemq", "port": 61613, "send_destination": "Beer_Garden_Operations_Parent", "subscribe_destination": "Beer_Garden_Events_Parent", "username": "******", "password": "******", "ssl": { "use_ssl": False }, } } patch = PatchOperation(operation="config", path='', value=created_child) payload = self.parser.serialize_patch(patch) updated_response = self.easy_client.client.session.patch( self.easy_client.client.base_url + "api/v1/gardens/" + self.child_garden_name, data=payload, headers=self.easy_client.client.JSON_HEADERS) assert updated_response.ok
def test_patch_password_update_meta(self, http_client, base_url, mongo_principal, mongo_role): mongo_role.save() mongo_principal.metadata = {"auto_change": True, "changed": False} mongo_principal.save() body = PatchOperation(operation="update", path="/password", value="new_password") url = base_url + "/api/v1/users/" + str(mongo_principal.id) request = HTTPRequest( url, method="PATCH", headers={"content-type": "application/json"}, body=SchemaParser.serialize_patch(body), ) response = yield http_client.fetch(request, raise_error=False) assert response.code == 200 updated = SchemaParser.parse_principal(response.body.decode("utf-8"), from_string=True) assert updated.metadata.get("changed") is True
def test_update_garden_connection_info(self): response = self.easy_client.client.session.get( self.easy_client.client.base_url + "api/v1/gardens/") gardens = self.parser.parse_garden(response.json(), many=True) child_garden = None for garden in gardens: if garden.name == self.child_garden_name: child_garden = garden break child_garden.connection_type = "HTTP" child_garden.connection_params = { "http": { "host": "beer-garden-child", "port": 2337, "ssl": False } } patch = PatchOperation( operation="config", path="", value=self.parser.serialize_garden(child_garden, to_string=False), ) payload = self.parser.serialize_patch(patch) print(payload) response = self.easy_client.client.session.patch( self.easy_client.client.base_url + "api/v1/gardens/" + self.child_garden_name, data=payload, headers=self.easy_client.client.JSON_HEADERS, ) assert response.ok