diff --git a/.dockerignore b/.dockerignore index 5e6c3505694118ea3a8aae4f85d71d973f2f712a..fa3b07608a8e35d5d5c64e08afd68b7ea04d10d8 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,4 +7,7 @@ dump.rdb .cache .gitignore .gitlab-ci.yml -test/ \ No newline at end of file +test/ +venv/ +env/ + diff --git a/MANIFEST b/MANIFEST index 972b879bed92c29c4eeb163041884d2f85d55211..6253e9198a8b23ae4f0cb7d41bbbacc283042a43 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,2 +1,2 @@ -VERSION=v0.0.5 +VERSION=v0.0.6 SERVICE=evidence-collector diff --git a/README.md b/README.md index f06663c5bfb30783e4b314b40e8132a43abaddd9..1093fcbe4b78dda809af2f98edb9736fb4d9be72 100644 --- a/README.md +++ b/README.md @@ -77,15 +77,19 @@ $ ./entrypoint.sh ### Generate gRPC code from `.proto` files ``` -$ pip3 install grpcio-tools -$ python3 -m grpc_tools.protoc --proto_path=proto evidence.proto --python_out=evidence --grpc_python_out=evidence +pip3 install grpcio-tools # (included in requirements.txt) +python3 -m grpc_tools.protoc --proto_path=proto evidence.proto --python_out=grpc_gen --grpc_python_out=grpc_gen +python3 -m grpc_tools.protoc --proto_path=proto assessment.proto --python_out=grpc_gen --grpc_python_out=grpc_gen +python3 -m grpc_tools.protoc --proto_path=proto metric.proto --python_out=grpc_gen --grpc_python_out=grpc_gen ``` -As we are interacting with Clouditor, .proto files are taken from [there](https://github.com/clouditor/clouditor/tree/main/proto). +As we are interacting with Clouditor, .proto files are taken from [there](https://github.com/clouditor/clouditor/tree/main/proto). +Because of dependencies on Google APIs, .proto files in proto/google are taken from [here](https://github.com/googleapis/googleapis/tree/master/google/api). > Note: > since we are running the code as a package, we have to modify imports in newly generated code: -> `import evidence_pb2 as evidence__pb2` --> `import evidence.evidence_pb2 as evidence__pb2` +> `import evidence_pb2 as evidence__pb2` --> `import grpc_gen.evidence_pb2 as evidence__pb2` +> (check all generated files) ### API User authentication diff --git a/evidence/evidence_store_pb2.py b/evidence/evidence_store_pb2.py deleted file mode 100644 index 69bacf0ba8f930e6c78270ba3d27b2d8fe625d88..0000000000000000000000000000000000000000 --- a/evidence/evidence_store_pb2.py +++ /dev/null @@ -1,194 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: evidence_store.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -import evidence.evidence_pb2 as evidence__pb2 -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='evidence_store.proto', - package='clouditor', - syntax='proto3', - serialized_options=b'Z\014api/evidence', - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x14\x65vidence_store.proto\x12\tclouditor\x1a\x0e\x65vidence.proto\x1a\x1bgoogle/protobuf/empty.proto\"\'\n\x15StoreEvidenceResponse\x12\x0e\n\x06status\x18\x01 \x01(\x08\"\x16\n\x14ListEvidencesRequest\"?\n\x15ListEvidencesResponse\x12&\n\tevidences\x18\x01 \x03(\x0b\x32\x13.clouditor.Evidence2\xec\x01\n\rEvidenceStore\x12\x46\n\rStoreEvidence\x12\x13.clouditor.Evidence\x1a .clouditor.StoreEvidenceResponse\x12?\n\x0eStoreEvidences\x12\x13.clouditor.Evidence\x1a\x16.google.protobuf.Empty(\x01\x12R\n\rListEvidences\x12\x1f.clouditor.ListEvidencesRequest\x1a .clouditor.ListEvidencesResponseB\x0eZ\x0c\x61pi/evidenceb\x06proto3' - , - dependencies=[evidence__pb2.DESCRIPTOR,google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,]) - - - - -_STOREEVIDENCERESPONSE = _descriptor.Descriptor( - name='StoreEvidenceResponse', - full_name='clouditor.StoreEvidenceResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='clouditor.StoreEvidenceResponse.status', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=80, - serialized_end=119, -) - - -_LISTEVIDENCESREQUEST = _descriptor.Descriptor( - name='ListEvidencesRequest', - full_name='clouditor.ListEvidencesRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=121, - serialized_end=143, -) - - -_LISTEVIDENCESRESPONSE = _descriptor.Descriptor( - name='ListEvidencesResponse', - full_name='clouditor.ListEvidencesResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='evidences', full_name='clouditor.ListEvidencesResponse.evidences', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=145, - serialized_end=208, -) - -_LISTEVIDENCESRESPONSE.fields_by_name['evidences'].message_type = evidence__pb2._EVIDENCE -DESCRIPTOR.message_types_by_name['StoreEvidenceResponse'] = _STOREEVIDENCERESPONSE -DESCRIPTOR.message_types_by_name['ListEvidencesRequest'] = _LISTEVIDENCESREQUEST -DESCRIPTOR.message_types_by_name['ListEvidencesResponse'] = _LISTEVIDENCESRESPONSE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -StoreEvidenceResponse = _reflection.GeneratedProtocolMessageType('StoreEvidenceResponse', (_message.Message,), { - 'DESCRIPTOR' : _STOREEVIDENCERESPONSE, - '__module__' : 'evidence_store_pb2' - # @@protoc_insertion_point(class_scope:clouditor.StoreEvidenceResponse) - }) -_sym_db.RegisterMessage(StoreEvidenceResponse) - -ListEvidencesRequest = _reflection.GeneratedProtocolMessageType('ListEvidencesRequest', (_message.Message,), { - 'DESCRIPTOR' : _LISTEVIDENCESREQUEST, - '__module__' : 'evidence_store_pb2' - # @@protoc_insertion_point(class_scope:clouditor.ListEvidencesRequest) - }) -_sym_db.RegisterMessage(ListEvidencesRequest) - -ListEvidencesResponse = _reflection.GeneratedProtocolMessageType('ListEvidencesResponse', (_message.Message,), { - 'DESCRIPTOR' : _LISTEVIDENCESRESPONSE, - '__module__' : 'evidence_store_pb2' - # @@protoc_insertion_point(class_scope:clouditor.ListEvidencesResponse) - }) -_sym_db.RegisterMessage(ListEvidencesResponse) - - -DESCRIPTOR._options = None - -_EVIDENCESTORE = _descriptor.ServiceDescriptor( - name='EvidenceStore', - full_name='clouditor.EvidenceStore', - file=DESCRIPTOR, - index=0, - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_start=211, - serialized_end=447, - methods=[ - _descriptor.MethodDescriptor( - name='StoreEvidence', - full_name='clouditor.EvidenceStore.StoreEvidence', - index=0, - containing_service=None, - input_type=evidence__pb2._EVIDENCE, - output_type=_STOREEVIDENCERESPONSE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='StoreEvidences', - full_name='clouditor.EvidenceStore.StoreEvidences', - index=1, - containing_service=None, - input_type=evidence__pb2._EVIDENCE, - output_type=google_dot_protobuf_dot_empty__pb2._EMPTY, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='ListEvidences', - full_name='clouditor.EvidenceStore.ListEvidences', - index=2, - containing_service=None, - input_type=_LISTEVIDENCESREQUEST, - output_type=_LISTEVIDENCESRESPONSE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), -]) -_sym_db.RegisterServiceDescriptor(_EVIDENCESTORE) - -DESCRIPTOR.services_by_name['EvidenceStore'] = _EVIDENCESTORE - -# @@protoc_insertion_point(module_scope) diff --git a/evidence/evidence_store_pb2_grpc.py b/evidence/evidence_store_pb2_grpc.py deleted file mode 100644 index 3f037d76a6eb6f2613f258bd82d964c15115ecf8..0000000000000000000000000000000000000000 --- a/evidence/evidence_store_pb2_grpc.py +++ /dev/null @@ -1,140 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -import evidence.evidence_pb2 as evidence__pb2 -import evidence.evidence_store_pb2 as evidence__store__pb2 -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 - - -class EvidenceStoreStub(object): - """Manages the storage of evidences - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.StoreEvidence = channel.unary_unary( - '/clouditor.EvidenceStore/StoreEvidence', - request_serializer=evidence__pb2.Evidence.SerializeToString, - response_deserializer=evidence__store__pb2.StoreEvidenceResponse.FromString, - ) - self.StoreEvidences = channel.stream_unary( - '/clouditor.EvidenceStore/StoreEvidences', - request_serializer=evidence__pb2.Evidence.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.ListEvidences = channel.unary_unary( - '/clouditor.EvidenceStore/ListEvidences', - request_serializer=evidence__store__pb2.ListEvidencesRequest.SerializeToString, - response_deserializer=evidence__store__pb2.ListEvidencesResponse.FromString, - ) - - -class EvidenceStoreServicer(object): - """Manages the storage of evidences - """ - - def StoreEvidence(self, request, context): - """Stores an evidence to the evidence storage - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def StoreEvidences(self, request_iterator, context): - """Stores a stream of evidences to the evidence storage - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListEvidences(self, request, context): - """Returns the evidences lying in the evidence storage - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_EvidenceStoreServicer_to_server(servicer, server): - rpc_method_handlers = { - 'StoreEvidence': grpc.unary_unary_rpc_method_handler( - servicer.StoreEvidence, - request_deserializer=evidence__pb2.Evidence.FromString, - response_serializer=evidence__store__pb2.StoreEvidenceResponse.SerializeToString, - ), - 'StoreEvidences': grpc.stream_unary_rpc_method_handler( - servicer.StoreEvidences, - request_deserializer=evidence__pb2.Evidence.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'ListEvidences': grpc.unary_unary_rpc_method_handler( - servicer.ListEvidences, - request_deserializer=evidence__store__pb2.ListEvidencesRequest.FromString, - response_serializer=evidence__store__pb2.ListEvidencesResponse.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'clouditor.EvidenceStore', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class EvidenceStore(object): - """Manages the storage of evidences - """ - - @staticmethod - def StoreEvidence(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/clouditor.EvidenceStore/StoreEvidence', - evidence__pb2.Evidence.SerializeToString, - evidence__store__pb2.StoreEvidenceResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def StoreEvidences(request_iterator, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.stream_unary(request_iterator, target, '/clouditor.EvidenceStore/StoreEvidences', - evidence__pb2.Evidence.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListEvidences(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/clouditor.EvidenceStore/ListEvidences', - evidence__store__pb2.ListEvidencesRequest.SerializeToString, - evidence__store__pb2.ListEvidencesResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/evidence/generate_evidence.py b/evidence/generate_evidence.py deleted file mode 100644 index 9e0e53c2cf965d453d50589a8f5af59ca89c6364..0000000000000000000000000000000000000000 --- a/evidence/generate_evidence.py +++ /dev/null @@ -1,34 +0,0 @@ -import json -from evidence.evidence_pb2 import Evidence - -# Used if user doesn't provide other -_default_resource_type = ["VirtualMachine", "Compute", "Resource"] - -def create_resource(id, name, type, property_list): - resource = { - "id": str(id), - "name": str(name), - "type": type if type is not None else _default_resource_type - } - - if property_list is not None: - resource.update(property_list) - - return resource - -def create_evidence(id, service_id, tool_id, raw, resource): - evidence = Evidence() - - evidence.id = str(id) - evidence.timestamp.GetCurrentTime() - evidence.timestamp.nanos = 0 - evidence.service_id = service_id - evidence.tool_id = tool_id - evidence.raw = json.dumps(raw) - evidence.resource.struct_value.update(resource) - - return evidence - -def print_evidence(logger, evidence): - evidence.raw = evidence.raw[:50] + "..." - logger.debug(evidence) \ No newline at end of file diff --git a/forward_evidence/forward_evidence.py b/forward_evidence/forward_evidence.py index bc2d5f5a215e52354f6ab9960fab3e6ee24aab1d..59ddc12262f6980a57eb6c39e0ab277c35e82e7c 100644 --- a/forward_evidence/forward_evidence.py +++ b/forward_evidence/forward_evidence.py @@ -1,21 +1,18 @@ -from evidence.evidence_store_pb2_grpc import EvidenceStoreStub -from evidence.evidence_pb2 import Evidence +from grpc_gen.assessment_pb2_grpc import AssessmentStub import grpc class ForwardEvidence(object): def __init__(self, constants, logger): self.channel = grpc.insecure_channel('{}:{}'.format(constants['clouditor']['host'], constants['clouditor']['port'])) - self.stub = EvidenceStoreStub(self.channel) + self.stub = AssessmentStub(self.channel) self.logger = logger - def send_evidence(self, evidence): + def send_evidence(self, assessevidencerequest): try: - response = self.stub.StoreEvidence(evidence) + response = self.stub.AssessEvidence(assessevidencerequest) self.logger.info('gRPC evidence forwarded: ' + str(response)) except grpc.RpcError as err: self.logger.error(err) self.logger.error(err.details()) self.logger.error('{}, {}'.format(err.code().name, err.code().value)) - - diff --git a/forward_evidence/generate_evidence.py b/forward_evidence/generate_evidence.py new file mode 100644 index 0000000000000000000000000000000000000000..c8a5a6b3de7f2ad1e966e1cf6ff66b718f318d60 --- /dev/null +++ b/forward_evidence/generate_evidence.py @@ -0,0 +1,33 @@ +import json +from grpc_gen.assessment_pb2 import AssessEvidenceRequest + +# Used if user doesn't provide other +_default_resource_type = ["VirtualMachine", "Compute", "Resource"] + +def create_resource(id, name, type, property_list): + resource = { + "id": str(id), + "name": str(name), + "type": type if type is not None else _default_resource_type + } + + if property_list is not None: + resource.update(property_list) + + return resource + +def create_assessevidence_request(id, service_id, tool_id, raw, resource): + aer = AssessEvidenceRequest() + aer.evidence.id = str(id) + aer.evidence.timestamp.GetCurrentTime() + aer.evidence.timestamp.nanos = 0 + aer.evidence.service_id = service_id + aer.evidence.tool_id = tool_id + aer.evidence.raw = json.dumps(raw) + aer.evidence.resource.struct_value.update(resource) + + return aer + +def print_evidence(logger, evidence): + evidence.raw = evidence.raw[:50] + "..." + logger.debug(evidence) diff --git a/grpc_gen/assessment_pb2.py b/grpc_gen/assessment_pb2.py new file mode 100644 index 0000000000000000000000000000000000000000..82565b59197df54cea14cf6da5e88682d957b257 --- /dev/null +++ b/grpc_gen/assessment_pb2.py @@ -0,0 +1,379 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: assessment.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 +from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 +import grpc_gen.evidence_pb2 as evidence__pb2 +import grpc_gen.metric_pb2 as metric__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='assessment.proto', + package='clouditor', + syntax='proto3', + serialized_options=b'Z\016api/assessment', + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x10\x61ssessment.proto\x12\tclouditor\x1a\x1cgoogle/api/annotations.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x0e\x65vidence.proto\x1a\x0cmetric.proto\".\n\x18TriggerAssessmentRequest\x12\x12\n\nsomeOption\x18\x01 \x01(\t\"\x1e\n\x1cListAssessmentResultsRequest\"C\n\x1dListAssessmentResultsResponse\x12\"\n\x07results\x18\x01 \x03(\x0b\x32\x11.clouditor.Result\">\n\x15\x41ssessEvidenceRequest\x12%\n\x08\x65vidence\x18\x01 \x01(\x0b\x32\x13.clouditor.Evidence\"(\n\x16\x41ssessEvidenceResponse\x12\x0e\n\x06status\x18\x01 \x01(\x08\"\xe9\x01\n\x06Result\x12\n\n\x02id\x18\x01 \x01(\t\x12-\n\ttimestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x11\n\tmetric_id\x18\x03 \x01(\t\x12\x33\n\x0bmetric_data\x18\x04 \x01(\x0b\x32\x1e.clouditor.MetricConfiguration\x12\x11\n\tcompliant\x18\x05 \x01(\x08\x12\x13\n\x0b\x65vidence_id\x18\x06 \x01(\t\x12\x13\n\x0bresource_id\x18\x07 \x01(\t\x12\x1f\n\x17non_compliance_comments\x18\x08 \x01(\t2\xae\x03\n\nAssessment\x12R\n\x11TriggerAssessment\x12#.clouditor.TriggerAssessmentRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x8d\x01\n\x15ListAssessmentResults\x12\'.clouditor.ListAssessmentResultsRequest\x1a(.clouditor.ListAssessmentResultsResponse\"!\x82\xd3\xe4\x93\x02\x1b\"\x16/v1/assessment/resultsb\x01*\x12z\n\x0e\x41ssessEvidence\x12 .clouditor.AssessEvidenceRequest\x1a!.clouditor.AssessEvidenceResponse\"#\x82\xd3\xe4\x93\x02\x1d\"\x18/v1/assessment/evidencesb\x01*\x12@\n\x0f\x41ssessEvidences\x12\x13.clouditor.Evidence\x1a\x16.google.protobuf.Empty(\x01\x42\x10Z\x0e\x61pi/assessmentb\x06proto3' + , + dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,evidence__pb2.DESCRIPTOR,metric__pb2.DESCRIPTOR,]) + + + + +_TRIGGERASSESSMENTREQUEST = _descriptor.Descriptor( + name='TriggerAssessmentRequest', + full_name='clouditor.TriggerAssessmentRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='someOption', full_name='clouditor.TriggerAssessmentRequest.someOption', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=153, + serialized_end=199, +) + + +_LISTASSESSMENTRESULTSREQUEST = _descriptor.Descriptor( + name='ListAssessmentResultsRequest', + full_name='clouditor.ListAssessmentResultsRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=201, + serialized_end=231, +) + + +_LISTASSESSMENTRESULTSRESPONSE = _descriptor.Descriptor( + name='ListAssessmentResultsResponse', + full_name='clouditor.ListAssessmentResultsResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='results', full_name='clouditor.ListAssessmentResultsResponse.results', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=233, + serialized_end=300, +) + + +_ASSESSEVIDENCEREQUEST = _descriptor.Descriptor( + name='AssessEvidenceRequest', + full_name='clouditor.AssessEvidenceRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='evidence', full_name='clouditor.AssessEvidenceRequest.evidence', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=302, + serialized_end=364, +) + + +_ASSESSEVIDENCERESPONSE = _descriptor.Descriptor( + name='AssessEvidenceResponse', + full_name='clouditor.AssessEvidenceResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='status', full_name='clouditor.AssessEvidenceResponse.status', index=0, + number=1, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=366, + serialized_end=406, +) + + +_RESULT = _descriptor.Descriptor( + name='Result', + full_name='clouditor.Result', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='clouditor.Result.id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='timestamp', full_name='clouditor.Result.timestamp', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='metric_id', full_name='clouditor.Result.metric_id', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='metric_data', full_name='clouditor.Result.metric_data', index=3, + number=4, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='compliant', full_name='clouditor.Result.compliant', index=4, + number=5, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='evidence_id', full_name='clouditor.Result.evidence_id', index=5, + number=6, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='resource_id', full_name='clouditor.Result.resource_id', index=6, + number=7, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='non_compliance_comments', full_name='clouditor.Result.non_compliance_comments', index=7, + number=8, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=409, + serialized_end=642, +) + +_LISTASSESSMENTRESULTSRESPONSE.fields_by_name['results'].message_type = _RESULT +_ASSESSEVIDENCEREQUEST.fields_by_name['evidence'].message_type = evidence__pb2._EVIDENCE +_RESULT.fields_by_name['timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP +_RESULT.fields_by_name['metric_data'].message_type = metric__pb2._METRICCONFIGURATION +DESCRIPTOR.message_types_by_name['TriggerAssessmentRequest'] = _TRIGGERASSESSMENTREQUEST +DESCRIPTOR.message_types_by_name['ListAssessmentResultsRequest'] = _LISTASSESSMENTRESULTSREQUEST +DESCRIPTOR.message_types_by_name['ListAssessmentResultsResponse'] = _LISTASSESSMENTRESULTSRESPONSE +DESCRIPTOR.message_types_by_name['AssessEvidenceRequest'] = _ASSESSEVIDENCEREQUEST +DESCRIPTOR.message_types_by_name['AssessEvidenceResponse'] = _ASSESSEVIDENCERESPONSE +DESCRIPTOR.message_types_by_name['Result'] = _RESULT +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +TriggerAssessmentRequest = _reflection.GeneratedProtocolMessageType('TriggerAssessmentRequest', (_message.Message,), { + 'DESCRIPTOR' : _TRIGGERASSESSMENTREQUEST, + '__module__' : 'assessment_pb2' + # @@protoc_insertion_point(class_scope:clouditor.TriggerAssessmentRequest) + }) +_sym_db.RegisterMessage(TriggerAssessmentRequest) + +ListAssessmentResultsRequest = _reflection.GeneratedProtocolMessageType('ListAssessmentResultsRequest', (_message.Message,), { + 'DESCRIPTOR' : _LISTASSESSMENTRESULTSREQUEST, + '__module__' : 'assessment_pb2' + # @@protoc_insertion_point(class_scope:clouditor.ListAssessmentResultsRequest) + }) +_sym_db.RegisterMessage(ListAssessmentResultsRequest) + +ListAssessmentResultsResponse = _reflection.GeneratedProtocolMessageType('ListAssessmentResultsResponse', (_message.Message,), { + 'DESCRIPTOR' : _LISTASSESSMENTRESULTSRESPONSE, + '__module__' : 'assessment_pb2' + # @@protoc_insertion_point(class_scope:clouditor.ListAssessmentResultsResponse) + }) +_sym_db.RegisterMessage(ListAssessmentResultsResponse) + +AssessEvidenceRequest = _reflection.GeneratedProtocolMessageType('AssessEvidenceRequest', (_message.Message,), { + 'DESCRIPTOR' : _ASSESSEVIDENCEREQUEST, + '__module__' : 'assessment_pb2' + # @@protoc_insertion_point(class_scope:clouditor.AssessEvidenceRequest) + }) +_sym_db.RegisterMessage(AssessEvidenceRequest) + +AssessEvidenceResponse = _reflection.GeneratedProtocolMessageType('AssessEvidenceResponse', (_message.Message,), { + 'DESCRIPTOR' : _ASSESSEVIDENCERESPONSE, + '__module__' : 'assessment_pb2' + # @@protoc_insertion_point(class_scope:clouditor.AssessEvidenceResponse) + }) +_sym_db.RegisterMessage(AssessEvidenceResponse) + +Result = _reflection.GeneratedProtocolMessageType('Result', (_message.Message,), { + 'DESCRIPTOR' : _RESULT, + '__module__' : 'assessment_pb2' + # @@protoc_insertion_point(class_scope:clouditor.Result) + }) +_sym_db.RegisterMessage(Result) + + +DESCRIPTOR._options = None + +_ASSESSMENT = _descriptor.ServiceDescriptor( + name='Assessment', + full_name='clouditor.Assessment', + file=DESCRIPTOR, + index=0, + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_start=645, + serialized_end=1075, + methods=[ + _descriptor.MethodDescriptor( + name='TriggerAssessment', + full_name='clouditor.Assessment.TriggerAssessment', + index=0, + containing_service=None, + input_type=_TRIGGERASSESSMENTREQUEST, + output_type=google_dot_protobuf_dot_empty__pb2._EMPTY, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), + _descriptor.MethodDescriptor( + name='ListAssessmentResults', + full_name='clouditor.Assessment.ListAssessmentResults', + index=1, + containing_service=None, + input_type=_LISTASSESSMENTRESULTSREQUEST, + output_type=_LISTASSESSMENTRESULTSRESPONSE, + serialized_options=b'\202\323\344\223\002\033\"\026/v1/assessment/resultsb\001*', + create_key=_descriptor._internal_create_key, + ), + _descriptor.MethodDescriptor( + name='AssessEvidence', + full_name='clouditor.Assessment.AssessEvidence', + index=2, + containing_service=None, + input_type=_ASSESSEVIDENCEREQUEST, + output_type=_ASSESSEVIDENCERESPONSE, + serialized_options=b'\202\323\344\223\002\035\"\030/v1/assessment/evidencesb\001*', + create_key=_descriptor._internal_create_key, + ), + _descriptor.MethodDescriptor( + name='AssessEvidences', + full_name='clouditor.Assessment.AssessEvidences', + index=3, + containing_service=None, + input_type=evidence__pb2._EVIDENCE, + output_type=google_dot_protobuf_dot_empty__pb2._EMPTY, + serialized_options=None, + create_key=_descriptor._internal_create_key, + ), +]) +_sym_db.RegisterServiceDescriptor(_ASSESSMENT) + +DESCRIPTOR.services_by_name['Assessment'] = _ASSESSMENT + +# @@protoc_insertion_point(module_scope) diff --git a/grpc_gen/assessment_pb2_grpc.py b/grpc_gen/assessment_pb2_grpc.py new file mode 100644 index 0000000000000000000000000000000000000000..11ab55b4c068b68e4a91722562a644bddf4b0d62 --- /dev/null +++ b/grpc_gen/assessment_pb2_grpc.py @@ -0,0 +1,182 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +import grpc_gen.assessment_pb2 as assessment__pb2 +import grpc_gen.evidence_pb2 as evidence__pb2 +from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 + + +class AssessmentStub(object): + """Representing the link between orchestrator and discovery: Assessing evidences + from discovery and sending results to orchestrator + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.TriggerAssessment = channel.unary_unary( + '/clouditor.Assessment/TriggerAssessment', + request_serializer=assessment__pb2.TriggerAssessmentRequest.SerializeToString, + response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + ) + self.ListAssessmentResults = channel.unary_unary( + '/clouditor.Assessment/ListAssessmentResults', + request_serializer=assessment__pb2.ListAssessmentResultsRequest.SerializeToString, + response_deserializer=assessment__pb2.ListAssessmentResultsResponse.FromString, + ) + self.AssessEvidence = channel.unary_unary( + '/clouditor.Assessment/AssessEvidence', + request_serializer=assessment__pb2.AssessEvidenceRequest.SerializeToString, + response_deserializer=assessment__pb2.AssessEvidenceResponse.FromString, + ) + self.AssessEvidences = channel.stream_unary( + '/clouditor.Assessment/AssessEvidences', + request_serializer=evidence__pb2.Evidence.SerializeToString, + response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + ) + + +class AssessmentServicer(object): + """Representing the link between orchestrator and discovery: Assessing evidences + from discovery and sending results to orchestrator + """ + + def TriggerAssessment(self, request, context): + """Triggers the assessment. Part of the private API, + not exposed as REST. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ListAssessmentResults(self, request, context): + """TODO(all): Part of public API because external entities (mainly + discoveries) can use it? List the latest set of assessment results. Part of + the public API, also exposed as REST + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def AssessEvidence(self, request, context): + """Assesses the evidence sent by discovery. Part of the public API, + also exposed as REST + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def AssessEvidences(self, request_iterator, context): + """Assesses stream of evidences coming from the discovery. Part of the public + API, not exposed as REST + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_AssessmentServicer_to_server(servicer, server): + rpc_method_handlers = { + 'TriggerAssessment': grpc.unary_unary_rpc_method_handler( + servicer.TriggerAssessment, + request_deserializer=assessment__pb2.TriggerAssessmentRequest.FromString, + response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + ), + 'ListAssessmentResults': grpc.unary_unary_rpc_method_handler( + servicer.ListAssessmentResults, + request_deserializer=assessment__pb2.ListAssessmentResultsRequest.FromString, + response_serializer=assessment__pb2.ListAssessmentResultsResponse.SerializeToString, + ), + 'AssessEvidence': grpc.unary_unary_rpc_method_handler( + servicer.AssessEvidence, + request_deserializer=assessment__pb2.AssessEvidenceRequest.FromString, + response_serializer=assessment__pb2.AssessEvidenceResponse.SerializeToString, + ), + 'AssessEvidences': grpc.stream_unary_rpc_method_handler( + servicer.AssessEvidences, + request_deserializer=evidence__pb2.Evidence.FromString, + response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'clouditor.Assessment', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class Assessment(object): + """Representing the link between orchestrator and discovery: Assessing evidences + from discovery and sending results to orchestrator + """ + + @staticmethod + def TriggerAssessment(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/clouditor.Assessment/TriggerAssessment', + assessment__pb2.TriggerAssessmentRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def ListAssessmentResults(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/clouditor.Assessment/ListAssessmentResults', + assessment__pb2.ListAssessmentResultsRequest.SerializeToString, + assessment__pb2.ListAssessmentResultsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def AssessEvidence(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/clouditor.Assessment/AssessEvidence', + assessment__pb2.AssessEvidenceRequest.SerializeToString, + assessment__pb2.AssessEvidenceResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def AssessEvidences(request_iterator, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.stream_unary(request_iterator, target, '/clouditor.Assessment/AssessEvidences', + evidence__pb2.Evidence.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/evidence/evidence_pb2.py b/grpc_gen/evidence_pb2.py similarity index 100% rename from evidence/evidence_pb2.py rename to grpc_gen/evidence_pb2.py diff --git a/evidence/evidence_pb2_grpc.py b/grpc_gen/evidence_pb2_grpc.py similarity index 100% rename from evidence/evidence_pb2_grpc.py rename to grpc_gen/evidence_pb2_grpc.py diff --git a/grpc_gen/metric_pb2.py b/grpc_gen/metric_pb2.py new file mode 100644 index 0000000000000000000000000000000000000000..433292da9cf1322f1650520ceaa240ab70951a81 --- /dev/null +++ b/grpc_gen/metric_pb2.py @@ -0,0 +1,397 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: metric.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='metric.proto', + package='clouditor', + syntax='proto3', + serialized_options=b'Z\016api/assessment', + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x0cmetric.proto\x12\tclouditor\x1a\x1cgoogle/protobuf/struct.proto\"\xc1\x01\n\x06Metric\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x10\n\x08\x63\x61tegory\x18\x04 \x01(\t\x12&\n\x05scale\x18\x05 \x01(\x0e\x32\x17.clouditor.Metric.Scale\x12\x1f\n\x05range\x18\x06 \x01(\x0b\x32\x10.clouditor.Range\"-\n\x05Scale\x12\x0b\n\x07NOMIMAL\x10\x00\x12\x0b\n\x07ORDINAL\x10\x01\x12\n\n\x06METRIC\x10\x02\"\x8d\x01\n\x05Range\x12\x32\n\x0e\x61llowed_values\x18\x01 \x01(\x0b\x32\x18.clouditor.AllowedValuesH\x00\x12!\n\x05order\x18\x02 \x01(\x0b\x32\x10.clouditor.OrderH\x00\x12$\n\x07min_max\x18\x03 \x01(\x0b\x32\x11.clouditor.MinMaxH\x00\x42\x07\n\x05range\"\"\n\x06MinMax\x12\x0b\n\x03min\x18\x01 \x01(\x03\x12\x0b\n\x03max\x18\x02 \x01(\x03\"7\n\rAllowedValues\x12&\n\x06values\x18\x01 \x03(\x0b\x32\x16.google.protobuf.Value\"/\n\x05Order\x12&\n\x06values\x18\x01 \x03(\x0b\x32\x16.google.protobuf.Value\"i\n\x13MetricConfiguration\x12\x10\n\x08operator\x18\x01 \x01(\t\x12,\n\x0ctarget_value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.Value\x12\x12\n\nis_default\x18\x03 \x01(\x08\x42\x10Z\x0e\x61pi/assessmentb\x06proto3' + , + dependencies=[google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,]) + + + +_METRIC_SCALE = _descriptor.EnumDescriptor( + name='Scale', + full_name='clouditor.Metric.Scale', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='NOMIMAL', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ORDINAL', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='METRIC', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=206, + serialized_end=251, +) +_sym_db.RegisterEnumDescriptor(_METRIC_SCALE) + + +_METRIC = _descriptor.Descriptor( + name='Metric', + full_name='clouditor.Metric', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='clouditor.Metric.id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='name', full_name='clouditor.Metric.name', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='description', full_name='clouditor.Metric.description', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='category', full_name='clouditor.Metric.category', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='scale', full_name='clouditor.Metric.scale', index=4, + number=5, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='range', full_name='clouditor.Metric.range', index=5, + number=6, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _METRIC_SCALE, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=58, + serialized_end=251, +) + + +_RANGE = _descriptor.Descriptor( + name='Range', + full_name='clouditor.Range', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='allowed_values', full_name='clouditor.Range.allowed_values', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='order', full_name='clouditor.Range.order', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='min_max', full_name='clouditor.Range.min_max', index=2, + number=3, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + _descriptor.OneofDescriptor( + name='range', full_name='clouditor.Range.range', + index=0, containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[]), + ], + serialized_start=254, + serialized_end=395, +) + + +_MINMAX = _descriptor.Descriptor( + name='MinMax', + full_name='clouditor.MinMax', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='min', full_name='clouditor.MinMax.min', index=0, + number=1, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='max', full_name='clouditor.MinMax.max', index=1, + number=2, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=397, + serialized_end=431, +) + + +_ALLOWEDVALUES = _descriptor.Descriptor( + name='AllowedValues', + full_name='clouditor.AllowedValues', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='values', full_name='clouditor.AllowedValues.values', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=433, + serialized_end=488, +) + + +_ORDER = _descriptor.Descriptor( + name='Order', + full_name='clouditor.Order', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='values', full_name='clouditor.Order.values', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=490, + serialized_end=537, +) + + +_METRICCONFIGURATION = _descriptor.Descriptor( + name='MetricConfiguration', + full_name='clouditor.MetricConfiguration', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='operator', full_name='clouditor.MetricConfiguration.operator', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='target_value', full_name='clouditor.MetricConfiguration.target_value', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='is_default', full_name='clouditor.MetricConfiguration.is_default', index=2, + number=3, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=539, + serialized_end=644, +) + +_METRIC.fields_by_name['scale'].enum_type = _METRIC_SCALE +_METRIC.fields_by_name['range'].message_type = _RANGE +_METRIC_SCALE.containing_type = _METRIC +_RANGE.fields_by_name['allowed_values'].message_type = _ALLOWEDVALUES +_RANGE.fields_by_name['order'].message_type = _ORDER +_RANGE.fields_by_name['min_max'].message_type = _MINMAX +_RANGE.oneofs_by_name['range'].fields.append( + _RANGE.fields_by_name['allowed_values']) +_RANGE.fields_by_name['allowed_values'].containing_oneof = _RANGE.oneofs_by_name['range'] +_RANGE.oneofs_by_name['range'].fields.append( + _RANGE.fields_by_name['order']) +_RANGE.fields_by_name['order'].containing_oneof = _RANGE.oneofs_by_name['range'] +_RANGE.oneofs_by_name['range'].fields.append( + _RANGE.fields_by_name['min_max']) +_RANGE.fields_by_name['min_max'].containing_oneof = _RANGE.oneofs_by_name['range'] +_ALLOWEDVALUES.fields_by_name['values'].message_type = google_dot_protobuf_dot_struct__pb2._VALUE +_ORDER.fields_by_name['values'].message_type = google_dot_protobuf_dot_struct__pb2._VALUE +_METRICCONFIGURATION.fields_by_name['target_value'].message_type = google_dot_protobuf_dot_struct__pb2._VALUE +DESCRIPTOR.message_types_by_name['Metric'] = _METRIC +DESCRIPTOR.message_types_by_name['Range'] = _RANGE +DESCRIPTOR.message_types_by_name['MinMax'] = _MINMAX +DESCRIPTOR.message_types_by_name['AllowedValues'] = _ALLOWEDVALUES +DESCRIPTOR.message_types_by_name['Order'] = _ORDER +DESCRIPTOR.message_types_by_name['MetricConfiguration'] = _METRICCONFIGURATION +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +Metric = _reflection.GeneratedProtocolMessageType('Metric', (_message.Message,), { + 'DESCRIPTOR' : _METRIC, + '__module__' : 'metric_pb2' + # @@protoc_insertion_point(class_scope:clouditor.Metric) + }) +_sym_db.RegisterMessage(Metric) + +Range = _reflection.GeneratedProtocolMessageType('Range', (_message.Message,), { + 'DESCRIPTOR' : _RANGE, + '__module__' : 'metric_pb2' + # @@protoc_insertion_point(class_scope:clouditor.Range) + }) +_sym_db.RegisterMessage(Range) + +MinMax = _reflection.GeneratedProtocolMessageType('MinMax', (_message.Message,), { + 'DESCRIPTOR' : _MINMAX, + '__module__' : 'metric_pb2' + # @@protoc_insertion_point(class_scope:clouditor.MinMax) + }) +_sym_db.RegisterMessage(MinMax) + +AllowedValues = _reflection.GeneratedProtocolMessageType('AllowedValues', (_message.Message,), { + 'DESCRIPTOR' : _ALLOWEDVALUES, + '__module__' : 'metric_pb2' + # @@protoc_insertion_point(class_scope:clouditor.AllowedValues) + }) +_sym_db.RegisterMessage(AllowedValues) + +Order = _reflection.GeneratedProtocolMessageType('Order', (_message.Message,), { + 'DESCRIPTOR' : _ORDER, + '__module__' : 'metric_pb2' + # @@protoc_insertion_point(class_scope:clouditor.Order) + }) +_sym_db.RegisterMessage(Order) + +MetricConfiguration = _reflection.GeneratedProtocolMessageType('MetricConfiguration', (_message.Message,), { + 'DESCRIPTOR' : _METRICCONFIGURATION, + '__module__' : 'metric_pb2' + # @@protoc_insertion_point(class_scope:clouditor.MetricConfiguration) + }) +_sym_db.RegisterMessage(MetricConfiguration) + + +DESCRIPTOR._options = None +# @@protoc_insertion_point(module_scope) diff --git a/grpc_gen/metric_pb2_grpc.py b/grpc_gen/metric_pb2_grpc.py new file mode 100644 index 0000000000000000000000000000000000000000..2daafffebfc817aefe8fcb96eaec25e65b3903e8 --- /dev/null +++ b/grpc_gen/metric_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/proto/assessment.proto b/proto/assessment.proto new file mode 100644 index 0000000000000000000000000000000000000000..c3002ac527d4e8620d0730fa6c9c24cdf619e93e --- /dev/null +++ b/proto/assessment.proto @@ -0,0 +1,106 @@ +/* + * Copyright 2021 Fraunhofer AISEC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $$\ $$\ $$\ $$\ + * $$ | $$ |\__| $$ | + * $$$$$$$\ $$ | $$$$$$\ $$\ $$\ $$$$$$$ |$$\ $$$$$$\ $$$$$$\ $$$$$$\ + * $$ _____|$$ |$$ __$$\ $$ | $$ |$$ __$$ |$$ |\_$$ _| $$ __$$\ $$ __$$\ + * $$ / $$ |$$ / $$ |$$ | $$ |$$ / $$ |$$ | $$ | $$ / $$ |$$ | \__| + * $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ |$$\ $$ | $$ |$$ | + * \$$$$$$\ $$ |\$$$$$ |\$$$$$ |\$$$$$$ |$$ | \$$$ |\$$$$$ |$$ | + * \_______|\__| \______/ \______/ \_______|\__| \____/ \______/ \__| + * + * This file is part of Clouditor Community Edition. + */ +syntax = "proto3"; + +package clouditor; + +import "google/api/annotations.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; +import "evidence.proto"; +import "metric.proto"; + +option go_package = "api/assessment"; + +// Representing the link between orchestrator and discovery: Assessing evidences +// from discovery and sending results to orchestrator +service Assessment { + // Triggers the assessment. Part of the private API, + // not exposed as REST. + rpc TriggerAssessment(TriggerAssessmentRequest) + returns (google.protobuf.Empty) {} + + // TODO(all): Part of public API because external entities (mainly + // discoveries) can use it? List the latest set of assessment results. Part of + // the public API, also exposed as REST + rpc ListAssessmentResults(ListAssessmentResultsRequest) + returns (ListAssessmentResultsResponse) { + option (google.api.http) = { + post : "/v1/assessment/results" + response_body : "*" + }; + } + + // Assesses the evidence sent by discovery. Part of the public API, + // also exposed as REST + rpc AssessEvidence(AssessEvidenceRequest) returns (AssessEvidenceResponse) { + option (google.api.http) = { + post : "/v1/assessment/evidences" + response_body : "*" + }; + } + + // Assesses stream of evidences coming from the discovery. Part of the public + // API, not exposed as REST + rpc AssessEvidences(stream Evidence) returns (google.protobuf.Empty); +}; + +message TriggerAssessmentRequest { string someOption = 1; } + +message ListAssessmentResultsRequest {} +message ListAssessmentResultsResponse { repeated Result results = 1; } + +message AssessEvidenceRequest { Evidence evidence = 1; } +message AssessEvidenceResponse { bool status = 1; } + +// A result resource, representing the result after assessing the cloud resource +// with id resource_id. +message Result { + // Assessment result id + string id = 1; + + // Time of assessment + google.protobuf.Timestamp timestamp = 2; + + // Reference to the metric the assessment was based on + string metric_id = 3; + + // Data corresponding to the metric by the given metric id + MetricConfiguration metric_data = 4; + + // Compliant case: true or false + bool compliant = 5; + + // Reference to the assessed evidence + string evidence_id = 6; + + // Reference to the resource of the assessed evidence + string resource_id = 7; + + // Some comments on the reason for non-compliance + string non_compliance_comments = 8; +} diff --git a/proto/evidence.proto b/proto/evidence.proto index 145d767a37b93b5cf57ab4c7ab2cc021f10f2cf2..f1f25856b4aab40d00bf31e5b06cbc2f5a84e304 100644 --- a/proto/evidence.proto +++ b/proto/evidence.proto @@ -37,11 +37,23 @@ option go_package = "api/evidence"; // An evidence resource message Evidence { - string id = 1; // the ID in a uuid format - // TODO: replace with google/type/date.proto timestamp.proto or date.proto? - google.protobuf.Timestamp timestamp = 2; // time of evidence creation - string service_id = 3; // Reference to a service this evidence was gathered from - string tool_id = 4; // Reference to the tool which provided the evidence - string raw = 5; // evidence in its original form without following a defined schema, e.g. the raw JSON - google.protobuf.Value resource = 6; // semantic representation of the Cloud resource according to our defined ontology + // the ID in a uuid format + string id = 1; + + // time of evidence creation + google.protobuf.Timestamp timestamp = 2; + + // Reference to a service this evidence was gathered from + string service_id = 3; + + // Reference to the tool which provided the evidence + string tool_id = 4; + + // Contains the evidence in its original form without following a defined + // schema, e.g. the raw JSON + string raw = 5; + + // Semantic representation of the Cloud resource according to our defined + // ontology + google.protobuf.Value resource = 6; } \ No newline at end of file diff --git a/proto/evidence_store.proto b/proto/evidence_store.proto deleted file mode 100644 index 818162856d8122f4d6309854dafa37a410a385ec..0000000000000000000000000000000000000000 --- a/proto/evidence_store.proto +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2021 Fraunhofer AISEC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * $$\ $$\ $$\ $$\ - * $$ | $$ |\__| $$ | - * $$$$$$$\ $$ | $$$$$$\ $$\ $$\ $$$$$$$ |$$\ $$$$$$\ $$$$$$\ $$$$$$\ - * $$ _____|$$ |$$ __$$\ $$ | $$ |$$ __$$ |$$ |\_$$ _| $$ __$$\ $$ __$$\ - * $$ / $$ |$$ / $$ |$$ | $$ |$$ / $$ |$$ | $$ | $$ / $$ |$$ | \__| - * $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ |$$\ $$ | $$ |$$ | - * \$$$$$$\ $$ |\$$$$$ |\$$$$$ |\$$$$$$ |$$ | \$$$ |\$$$$$ |$$ | - * \_______|\__| \______/ \______/ \_______|\__| \____/ \______/ \__| - * - * This file is part of Clouditor Community Edition. - */ - syntax = "proto3"; - - package clouditor; - - import "evidence.proto"; - import "google/protobuf/empty.proto"; - - option go_package = "api/evidence"; - - // Manages the storage of evidences - service EvidenceStore { - // Stores an evidence to the evidence storage - rpc StoreEvidence(Evidence) returns (StoreEvidenceResponse); - - // Stores a stream of evidences to the evidence storage - rpc StoreEvidences(stream Evidence) returns (google.protobuf.Empty); - - // Returns the evidences lying in the evidence storage - rpc ListEvidences(ListEvidencesRequest) returns (ListEvidencesResponse); - } - - message StoreEvidenceResponse { bool status = 1; } - - message ListEvidencesRequest {} - message ListEvidencesResponse { repeated Evidence evidences = 1; } \ No newline at end of file diff --git a/proto/google/api/annotations.proto b/proto/google/api/annotations.proto new file mode 100644 index 0000000000000000000000000000000000000000..efdab3db6ca845d96b12f398e22ba22579692028 --- /dev/null +++ b/proto/google/api/annotations.proto @@ -0,0 +1,31 @@ +// Copyright 2015 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/http.proto"; +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "AnnotationsProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + // See `HttpRule`. + HttpRule http = 72295728; +} diff --git a/proto/google/api/http.proto b/proto/google/api/http.proto new file mode 100644 index 0000000000000000000000000000000000000000..113fa936a09e691505e857140d75fd7f78028374 --- /dev/null +++ b/proto/google/api/http.proto @@ -0,0 +1,375 @@ +// Copyright 2015 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "HttpProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Defines the HTTP configuration for an API service. It contains a list of +// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method +// to one or more HTTP REST API methods. +message Http { + // A list of HTTP configuration rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated HttpRule rules = 1; + + // When set to true, URL path parameters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // + // The default behavior is to not decode RFC 6570 reserved characters in multi + // segment matches. + bool fully_decode_reserved_expansion = 2; +} + +// # gRPC Transcoding +// +// gRPC Transcoding is a feature for mapping between a gRPC method and one or +// more HTTP REST endpoints. It allows developers to build a single API service +// that supports both gRPC APIs and REST APIs. Many systems, including [Google +// APIs](https://github.com/googleapis/googleapis), +// [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC +// Gateway](https://github.com/grpc-ecosystem/grpc-gateway), +// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature +// and use it for large scale production services. +// +// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies +// how different portions of the gRPC request message are mapped to the URL +// path, URL query parameters, and HTTP request body. It also controls how the +// gRPC response message is mapped to the HTTP response body. `HttpRule` is +// typically specified as an `google.api.http` annotation on the gRPC method. +// +// Each mapping specifies a URL path template and an HTTP method. The path +// template may refer to one or more fields in the gRPC request message, as long +// as each field is a non-repeated field with a primitive (non-message) type. +// The path template controls how fields of the request message are mapped to +// the URL path. +// +// Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/{name=messages/*}" +// }; +// } +// } +// message GetMessageRequest { +// string name = 1; // Mapped to URL path. +// } +// message Message { +// string text = 1; // The resource content. +// } +// +// This enables an HTTP REST to gRPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` +// +// Any fields in the request message which are not bound by the path template +// automatically become HTTP query parameters if there is no HTTP request body. +// For example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get:"/v1/messages/{message_id}" +// }; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // Mapped to URL path. +// int64 revision = 2; // Mapped to URL query parameter `revision`. +// SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. +// } +// +// This enables a HTTP JSON to RPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | +// `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: +// "foo"))` +// +// Note that fields which are mapped to URL query parameters must have a +// primitive type or a repeated primitive type or a non-repeated message type. +// In the case of a repeated type, the parameter can be repeated in the URL +// as `...?param=A¶m=B`. In the case of a message type, each field of the +// message is mapped to a separate parameter, such as +// `...?foo.a=A&foo.b=B&foo.c=C`. +// +// For HTTP methods that allow a request body, the `body` field +// specifies the mapping. Consider a REST update method on the +// message resource collection: +// +// service Messaging { +// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "message" +// }; +// } +// } +// message UpdateMessageRequest { +// string message_id = 1; // mapped to the URL +// Message message = 2; // mapped to the body +// } +// +// The following HTTP JSON to RPC mapping is enabled, where the +// representation of the JSON in the request body is determined by +// protos JSON encoding: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" message { text: "Hi!" })` +// +// The special name `*` can be used in the body mapping to define that +// every field not bound by the path template should be mapped to the +// request body. This enables the following alternative definition of +// the update method: +// +// service Messaging { +// rpc UpdateMessage(Message) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "*" +// }; +// } +// } +// message Message { +// string message_id = 1; +// string text = 2; +// } +// +// +// The following HTTP JSON to RPC mapping is enabled: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" text: "Hi!")` +// +// Note that when using `*` in the body mapping, it is not possible to +// have HTTP parameters, as all fields not bound by the path end in +// the body. This makes this option more rarely used in practice when +// defining REST APIs. The common usage of `*` is in custom methods +// which don't use the URL at all for transferring data. +// +// It is possible to define multiple HTTP methods for one RPC by using +// the `additional_bindings` option. Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/messages/{message_id}" +// additional_bindings { +// get: "/v1/users/{user_id}/messages/{message_id}" +// } +// }; +// } +// } +// message GetMessageRequest { +// string message_id = 1; +// string user_id = 2; +// } +// +// This enables the following two alternative HTTP JSON to RPC mappings: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` +// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: +// "123456")` +// +// ## Rules for HTTP mapping +// +// 1. Leaf request fields (recursive expansion nested messages in the request +// message) are classified into three categories: +// - Fields referred by the path template. They are passed via the URL path. +// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They are passed via the HTTP +// request body. +// - All other fields are passed via the URL query parameters, and the +// parameter name is the field path in the request message. A repeated +// field can be represented as multiple query parameters under the same +// name. +// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL query parameter, all fields +// are passed via URL path and HTTP request body. +// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP request body, all +// fields are passed via URL path and URL query parameters. +// +// ### Path template syntax +// +// Template = "/" Segments [ Verb ] ; +// Segments = Segment { "/" Segment } ; +// Segment = "*" | "**" | LITERAL | Variable ; +// Variable = "{" FieldPath [ "=" Segments ] "}" ; +// FieldPath = IDENT { "." IDENT } ; +// Verb = ":" LITERAL ; +// +// The syntax `*` matches a single URL path segment. The syntax `**` matches +// zero or more URL path segments, which must be the last part of the URL path +// except the `Verb`. +// +// The syntax `Variable` matches part of the URL path as specified by its +// template. A variable template must not contain other variables. If a variable +// matches a single path segment, its template may be omitted, e.g. `{var}` +// is equivalent to `{var=*}`. +// +// The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` +// contains any reserved character, such characters should be percent-encoded +// before the matching. +// +// If a variable contains exactly one path segment, such as `"{var}"` or +// `"{var=*}"`, when such a variable is expanded into a URL path on the client +// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The +// server side does the reverse decoding. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{var}`. +// +// If a variable contains multiple path segments, such as `"{var=foo/*}"` +// or `"{var=**}"`, when such a variable is expanded into a URL path on the +// client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. +// The server side does the reverse decoding, except "%2F" and "%2f" are left +// unchanged. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{+var}`. +// +// ## Using gRPC API Service Configuration +// +// gRPC API Service Configuration (service config) is a configuration language +// for configuring a gRPC service to become a user-facing product. The +// service config is simply the YAML representation of the `google.api.Service` +// proto message. +// +// As an alternative to annotating your proto file, you can configure gRPC +// transcoding in your service config YAML files. You do this by specifying a +// `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same +// effect as the proto annotation. This can be particularly useful if you +// have a proto that is reused in multiple services. Note that any transcoding +// specified in the service config will override any matching transcoding +// configuration in the proto. +// +// Example: +// +// http: +// rules: +// # Selects a gRPC method and applies HttpRule to it. +// - selector: example.v1.Messaging.GetMessage +// get: /v1/messages/{message_id}/{sub.subfield} +// +// ## Special notes +// +// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the +// proto to JSON conversion must follow the [proto3 +// specification](https://developers.google.com/protocol-buffers/docs/proto3#json). +// +// While the single segment variable follows the semantics of +// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String +// Expansion, the multi segment variable **does not** follow RFC 6570 Section +// 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion +// does not expand special characters like `?` and `#`, which would lead +// to invalid URLs. As the result, gRPC Transcoding uses a custom encoding +// for multi segment variables. +// +// The path variables **must not** refer to any repeated or mapped field, +// because client libraries are not capable of handling such variable expansion. +// +// The path variables **must not** capture the leading "/" character. The reason +// is that the most common use case "{var}" does not capture the leading "/" +// character. For consistency, all path variables must share the same behavior. +// +// Repeated message fields must not be mapped to URL query parameters, because +// no client library can support such complicated mapping. +// +// If an API needs to use a JSON array for request or response body, it can map +// the request or response body to a repeated field. However, some gRPC +// Transcoding implementations may not support this feature. +message HttpRule { + // Selects a method to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + string selector = 1; + + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + oneof pattern { + // Maps to HTTP GET. Used for listing and getting information about + // resources. + string get = 2; + + // Maps to HTTP PUT. Used for replacing a resource. + string put = 3; + + // Maps to HTTP POST. Used for creating a resource or performing an action. + string post = 4; + + // Maps to HTTP DELETE. Used for deleting a resource. + string delete = 5; + + // Maps to HTTP PATCH. Used for updating a resource. + string patch = 6; + + // The custom pattern is used for specifying an HTTP method that is not + // included in the `pattern` field, such as HEAD, or "*" to leave the + // HTTP method unspecified for this rule. The wild-card rule is useful + // for services that provide content to Web (HTML) clients. + CustomHttpPattern custom = 8; + } + + // The name of the request field whose value is mapped to the HTTP request + // body, or `*` for mapping all request fields not captured by the path + // pattern to the HTTP body, or omitted for not having any HTTP request body. + // + // NOTE: the referred field must be present at the top-level of the request + // message type. + string body = 7; + + // Optional. The name of the response field whose value is mapped to the HTTP + // response body. When omitted, the entire response message will be used + // as the HTTP response body. + // + // NOTE: The referred field must be present at the top-level of the response + // message type. + string response_body = 12; + + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + repeated HttpRule additional_bindings = 11; +} + +// A custom pattern is used for defining custom HTTP verb. +message CustomHttpPattern { + // The name of this custom HTTP verb. + string kind = 1; + + // The path matched by this custom verb. + string path = 2; +} diff --git a/proto/metric.proto b/proto/metric.proto new file mode 100644 index 0000000000000000000000000000000000000000..f5f0763315a834096e4cd14b452c6c215d85210c --- /dev/null +++ b/proto/metric.proto @@ -0,0 +1,105 @@ +/* + * Copyright 2021 Fraunhofer AISEC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $$\ $$\ $$\ $$\ + * $$ | $$ |\__| $$ | + * $$$$$$$\ $$ | $$$$$$\ $$\ $$\ $$$$$$$ |$$\ $$$$$$\ $$$$$$\ $$$$$$\ + * $$ _____|$$ |$$ __$$\ $$ | $$ |$$ __$$ |$$ |\_$$ _| $$ __$$\ $$ __$$\ + * $$ / $$ |$$ / $$ |$$ | $$ |$$ / $$ |$$ | $$ | $$ / $$ |$$ | \__| + * $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ |$$\ $$ | $$ |$$ | + * \$$$$$$\ $$ |\$$$$$ |\$$$$$ |\$$$$$$ |$$ | \$$$ |\$$$$$ |$$ | + * \_______|\__| \______/ \______/ \_______|\__| \____/ \______/ \__| + * + * This file is part of Clouditor Community Edition. + */ +// ToDo(all): Change name of file to resources.proto or similar? (It is not +// containing evidences only) +syntax = "proto3"; + +package clouditor; + +import "google/protobuf/struct.proto"; + +option go_package = "api/assessment"; + +// A metric resource +message Metric { + // Required. The unique identifier of the metric. + string id = 1; + + // Required. The human readable name of the metric. + string name = 2; + + // The description of the metric + string description = 3; + + // The reference to control catalog category or domain + string category = 4; + + // The scale of this metric, e.g. categories, ranked data or metric values. + Scale scale = 5; + + // The range of this metric. Depending on the scale. + Range range = 6; + + // The values a Scale accepts + enum Scale { + NOMIMAL = 0; + ORDINAL = 1; + METRIC = 2; + } +} + +// A range resource representing the range of values +message Range { + // Required. + oneof range { + // used for nominal scale + AllowedValues allowed_values = 1; + + // used for ordinal scale + Order order = 2; + + // used for metric scale + MinMax min_max = 3; + } +} + +// Defines a range of values through a (inclusive) minimum and a maximum +message MinMax { + // Required. + int64 min = 1; + // Required. + int64 max = 2; +} + +// Defines a range +message AllowedValues { repeated google.protobuf.Value values = 1; } + +// Defines a range of values in a pre-defined order from the lowest to the +// highest. +message Order { repeated google.protobuf.Value values = 1; } + +// Defines the operator and a target value for an individual metric +message MetricConfiguration { + // The operator to compare the metric, such as == or > + string operator = 1; + + // The target value + google.protobuf.Value target_value = 2; + + // Whether this configuration is a default configuration + bool is_default = 3; +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 77f96520976947489d42a1390353c2a311c52fa1..fc5e7749c11f838986b35798208260386cfa2666 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,30 @@ -grpcio==1.41.1 -rq==1.2.2 +cachetools==4.2.4 +certifi==2021.10.8 +charset-normalizer==2.0.9 +click==7.1.2 +configparser==5.1.0 +croniter==1.0.15 elasticsearch==7.13.4 +elasticsearch-dsl==7.4.0 +google-api-core==2.3.0 +google-api-python-client==2.33.0 +google-auth==2.3.3 +google-auth-httplib2==0.1.0 +googleapis-common-protos==1.54.0 +grpcio==1.42.0 +grpcio-tools==1.42.0 +httplib2==0.20.2 +idna==3.3 +protobuf==3.19.1 +pyasn1==0.4.8 +pyasn1-modules==0.2.8 +pyparsing==3.0.6 +python-dateutil==2.8.2 redis==3.3.11 +requests==2.26.0 +rq==1.2.2 +rq-scheduler==0.11.0 +rsa==4.8 +six==1.16.0 +uritemplate==4.1.1 urllib3==1.25.8 -elasticsearch_dsl==7.4.0 -protobuf==3.19.1 -rq_scheduler==0.11.0 -click==7.1.2 -configparser==5.1.0 \ No newline at end of file diff --git a/wazuh_evidence_collector/wazuh_evidence_collector.py b/wazuh_evidence_collector/wazuh_evidence_collector.py index bc6a87a04ecbdd028fa9d7c6e9508b452a5b4f61..a24c5c41aa25976da4012f68ae2203d0cc1d1b79 100644 --- a/wazuh_evidence_collector/wazuh_evidence_collector.py +++ b/wazuh_evidence_collector/wazuh_evidence_collector.py @@ -3,10 +3,9 @@ from wazuh_evidence_collector.wazuh_client import WazuhClient from elasticsearch import Elasticsearch from elasticsearch_dsl import Search from forward_evidence.forward_evidence import ForwardEvidence -from evidence.generate_evidence import create_resource, create_evidence, print_evidence +from forward_evidence.generate_evidence import create_resource, create_assessevidence_request, print_evidence import uuid import configparser -import logging import logging.config f = open('constants.json',) @@ -61,7 +60,7 @@ def run_collector(): # Get list of all agent ids (including manager's) def get_agents(wc): body = wc.req('GET', 'agents') - + agent_list = [] for agent in body['data']['affected_items']: agent_list.append([agent['id'], agent['name']]) @@ -70,17 +69,17 @@ def run_collector(): body, agent_list = get_agents(wc) - evidence_list = [] + ae_req_list = [] for agent in agent_list: - evidence_list.append(generate_evidence(wc, es, agent)) + ae_req_list.append(generate_evidence(wc, es, agent)) # TODO: - for evidence in evidence_list: - forwarder.send_evidence(evidence) - print_evidence(LOGGER, evidence) + for ae_req in ae_req_list: + forwarder.send_evidence(ae_req) + print_evidence(LOGGER, ae_req.evidence) - return evidence_list + return ae_req_list # Run checks and generate evidence def generate_evidence(wc, es, agent): @@ -204,7 +203,7 @@ def generate_evidence(wc, es, agent): # TODO: change ID resource = create_resource(agent[0], agent[1], None, malware_protection) - return create_evidence(get_id(), "evidence_collector_service", get_tool_id(), raw_evidence, resource) + return create_assessevidence_request(get_id(), "evidence_collector_service", get_tool_id(), raw_evidence, resource) if __name__ == "__main__": main() \ No newline at end of file