Repository: clouditor/clouditor
Pull request #539 (2022-02-25 09:07:33)

Updating `voc` package according to latest ontology

garuppel: The ARM discovery needs mayor updates, I will do that in a separate PR. 
codecov[bot]: # [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/539?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) Report
> Merging [#539](https://codecov.io/gh/clouditor/clouditor/pull/539?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (4d0012b) into [main](https://codecov.io/gh/clouditor/clouditor/commit/b280a4b670ecd7df8509dc6a72a151a5b8ec8ede?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (b280a4b) will **decrease** coverage by `0.47%`.
> The diff coverage is `97.38%`.

[![Impacted file tree graph](https://codecov.io/gh/clouditor/clouditor/pull/539/graphs/tree.svg?width=650&height=150&src=pr&token=syrXsw5LTX&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)](https://codecov.io/gh/clouditor/clouditor/pull/539?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)

```diff
@@            Coverage Diff             @@
##             main     #539      +/-   ##
==========================================
- Coverage   82.35%   81.87%   -0.48%     
==========================================
  Files          53       53              
  Lines        4799     4850      +51     
==========================================
+ Hits         3952     3971      +19     
- Misses        655      680      +25     
- Partials      192      199       +7     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `81.87% <97.38%> (-0.48%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/clouditor/clouditor/pull/539?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) | Coverage Δ | |
|---|---|---|
| [voc/voc.go](https://codecov.io/gh/clouditor/clouditor/pull/539/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-dm9jL3ZvYy5nbw==) | `82.35% <80.00%> (ø)` | |
| [service/discovery/azure/storage.go](https://codecov.io/gh/clouditor/clouditor/pull/539/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvYXp1cmUvc3RvcmFnZS5nbw==) | `87.84% <94.33%> (+0.44%)` | :arrow_up: |
| [policies/policies.go](https://codecov.io/gh/clouditor/clouditor/pull/539/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-cG9saWNpZXMvcG9saWNpZXMuZ28=) | `73.72% <100.00%> (ø)` | |
| [service/discovery/aws/compute.go](https://codecov.io/gh/clouditor/clouditor/pull/539/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvYXdzL2NvbXB1dGUuZ28=) | `100.00% <100.00%> (ø)` | |
| [service/discovery/aws/storage.go](https://codecov.io/gh/clouditor/clouditor/pull/539/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvYXdzL3N0b3JhZ2UuZ28=) | `84.65% <100.00%> (+1.41%)` | :arrow_up: |
| [service/discovery/azure/arm\_template.go](https://codecov.io/gh/clouditor/clouditor/pull/539/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvYXp1cmUvYXJtX3RlbXBsYXRlLmdv) | `87.86% <100.00%> (-1.41%)` | :arrow_down: |
| [service/discovery/azure/compute.go](https://codecov.io/gh/clouditor/clouditor/pull/539/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvYXp1cmUvY29tcHV0ZS5nbw==) | `87.50% <100.00%> (-0.19%)` | :arrow_down: |
| [service/discovery/azure/network.go](https://codecov.io/gh/clouditor/clouditor/pull/539/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvYXp1cmUvbmV0d29yay5nbw==) | `91.21% <100.00%> (ø)` | |
| [service/discovery/k8s/compute.go](https://codecov.io/gh/clouditor/clouditor/pull/539/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvazhzL2NvbXB1dGUuZ28=) | `83.72% <100.00%> (ø)` | |
| [service/discovery/k8s/network.go](https://codecov.io/gh/clouditor/clouditor/pull/539/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvazhzL25ldHdvcmsuZ28=) | `90.29% <100.00%> (ø)` | |
| ... and [5 more](https://codecov.io/gh/clouditor/clouditor/pull/539/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/clouditor/clouditor/pull/539?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/539?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Last update [b280a4b...4d0012b](https://codecov.io/gh/clouditor/clouditor/pull/539?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor).


Patch:
diff --git a/policies/bundles/BootLoggingEnabled/metric.rego b/policies/bundles/BootLoggingEnabled/metric.rego
index cd253370..a110dcb8 100644
--- a/policies/bundles/BootLoggingEnabled/metric.rego
+++ b/policies/bundles/BootLoggingEnabled/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-bootLog := input.bootLog
+bootLogging := input.bootLogging
 
 applicable {
-	bootLog
+	bootLogging
 }
 
 compliant {
-	compare(data.operator, data.target_value, bootLog.enabled)
+	compare(data.operator, data.target_value, bootLogging.enabled)
 }
diff --git a/policies/bundles/BootLoggingOutput/metric.rego b/policies/bundles/BootLoggingOutput/metric.rego
index 05007b31..36525532 100644
--- a/policies/bundles/BootLoggingOutput/metric.rego
+++ b/policies/bundles/BootLoggingOutput/metric.rego
@@ -8,12 +8,12 @@ default compliant = false
 
 metricConfiguration := data.target_value
 
-bootLog := input.bootLog
+bootLogging := input.bootLogging
 
 applicable {
-	bootLog
+	bootLogging
 }
 
 compliant {
-	isIn(data.target_value, bootLog.output)
+	isIn(data.target_value, bootLogging.loggingService)
 }
diff --git a/policies/bundles/BootLoggingRetention/metric.rego b/policies/bundles/BootLoggingRetention/metric.rego
index 2e38feb6..75210d03 100644
--- a/policies/bundles/BootLoggingRetention/metric.rego
+++ b/policies/bundles/BootLoggingRetention/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-bootLog := input.bootLog
+bootLogging := input.bootLogging
 
 applicable {
-	bootLog
+	bootLogging
 }
 
 compliant {
-	compare(data.operator, data.target_value, bootLog.retentionPeriod)
+	compare(data.operator, data.target_value, bootLogging.retentionPeriod)
 }
diff --git a/policies/bundles/MalwareProtectionOutput/metric.rego b/policies/bundles/MalwareProtectionOutput/metric.rego
index 7393a5e4..bc380300 100644
--- a/policies/bundles/MalwareProtectionOutput/metric.rego
+++ b/policies/bundles/MalwareProtectionOutput/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-mp := input.malwareProtection
+mp := input.malwareProtection.applicationLogging
 
 applicable {
 	mp
 }
 
 compliant {
-	isIn(data.target_value, mp.output)
+	isIn(data.target_value, mp.loggingService)
 }
diff --git a/policies/bundles/OSLoggingEnabled/metric.rego b/policies/bundles/OSLoggingEnabled/metric.rego
index a88cbfe8..563c3fc1 100644
--- a/policies/bundles/OSLoggingEnabled/metric.rego
+++ b/policies/bundles/OSLoggingEnabled/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-OSLog := input.oSLog
+OSLogging := input.oSLogging
 
 applicable {
-	OSLog
+	OSLogging
 }
 
 compliant {
-	compare(data.operator, data.target_value, OSLog.enabled)
+	compare(data.operator, data.target_value, OSLogging.enabled)
 }
diff --git a/policies/bundles/OSLoggingOutput/metric.rego b/policies/bundles/OSLoggingOutput/metric.rego
index 663f73bf..0ae486b4 100644
--- a/policies/bundles/OSLoggingOutput/metric.rego
+++ b/policies/bundles/OSLoggingOutput/metric.rego
@@ -8,12 +8,12 @@ default compliant = false
 
 metricConfiguration := data.target_value
 
-OSLog := input.oSLog
+OSLogging := input.oSLogging
 
 applicable {
-	OSLog
+	OSLogging
 }
 
 compliant {
-	isIn(data.target_value, OSLog.output)
+	isIn(data.target_value, OSLogging.loggingService)
 }
diff --git a/policies/bundles/OSLoggingRetention/metric.rego b/policies/bundles/OSLoggingRetention/metric.rego
index 7de5b593..b39b1675 100644
--- a/policies/bundles/OSLoggingRetention/metric.rego
+++ b/policies/bundles/OSLoggingRetention/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-OSLog := input.oSLog
+OSLogging := input.oSLogging
 
 applicable {
-	OSLog
+	OSLogging
 }
 
 compliant {
-	compare(data.operator, data.target_value, OSLog.retentionPeriod)
+	compare(data.operator, data.target_value, OSLogging.retentionPeriod)
 }
diff --git a/policies/policies.go b/policies/policies.go
index 0bcf3ac9..af2e29da 100644
--- a/policies/policies.go
+++ b/policies/policies.go
@@ -58,7 +58,7 @@ type MetricConfigurationSource interface {
 
 func RunEvidence(evidence *evidence.Evidence, holder MetricConfigurationSource) ([]*Result, error) {
 	data := make([]*Result, 0)
-	var baseDir string = "."
+	var baseDir = "."
 
 	var m = evidence.Resource.GetStructValue().AsMap()
 
diff --git a/service/discovery/aws/compute.go b/service/discovery/aws/compute.go
index 90e2773b..6cc4afd3 100644
--- a/service/discovery/aws/compute.go
+++ b/service/discovery/aws/compute.go
@@ -28,11 +28,12 @@
 package aws
 
 import (
-	"clouditor.io/clouditor/api/discovery"
-	"clouditor.io/clouditor/voc"
 	"context"
 	"errors"
 	"fmt"
+
+	"clouditor.io/clouditor/api/discovery"
+	"clouditor.io/clouditor/voc"
 	"github.com/aws/aws-sdk-go-v2/aws"
 	"github.com/aws/aws-sdk-go-v2/service/ec2"
 	typesEC2 "github.com/aws/aws-sdk-go-v2/service/ec2/types"
@@ -120,7 +121,7 @@ func (d *computeDiscovery) discoverVirtualMachines() ([]voc.VirtualMachine, erro
 		for i := range reservation.Instances {
 			vm := &reservation.Instances[i]
 			computeResource := &voc.Compute{
-				CloudResource: &voc.CloudResource{
+				Resource: &voc.Resource{
 					ID:           d.addARNToVM(vm),
 					Name:         d.getNameOfVM(vm),
 					CreationTime: 0,
@@ -129,14 +130,14 @@ func (d *computeDiscovery) discoverVirtualMachines() ([]voc.VirtualMachine, erro
 						Region: d.awsConfig.cfg.Region,
 					},
 				},
+				NetworkInterface: d.getNetworkInterfacesOfVM(vm),
 			}
 
 			resources = append(resources, voc.VirtualMachine{
-				Compute:          computeResource,
-				BlockStorage:     d.mapBlockStorageIDsOfVM(vm),
-				NetworkInterface: d.getNetworkInterfacesOfVM(vm),
-				BootLog:          d.getBootLog(vm),
-				OSLog:            d.getOSLog(vm),
+				Compute:      computeResource,
+				BlockStorage: d.mapBlockStorageIDsOfVM(vm),
+				BootLogging:  d.getBootLog(vm),
+				OSLogging:    d.getOSLog(vm),
 			})
 		}
 	}
@@ -175,7 +176,7 @@ func (d *computeDiscovery) mapFunctionResources(functions []typesLambda.Function
 		function := &functions[i]
 		resources = append(resources, voc.Function{
 			Compute: &voc.Compute{
-				CloudResource: &voc.CloudResource{
+				Resource: &voc.Resource{
 					ID:           voc.ResourceID(aws.ToString(function.FunctionArn)),
 					Name:         aws.ToString(function.FunctionName),
 					CreationTime: 0,
@@ -191,11 +192,11 @@ func (d *computeDiscovery) mapFunctionResources(functions []typesLambda.Function
 
 // getBootLog checks if boot logging is enabled
 // Currently there is no option to find out if any logs are enabled -> Assign default zero values
-func (*computeDiscovery) getBootLog(_ *typesEC2.Instance) (l *voc.BootLog) {
-	l = &voc.BootLog{
-		Log: &voc.Log{
+func (*computeDiscovery) getBootLog(_ *typesEC2.Instance) (l *voc.BootLogging) {
+	l = &voc.BootLogging{
+		Logging: &voc.Logging{
 			Auditing:        nil,
-			Output:          nil,
+			LoggingService:  nil,
 			Enabled:         false,
 			RetentionPeriod: 0,
 		},
@@ -205,11 +206,11 @@ func (*computeDiscovery) getBootLog(_ *typesEC2.Instance) (l *voc.BootLog) {
 
 // getOSLog checks if OS logging is enabled
 // Currently there is no option to find out if any logs are enabled -> Assign default zero values
-func (*computeDiscovery) getOSLog(_ *typesEC2.Instance) (l *voc.OSLog) {
-	l = &voc.OSLog{
-		Log: &voc.Log{
+func (*computeDiscovery) getOSLog(_ *typesEC2.Instance) (l *voc.OSLogging) {
+	l = &voc.OSLogging{
+		Logging: &voc.Logging{
 			Auditing:        nil,
-			Output:          nil,
+			LoggingService:  nil,
 			Enabled:         false,
 			RetentionPeriod: 0,
 		},
@@ -219,7 +220,10 @@ func (*computeDiscovery) getOSLog(_ *typesEC2.Instance) (l *voc.OSLog) {
 
 // mapBlockStorageIDsOfVM returns block storages IDs by iterating the VMs block storages
 func (*computeDiscovery) mapBlockStorageIDsOfVM(vm *typesEC2.Instance) (blockStorageIDs []voc.ResourceID) {
-	for _, mapping := range vm.BlockDeviceMappings {
+	// Loop through mappings using an index, since BlockDeviceMappings is an array of a struct
+	// and not of a pointer; otherwise we would copy a lot of data
+	for i := range vm.BlockDeviceMappings {
+		mapping := &vm.BlockDeviceMappings[i]
 		blockStorageIDs = append(blockStorageIDs, voc.ResourceID(aws.ToString(mapping.Ebs.VolumeId)))
 	}
 	return
@@ -227,8 +231,11 @@ func (*computeDiscovery) mapBlockStorageIDsOfVM(vm *typesEC2.Instance) (blockSto
 
 // getNetworkInterfacesOfVM returns the network interface IDs by iterating the VMs network interfaces
 func (*computeDiscovery) getNetworkInterfacesOfVM(vm *typesEC2.Instance) (networkInterfaceIDs []voc.ResourceID) {
-	for _, networkInterface := range vm.NetworkInterfaces {
-		networkInterfaceIDs = append(networkInterfaceIDs, voc.ResourceID(aws.ToString(networkInterface.NetworkInterfaceId)))
+	// Loop through mappings using an index, since is NetworkInterfaces an array of a struct
+	// and not of a pointer; otherwise we would copy a lot of data
+	for i := range vm.NetworkInterfaces {
+		ifc := &vm.NetworkInterfaces[i]
+		networkInterfaceIDs = append(networkInterfaceIDs, voc.ResourceID(aws.ToString(ifc.NetworkInterfaceId)))
 	}
 	return
 }
diff --git a/service/discovery/aws/storage.go b/service/discovery/aws/storage.go
index 44403f93..c4440917 100644
--- a/service/discovery/aws/storage.go
+++ b/service/discovery/aws/storage.go
@@ -120,7 +120,7 @@ func (d *awsS3Discovery) List() (resources []voc.IsCloudResource, err error) {
 		return
 	}
 	for _, b := range buckets {
-		encryptionAtRest, err = d.getEncryptionAtRest(b)
+		encryptionAtRest, err = d.getEncryptionAtRest(&b)
 		if err != nil {
 			return
 		}
@@ -128,28 +128,46 @@ func (d *awsS3Discovery) List() (resources []voc.IsCloudResource, err error) {
 		if err != nil {
 			return
 		}
-		resources = append(resources, &voc.ObjectStorage{
-			Storage: &voc.Storage{
-				CloudResource: &voc.CloudResource{
-					ID:           voc.ResourceID(b.arn),
-					Name:         b.name,
-					CreationTime: b.creationTime.Unix(),
-					Type:         []string{"ObjectStorage", "Storage", "Resource"},
-					GeoLocation: voc.GeoLocation{
-						Region: b.region,
+
+		resources = append(resources,
+			// Add ObjectStorage
+			&voc.ObjectStorage{
+				Storage: &voc.Storage{
+					Resource: &voc.Resource{
+						ID:           voc.ResourceID(b.arn),
+						Name:         b.name,
+						CreationTime: b.creationTime.Unix(),
+						Type:         []string{"ObjectStorage", "Storage", "Resource"},
+						GeoLocation: voc.GeoLocation{
+							Region: b.region,
+						},
 					},
+					AtRestEncryption: encryptionAtRest,
 				},
-				AtRestEncryption: encryptionAtRest,
-			},
-			HttpEndpoint: &voc.HttpEndpoint{
-				Url:                 b.endpoint,
-				TransportEncryption: encryptionAtTransmit,
 			},
-		})
+			// Add StorageService
+			&voc.StorageService{
+				Storages: []voc.ResourceID{voc.ResourceID(b.arn)},
+				NetworkService: &voc.NetworkService{
+					Networking: &voc.Networking{
+						Resource: &voc.Resource{
+							ID:           voc.ResourceID(b.arn),
+							CreationTime: b.creationTime.Unix(),
+							Name:         b.name,
+							GeoLocation:  voc.GeoLocation{Region: b.region},
+							Type:         []string{"StorageService", "NetworkService", "Networking", "Resource"},
+						},
+					},
+				},
+				HttpEndpoint: &voc.HttpEndpoint{
+					Url:                 b.endpoint,
+					TransportEncryption: encryptionAtTransmit,
+				},
+			})
 	}
 	return
 }
-func (b bucket) String() string {
+func (b *bucket) String() string {
 	return fmt.Sprintf("[ARN: %v, Name: %v, Creation Time: %v]", b.arn, b.name, b.creationTime)
 }
 
@@ -195,7 +213,7 @@ func (d *awsS3Discovery) getBuckets() (buckets []bucket, err error) {
 }
 
 // getEncryptionAtRest gets the bucket's encryption configuration
-func (d *awsS3Discovery) getEncryptionAtRest(bucket bucket) (e voc.HasAtRestEncryption, err error) {
+func (d *awsS3Discovery) getEncryptionAtRest(bucket *bucket) (e voc.HasAtRestEncryption, err error) {
 
 	input := s3.GetBucketEncryptionInput{
 		Bucket:              aws.String(bucket.name),
diff --git a/service/discovery/azure/arm_template.go b/service/discovery/azure/arm_template.go
index a973258d..31be4092 100644
--- a/service/discovery/azure/arm_template.go
+++ b/service/discovery/azure/arm_template.go
@@ -152,7 +152,8 @@ func (d *azureARMTemplateDiscovery) discoverARMTemplate() ([]voc.IsCloudResource
 								}
 								list = append(list, storage)
 							}
-							// TODO(garuppel): Handle BlockStorage resources?
+							// TODO(garuppel): Handle Storage Accounts with HttpEndpoint
+							// TODO(garuppel): Handle BlockStorage resources
 						}
 					}
 				}
@@ -193,7 +194,7 @@ func (d *azureARMTemplateDiscovery) handleObjectStorage(resourceValue map[string
 
 	storage = &voc.ObjectStorage{
 		Storage: &voc.Storage{
-			CloudResource: &voc.CloudResource{
+			Resource: &voc.Resource{
 				ID:           voc.ResourceID(d.createID(resourceGroup, "blobServices", azureResourceName)),
 				Name:         azureResourceName,
 				CreationTime: 0, // No creation time available
@@ -204,15 +205,16 @@ func (d *azureARMTemplateDiscovery) handleObjectStorage(resourceValue map[string
 			},
 			AtRestEncryption: enc,
 		},
-		HttpEndpoint: &voc.HttpEndpoint{
-			Url: "", // not available
-			TransportEncryption: &voc.TransportEncryption{
-				Enabled:    isServiceEncryptionEnabled("blob", storageAccountResource),
-				Enforced:   isHttpsTrafficOnlyEnabled(storageAccountResource),
-				TlsVersion: minTlsVersionOfStorageAccount(storageAccountResource),
-				Algorithm:  "TLS",
-			},
-		},
+		// TODO(garuppel): Delete if handleStorageAccount is implemented
+		//HttpEndpoint: &voc.HttpEndpoint{
+		//	Url: "", // not available
+		//	TransportEncryption: &voc.TransportEncryption{
+		//		Enabled:    isServiceEncryptionEnabled("blob", storageAccountResource),
+		//		Enforced:   isHttpsTrafficOnlyEnabled(storageAccountResource),
+		//		TlsVersion: minTlsVersionOfStorageAccount(storageAccountResource),
+		//		Algorithm:  "TLS",
+		//	},
+		//},
 	}
 
 	return storage, nil
@@ -247,7 +249,7 @@ func (d *azureARMTemplateDiscovery) handleFileStorage(resourceValue map[string]i
 
 	storage = &voc.FileStorage{
 		Storage: &voc.Storage{
-			CloudResource: &voc.CloudResource{
+			Resource: &voc.Resource{
 				ID:           voc.ResourceID(d.createID(resourceGroup, "fileServices", azureResourceName)),
 				Name:         azureResourceName,
 				CreationTime: 0, // No creation time available
@@ -258,15 +260,16 @@ func (d *azureARMTemplateDiscovery) handleFileStorage(resourceValue map[string]i
 			},
 			AtRestEncryption: enc,
 		},
-		HttpEndpoint: &voc.HttpEndpoint{
-			Url: "", // not available
-			TransportEncryption: &voc.TransportEncryption{
-				Enabled:    isServiceEncryptionEnabled("file", storageAccountResource),
-				Enforced:   isHttpsTrafficOnlyEnabled(storageAccountResource),
-				TlsVersion: minTlsVersionOfStorageAccount(storageAccountResource),
-				Algorithm:  "TLS",
-			},
-		},
+		// TODO(garuppel): Delete if handleStorageAccount is implemented
+		//HttpEndpoint: &voc.HttpEndpoint{
+		//	Url: "", // not available
+		//	TransportEncryption: &voc.TransportEncryption{
+		//		Enabled:    isServiceEncryptionEnabled("file", storageAccountResource),
+		//		Enforced:   isHttpsTrafficOnlyEnabled(storageAccountResource),
+		//		TlsVersion: minTlsVersionOfStorageAccount(storageAccountResource),
+		//		Algorithm:  "TLS",
+		//	},
+		//},
 	}
 
 	return storage, nil
@@ -383,7 +386,7 @@ func (d *azureARMTemplateDiscovery) handleLoadBalancer(template map[string]inter
 	lb := &voc.LoadBalancer{
 		NetworkService: &voc.NetworkService{
 			Networking: &voc.Networking{
-				CloudResource: &voc.CloudResource{
+				Resource: &voc.Resource{
 					ID:           voc.ResourceID(d.createID(resourceGroup, resourceType, name)),
 					Name:         name,
 					CreationTime: 0, // No creation time available
@@ -453,7 +456,7 @@ func (d *azureARMTemplateDiscovery) handleVirtualMachine(template map[string]int
 
 	vm := &voc.VirtualMachine{
 		Compute: &voc.Compute{
-			CloudResource: &voc.CloudResource{
+			Resource: &voc.Resource{
 				ID:           voc.ResourceID(id),
 				Name:         name,
 				CreationTime: 0, // No creation time available
@@ -463,15 +466,15 @@ func (d *azureARMTemplateDiscovery) handleVirtualMachine(template map[string]int
 				},
 			},
 		},
-		BootLog: &voc.BootLog{
-			Log: &voc.Log{
+		BootLogging: &voc.BootLogging{
+			Logging: &voc.Logging{
 				Enabled:         bootDiagnosticsEnabled,
-				Output:          []voc.ResourceID{voc.ResourceID(storageUri)},
+				LoggingService:  []voc.ResourceID{voc.ResourceID(storageUri)},
 				RetentionPeriod: 0, // Currently, configuring the retention period for Managed Boot Diagnostics is not available. The logs will be overwritten after 1gb of space according to https://github.com/MicrosoftDocs/azure-docs/issues/69953
 			},
 		},
-		OSLog: &voc.OSLog{
-			Log: &voc.Log{
+		OSLogging: &voc.OSLogging{
+			Logging: &voc.Logging{
 				Enabled: false,
 			}, // TODO(all): available in ARM template/Azure?
 		},
diff --git a/service/discovery/azure/compute.go b/service/discovery/azure/compute.go
index 7285db9b..85c3f7f1 100644
--- a/service/discovery/azure/compute.go
+++ b/service/discovery/azure/compute.go
@@ -109,7 +109,7 @@ func (d *azureComputeDiscovery) discoverFunction() ([]voc.IsCloudResource, error
 func (*azureComputeDiscovery) handleFunction(function *web.Site) voc.IsCompute {
 	return &voc.Function{
 		Compute: &voc.Compute{
-			CloudResource: &voc.CloudResource{
+			Resource: &voc.Resource{
 				ID:           voc.ResourceID(to.String(function.ID)),
 				Name:         to.String(function.Name),
 				CreationTime: 0, // No creation time available
@@ -120,7 +120,6 @@ func (*azureComputeDiscovery) handleFunction(function *web.Site) voc.IsCompute {
 			},
 		},
 	}
-
 }
 
 // Discover virtual machines
@@ -154,7 +153,7 @@ func (d *azureComputeDiscovery) handleVirtualMachines(vm *compute.VirtualMachine
 
 	r := &voc.VirtualMachine{
 		Compute: &voc.Compute{
-			CloudResource: &voc.CloudResource{
+			Resource: &voc.Resource{
 				ID:           voc.ResourceID(to.String(vm.ID)),
 				Name:         to.String(vm.Name),
 				CreationTime: 0, // No creation time available
@@ -163,13 +162,12 @@ func (d *azureComputeDiscovery) handleVirtualMachines(vm *compute.VirtualMachine
 					Region: *vm.Location,
 				},
 			}},
-		BootLog: &voc.BootLog{Log: &voc.Log{
+		BootLogging: &voc.BootLogging{Logging: &voc.Logging{
 			Enabled:         isBootDiagnosticEnabled(vm),
-			Output:          []voc.ResourceID{voc.ResourceID(bootLogOutput(vm))},
+			LoggingService:  []voc.ResourceID{voc.ResourceID(bootLogOutput(vm))},
 			RetentionPeriod: 0, // Currently, configuring the retention period for Managed Boot Diagnostics is not available. The logs will be overwritten after 1gb of space according to https://github.com/MicrosoftDocs/azure-docs/issues/69953
 		}},
-		OSLog: &voc.OSLog{}, // TODO(garuppel): Add OSLog
-		// TODO(garuppel) Add block storage resourceID
+		OSLogging:    &voc.OSLogging{}, // TODO(garuppel): Add OSLogging
 		BlockStorage: []voc.ResourceID{},
 	}
 
diff --git a/service/discovery/azure/network.go b/service/discovery/azure/network.go
index bcd7e67c..b4196841 100644
--- a/service/discovery/azure/network.go
+++ b/service/discovery/azure/network.go
@@ -137,7 +137,7 @@ func (d *azureNetworkDiscovery) handleLoadBalancer(lb *network.LoadBalancer) voc
 	return &voc.LoadBalancer{
 		NetworkService: &voc.NetworkService{
 			Networking: &voc.Networking{
-				CloudResource: &voc.CloudResource{
+				Resource: &voc.Resource{
 					ID:           voc.ResourceID(to.String(lb.ID)),
 					Name:         to.String(lb.Name),
 					CreationTime: 0, // No creation time available
@@ -160,7 +160,7 @@ func (d *azureNetworkDiscovery) handleLoadBalancer(lb *network.LoadBalancer) voc
 func (*azureNetworkDiscovery) handleNetworkInterfaces(ni *network.Interface) voc.IsNetwork {
 	return &voc.NetworkInterface{
 		Networking: &voc.Networking{
-			CloudResource: &voc.CloudResource{
+			Resource: &voc.Resource{
 				ID:           voc.ResourceID(to.String(ni.ID)),
 				Name:         to.String(ni.Name),
 				CreationTime: 0, // No creation time available
diff --git a/service/discovery/azure/storage.go b/service/discovery/azure/storage.go
index 90b639cc..964b2cf1 100644
--- a/service/discovery/azure/storage.go
+++ b/service/discovery/azure/storage.go
@@ -82,7 +82,7 @@ func (d *azureStorageDiscovery) List() (list []voc.IsCloudResource, err error) {
 }
 
 func (d *azureStorageDiscovery) discoverStorageAccounts() ([]voc.IsCloudResource, error) {
-	var list []voc.IsCloudResource
+	var storageResourcesList []voc.IsCloudResource
 
 	client := storage.NewAccountsClient(to.String(d.sub.SubscriptionID))
 	d.apply(&client.Client)
@@ -94,23 +94,32 @@ func (d *azureStorageDiscovery) discoverStorageAccounts() ([]voc.IsCloudResource
 
 	// Discover object and file storages
 	accounts := result.Values()
-	for i := range accounts {
+	for _, account := range accounts {
 		// Discover object storages
-		objectStorages, err := d.discoverObjectStorages(&accounts[i])
+		objectStorages, err := d.discoverObjectStorages(&account)
 		if err != nil {
 			return nil, fmt.Errorf("could not handle object storages: %w", err)
 		}
+		log.Infof("Adding object storages %+v", objectStorages)
 
 		// Discover file storages
-		fileStorages, err := d.discoverFileStorages(&accounts[i])
+		fileStorages, err := d.discoverFileStorages(&account)
 		if err != nil {
 			return nil, fmt.Errorf("could not handle file storages: %w", err)
 		}
+		log.Infof("Adding file storages %+v", fileStorages)
+
+		storageResourcesList = append(storageResourcesList, objectStorages...)
+		storageResourcesList = append(storageResourcesList, fileStorages...)
 
+		// Create storage service for all storage account resources
+		storageService, err := d.handleStorageAccount(&account, storageResourcesList)
+		if err != nil {
+			return nil, fmt.Errorf("could not create storage service: %w", err)
+		}
 		log.Infof("Adding storage account %+v", objectStorages)
 
-		list = append(list, objectStorages...)
-		list = append(list, fileStorages...)
+		storageResourcesList = append(storageResourcesList, storageService)
 	}
 
 	// Discover block storages
@@ -118,9 +127,9 @@ func (d *azureStorageDiscovery) discoverStorageAccounts() ([]voc.IsCloudResource
 	if err != nil {
 		return nil, fmt.Errorf("could not handle block storages: %w", err)
 	}
-	list = append(list, blockStorages...)
+	storageResourcesList = append(storageResourcesList, blockStorages...)
 
-	return list, err
+	return storageResourcesList, err
 }
 
 func (d *azureStorageDiscovery) discoverBlockStorages() ([]voc.IsCloudResource, error) {
@@ -135,7 +144,7 @@ func (d *azureStorageDiscovery) discoverBlockStorages() ([]voc.IsCloudResource,
 	}
 
 	for _, disk := range *result.Response().Value {
-		blockStorages, err := d.handleBlockStorage(disk)
+		blockStorages, err := d.handleBlockStorage(&disk)
 		if err != nil {
 			return nil, fmt.Errorf("could not handle block storage: %w", err)
 		}
@@ -196,7 +205,7 @@ func (d *azureStorageDiscovery) discoverObjectStorages(account *storage.Account)
 	return list, nil
 }
 
-func (d *azureStorageDiscovery) handleBlockStorage(disk compute.Disk) (*voc.BlockStorage, error) {
+func (d *azureStorageDiscovery) handleBlockStorage(disk *compute.Disk) (*voc.BlockStorage, error) {
 	enc, err := d.blockStorageAtRestEncryption(disk)
 	if err != nil {
 		return nil, fmt.Errorf("could not get block storage properties for the atRestEncryption: %w", err)
@@ -204,7 +213,7 @@ func (d *azureStorageDiscovery) handleBlockStorage(disk compute.Disk) (*voc.Bloc
 
 	return &voc.BlockStorage{
 		Storage: &voc.Storage{
-			CloudResource: &voc.CloudResource{
+			Resource: &voc.Resource{
 				ID:           voc.ResourceID(to.String(disk.ID)),
 				Name:         to.String(disk.Name),
 				CreationTime: disk.TimeCreated.Unix(),
@@ -226,7 +235,7 @@ func handleObjectStorage(account *storage.Account, container storage.ListContain
 
 	return &voc.ObjectStorage{
 		Storage: &voc.Storage{
-			CloudResource: &voc.CloudResource{
+			Resource: &voc.Resource{
 				ID:           voc.ResourceID(to.String(container.ID)),
 				Name:         to.String(container.Name),
 				CreationTime: account.CreationTime.Unix(),
@@ -237,8 +246,34 @@ func handleObjectStorage(account *storage.Account, container storage.ListContain
 			},
 			AtRestEncryption: enc,
 		},
+	}, nil
+}
+
+func (*azureStorageDiscovery) handleStorageAccount(account *storage.Account, storagesList []voc.IsCloudResource) (*voc.StorageService, error) {
+	var storageResourceIDs []voc.ResourceID
+
+	// Get all object storage IDs
+	for _, storage := range storagesList {
+		storageResourceIDs = append(storageResourceIDs, storage.GetID())
+	}
+
+	storageService := &voc.StorageService{
+		Storages: storageResourceIDs,
+		NetworkService: &voc.NetworkService{
+			Networking: &voc.Networking{
+				Resource: &voc.Resource{
+					ID:           voc.ResourceID(to.String(account.ID)),
+					Name:         *account.Name,
+					CreationTime: account.CreationTime.Unix(),
+					Type:         []string{"StorageService", "NetworkService", "Networking", "Resource"},
+					GeoLocation: voc.GeoLocation{
+						Region: *account.Location,
+					},
+				},
+			},
+		},
 		HttpEndpoint: &voc.HttpEndpoint{
-			Url: to.String(account.PrimaryEndpoints.Blob) + to.String(container.Name),
+			Url: generalizeURL(*account.PrimaryEndpoints.Blob),
 			TransportEncryption: &voc.TransportEncryption{
 				Enforced:   to.Bool(account.EnableHTTPSTrafficOnly),
 				Enabled:    true, // cannot be disabled
@@ -246,7 +281,18 @@ func handleObjectStorage(account *storage.Account, container storage.ListContain
 				Algorithm:  "TLS",
 			},
 		},
-	}, nil
+	}
+
+	return storageService, nil
+}
+
+//generalizeURL generalizes the URL, because the URL depends on the storage type
+func generalizeURL(url string) string {
+	urlSplit := strings.Split(url, ".")
+	urlSplit[1] = "[file,blob]"
+	newURL := strings.Join(urlSplit, ".")
+
+	return newURL
 }
 
 func handleFileStorage(account *storage.Account, fileshare storage.FileShareItem) (*voc.FileStorage, error) {
@@ -254,9 +300,10 @@ func handleFileStorage(account *storage.Account, fileshare storage.FileShareItem
 	if err != nil {
 		return nil, fmt.Errorf("could not get file storage properties for the atRestEncryption: %w", err)
 	}
+
 	return &voc.FileStorage{
 		Storage: &voc.Storage{
-			CloudResource: &voc.CloudResource{
+			Resource: &voc.Resource{
 				ID:           voc.ResourceID(to.String(fileshare.ID)),
 				Name:         to.String(fileshare.Name),
 				CreationTime: account.CreationTime.Unix(),
@@ -267,19 +314,10 @@ func handleFileStorage(account *storage.Account, fileshare storage.FileShareItem
 			},
 			AtRestEncryption: enc,
 		},
-		HttpEndpoint: &voc.HttpEndpoint{
-			Url: to.String(account.PrimaryEndpoints.File) + to.String(fileshare.Name),
-			TransportEncryption: &voc.TransportEncryption{
-				Enforced:   to.Bool(account.EnableHTTPSTrafficOnly),
-				Enabled:    true, // cannot be disabled
-				TlsVersion: string(account.MinimumTLSVersion),
-				Algorithm:  "TLS",
-			},
-		},
 	}, nil
 }
 
-func (d *azureStorageDiscovery) blockStorageAtRestEncryption(disk compute.Disk) (voc.HasAtRestEncryption, error) {
+func (d *azureStorageDiscovery) blockStorageAtRestEncryption(disk *compute.Disk) (voc.HasAtRestEncryption, error) {
 
 	var enc voc.HasAtRestEncryption
 
diff --git a/service/discovery/k8s/compute.go b/service/discovery/k8s/compute.go
index 305602ad..2a66517e 100644
--- a/service/discovery/k8s/compute.go
+++ b/service/discovery/k8s/compute.go
@@ -50,16 +50,16 @@ func (*k8sComputeDiscovery) Description() string {
 	return "Discover Kubernetes compute resources."
 }
 
-func (k k8sComputeDiscovery) List() ([]voc.IsCloudResource, error) {
+func (d k8sComputeDiscovery) List() ([]voc.IsCloudResource, error) {
 	var list []voc.IsCloudResource
 
-	pods, err := k.intf.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
+	pods, err := d.intf.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
 	if err != nil {
 		return nil, fmt.Errorf("could not list ingresses: %v", err)
 	}
 
 	for i := range pods.Items {
-		c := k.handlePod(&pods.Items[i])
+		c := d.handlePod(&pods.Items[i])
 
 		log.Infof("Adding container %+v", c)
 
@@ -72,7 +72,7 @@ func (k k8sComputeDiscovery) List() ([]voc.IsCloudResource, error) {
 func (k8sComputeDiscovery) handlePod(pod *v1.Pod) voc.IsCompute {
 	r := &voc.Container{
 		Compute: &voc.Compute{
-			CloudResource: &voc.CloudResource{
+			Resource: &voc.Resource{
 				ID:           voc.ResourceID(getContainerResourceID(pod)),
 				Name:         pod.Name,
 				CreationTime: pod.CreationTimestamp.Unix(),
diff --git a/service/discovery/k8s/network.go b/service/discovery/k8s/network.go
index f91c5dfe..3eb6b387 100644
--- a/service/discovery/k8s/network.go
+++ b/service/discovery/k8s/network.go
@@ -51,16 +51,16 @@ func (*k8sNetworkDiscovery) Description() string {
 	return "Discover Kubernetes network resources."
 }
 
-func (k k8sNetworkDiscovery) List() ([]voc.IsCloudResource, error) {
+func (d k8sNetworkDiscovery) List() ([]voc.IsCloudResource, error) {
 	var list []voc.IsCloudResource
 
-	services, err := k.intf.CoreV1().Services("").List(context.TODO(), metav1.ListOptions{})
+	services, err := d.intf.CoreV1().Services("").List(context.TODO(), metav1.ListOptions{})
 	if err != nil {
 		return nil, fmt.Errorf("could not list services: %w", err)
 	}
 
 	for i := range services.Items {
-		c := k.handleService(&services.Items[i])
+		c := d.handleService(&services.Items[i])
 
 		log.Infof("Adding service %+v", c)
 
@@ -68,13 +68,13 @@ func (k k8sNetworkDiscovery) List() ([]voc.IsCloudResource, error) {
 	}
 
 	// TODO Does not get ingresses
-	ingresses, err := k.intf.NetworkingV1().Ingresses("").List(context.TODO(), metav1.ListOptions{})
+	ingresses, err := d.intf.NetworkingV1().Ingresses("").List(context.TODO(), metav1.ListOptions{})
 	if err != nil {
 		return list, fmt.Errorf("could not list ingresses: %w", err)
 	}
 
 	for i := range ingresses.Items {
-		c := k.handleIngress(&ingresses.Items[i])
+		c := d.handleIngress(&ingresses.Items[i])
 
 		log.Infof("Adding ingress %+v", c)
 
@@ -93,7 +93,7 @@ func (k8sNetworkDiscovery) handleService(service *corev1.Service) voc.IsNetwork
 
 	return &voc.NetworkService{
 		Networking: &voc.Networking{
-			CloudResource: &voc.CloudResource{
+			Resource: &voc.Resource{
 				ID:           voc.ResourceID(getNetworkServiceResourceID(service)),
 				Name:         service.Name,
 				CreationTime: service.CreationTimestamp.Unix(),
@@ -116,7 +116,7 @@ func (k8sNetworkDiscovery) handleIngress(ingress *v1.Ingress) voc.IsNetwork {
 	lb := &voc.LoadBalancer{
 		NetworkService: &voc.NetworkService{
 			Networking: &voc.Networking{
-				CloudResource: &voc.CloudResource{
+				Resource: &voc.Resource{
 					ID:           voc.ResourceID(getLoadBalancerResourceID(ingress)),
 					Name:         ingress.Name,
 					CreationTime: ingress.CreationTimestamp.Unix(),
diff --git a/voc/account.go b/voc/account.go
index 96496da1..c92eea80 100644
--- a/voc/account.go
+++ b/voc/account.go
@@ -26,5 +26,5 @@
 package voc
 
 type Account struct {
-	*CloudResource
+	*Resource
 }
diff --git a/voc/activity_logging.go b/voc/activity_logging.go
new file mode 100644
index 00000000..06eaf781
--- /dev/null
+++ b/voc/activity_logging.go
@@ -0,0 +1,30 @@
+// 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.
+
+package voc
+
+type ActivityLogging struct {
+	*Logging
+}
diff --git a/voc/anomaly_detection.go b/voc/anomaly_detection.go
index 6f6196c4..0eed75ee 100644
--- a/voc/anomaly_detection.go
+++ b/voc/anomaly_detection.go
@@ -27,6 +27,6 @@ package voc
 
 type AnomalyDetection struct {
 	*Auditing
-	Output  []ResourceID `json:"output"`
-	Enabled bool         `json:"enabled"`
+	ApplicationLogging *ApplicationLogging `json:"applicationLogging"`
+	Enabled            bool                `json:"enabled"`
 }
diff --git a/voc/application_logging.go b/voc/application_logging.go
new file mode 100644
index 00000000..3f5e4e3c
--- /dev/null
+++ b/voc/application_logging.go
@@ -0,0 +1,30 @@
+// 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.
+
+package voc
+
+type ApplicationLogging struct {
+	*Logging
+}
diff --git a/voc/automatic_updates.go b/voc/automatic_updates.go
index 85d5e8e4..d5d78877 100644
--- a/voc/automatic_updates.go
+++ b/voc/automatic_updates.go
@@ -30,6 +30,6 @@ import "time"
 type AutomaticUpdates struct {
 	*Integrity
 	Enabled      bool          `json:"enabled"`
-	Interval     time.Duration `json:"interval"`
 	SecurityOnly bool          `json:"securityOnly"`
+	Interval     time.Duration `json:"interval"`
 }
diff --git a/voc/backup.go b/voc/backup.go
index 3fbb47df..0962582c 100644
--- a/voc/backup.go
+++ b/voc/backup.go
@@ -25,8 +25,11 @@
 
 package voc
 
+import "time"
+
 type Backup struct {
 	*Availability
-	Activated bool   `json:"activated"`
-	Policy    string `json:"policy"`
+	RetentionPeriod time.Duration `json:"retentionPeriod"`
+	Enabled         bool          `json:"enabled"`
+	Policy          string        `json:"policy"`
 }
diff --git a/voc/boot_logging.go b/voc/boot_logging.go
new file mode 100644
index 00000000..b848a501
--- /dev/null
+++ b/voc/boot_logging.go
@@ -0,0 +1,30 @@
+// 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.
+
+package voc
+
+type BootLogging struct {
+	*Logging
+}
diff --git a/voc/cicd_service.go b/voc/cicd_service.go
index 848d78c4..a1353598 100644
--- a/voc/cicd_service.go
+++ b/voc/cicd_service.go
@@ -26,5 +26,5 @@
 package voc
 
 type CICDService struct {
-	*CloudResource
+	*Resource
 }
diff --git a/voc/cloud_resource_group.go b/voc/cloud_resource_group.go
index 47621b86..2359a25e 100644
--- a/voc/cloud_resource_group.go
+++ b/voc/cloud_resource_group.go
@@ -26,5 +26,5 @@
 package voc
 
 type CloudResourceGroup struct {
-	CloudResources *[]CloudResource `json:"cloudResources"`
+	Resources *[]Resource `json:"resources"`
 }
diff --git a/voc/compute.go b/voc/compute.go
index be14783f..3c4015a4 100644
--- a/voc/compute.go
+++ b/voc/compute.go
@@ -26,5 +26,6 @@
 package voc
 
 type Compute struct {
-	*CloudResource
+	*Resource
+	NetworkInterface []ResourceID `json:"networkInterface"`
 }
diff --git a/voc/container.go b/voc/container.go
index cb6461ca..bae09d18 100644
--- a/voc/container.go
+++ b/voc/container.go
@@ -27,6 +27,5 @@ package voc
 
 type Container struct {
 	*Compute
-	Image            []ResourceID `json:"image"`
-	NetworkInterface []ResourceID `json:"networkInterface"`
+	Image []ResourceID `json:"image"`
 }
diff --git a/voc/container_orchestration.go b/voc/container_orchestration.go
index a49a6f2a..01f489b6 100644
--- a/voc/container_orchestration.go
+++ b/voc/container_orchestration.go
@@ -26,8 +26,7 @@
 package voc
 
 type ContainerOrchestration struct {
-	*CloudResource
-	ResourceLogging []ResourceID `json:"resourceLogging"`
-	Containers      []ResourceID `json:"containers"`
-	ManagementUrl   string       `json:"managementUrl"`
+	*Resource
+	Containers    []ResourceID `json:"containers"`
+	ManagementUrl string       `json:"managementUrl"`
 }
diff --git a/voc/container_registry.go b/voc/container_registry.go
index 438d665d..f3c84309 100644
--- a/voc/container_registry.go
+++ b/voc/container_registry.go
@@ -26,5 +26,5 @@
 package voc
 
 type ContainerRegistry struct {
-	*CloudResource
+	*Resource
 }
diff --git a/voc/database_operation.go b/voc/database_operation.go
index 8457deae..ea432073 100644
--- a/voc/database_operation.go
+++ b/voc/database_operation.go
@@ -26,7 +26,7 @@
 package voc
 
 type DatabaseOperation struct {
-	*Functionality
+	*Operation
 	Storage         []ResourceID `json:"storage"`
 	DatabaseService []ResourceID `json:"databaseService"`
 	Calls           []string     `json:"calls"`
diff --git a/voc/database_service.go b/voc/database_service.go
index 87179dff..8c2cb569 100644
--- a/voc/database_service.go
+++ b/voc/database_service.go
@@ -26,6 +26,5 @@
 package voc
 
 type DatabaseService struct {
-	*NetworkService
-	DatabaseStorages []ResourceID `json:"databaseStorages"`
+	*StorageService
 }
diff --git a/voc/file_storage.go b/voc/file_storage.go
index 91557505..386a3285 100644
--- a/voc/file_storage.go
+++ b/voc/file_storage.go
@@ -27,5 +27,4 @@ package voc
 
 type FileStorage struct {
 	*Storage
-	HttpEndpoint *HttpEndpoint `json:"httpEndpoint"`
 }
diff --git a/voc/http_request.go b/voc/http_request.go
index d53a6c0c..41caca06 100644
--- a/voc/http_request.go
+++ b/voc/http_request.go
@@ -26,7 +26,8 @@
 package voc
 
 type HttpRequest struct {
-	*Functionality
+	*Operation
 	HttpEndpoint *HttpEndpoint `json:"httpEndpoint"`
 	Call         string        `json:"call"`
+	ReqBody      string        `json:"reqBody"`
 }
diff --git a/voc/identity_management.go b/voc/identity_management.go
index 426bbdb6..b0555fc3 100644
--- a/voc/identity_management.go
+++ b/voc/identity_management.go
@@ -26,7 +26,7 @@
 package voc
 
 type IdentityManagement struct {
-	*CloudResource
+	*Resource
 	Authenticity  *Authenticity  `json:"authenticity"`
 	Authorization *Authorization `json:"authorization"`
 }
diff --git a/voc/image.go b/voc/image.go
index 246e9a0a..246d976b 100644
--- a/voc/image.go
+++ b/voc/image.go
@@ -26,6 +26,6 @@
 package voc
 
 type Image struct {
-	*CloudResource
+	*Resource
 	Application *Application `json:"application"`
 }
diff --git a/voc/io_t.go b/voc/io_t.go
index a8362c4b..cec515cf 100644
--- a/voc/io_t.go
+++ b/voc/io_t.go
@@ -26,5 +26,5 @@
 package voc
 
 type IoT struct {
-	*CloudResource
+	*Resource
 }
diff --git a/voc/log.go b/voc/log.go
index 79543402..80989244 100644
--- a/voc/log.go
+++ b/voc/log.go
@@ -29,8 +29,6 @@ import "time"
 
 type Log struct {
 	*Auditing
-	// TODO(all): How to know resource IDs beforehand (coming from metrics)? Maybe sth. like type or ignore it completely?
-	// TODO(all): Is it enough that one item of Output matches one output of data (Rego)?
 	Output          []ResourceID  `json:"output"`
 	Enabled         bool          `json:"enabled"`
 	RetentionPeriod time.Duration `json:"retentionPeriod"`
diff --git a/voc/log_operation.go b/voc/log_operation.go
new file mode 100644
index 00000000..3de25592
--- /dev/null
+++ b/voc/log_operation.go
@@ -0,0 +1,33 @@
+// 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.
+
+package voc
+
+type LogOperation struct {
+	*Operation
+	Logging *Logging `json:"logging"`
+	Call    string   `json:"call"`
+	Value   string   `json:"value"`
+}
diff --git a/voc/logging.go b/voc/logging.go
index fa9eb042..ea28777e 100644
--- a/voc/logging.go
+++ b/voc/logging.go
@@ -25,6 +25,11 @@
 
 package voc
 
+import "time"
+
 type Logging struct {
-	*CloudResource
+	*Auditing
+	LoggingService  []ResourceID  `json:"loggingService"`
+	Enabled         bool          `json:"enabled"`
+	RetentionPeriod time.Duration `json:"retentionPeriod"`
 }
diff --git a/voc/logging_service.go b/voc/logging_service.go
new file mode 100644
index 00000000..1d1bf7bf
--- /dev/null
+++ b/voc/logging_service.go
@@ -0,0 +1,31 @@
+// 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.
+
+package voc
+
+type LoggingService struct {
+	*NetworkService
+	Storage []ResourceID `json:"storage"`
+}
diff --git a/voc/malware_protection.go b/voc/malware_protection.go
index caebc3ee..3f0b191c 100644
--- a/voc/malware_protection.go
+++ b/voc/malware_protection.go
@@ -25,8 +25,12 @@
 
 package voc
 
+import "time"
+
 type MalwareProtection struct {
 	*Auditing
-	Output  []ResourceID `json:"output"`
-	Enabled bool         `json:"enabled"`
+	ApplicationLogging   *ApplicationLogging `json:"applicationLogging"`
+	DaysSinceActive      time.Duration       `json:"daysSinceActive"`
+	NumberOfThreatsFound int                 `json:"numberOfThreatsFound"`
+	Enabled              bool                `json:"enabled"`
 }
diff --git a/voc/network_service.go b/voc/network_service.go
index 3f70f06c..ca683d90 100644
--- a/voc/network_service.go
+++ b/voc/network_service.go
@@ -27,7 +27,8 @@ package voc
 
 type NetworkService struct {
 	*Networking
-	Compute []ResourceID `json:"compute"`
-	Ips     []string     `json:"ips"`
-	Ports   []int16      `json:"ports"`
+	Compute             []ResourceID         `json:"compute"`
+	TransportEncryption *TransportEncryption `json:"transportEncryption"`
+	Ips                 []string             `json:"ips"`
+	Ports               []int16              `json:"ports"`
 }
diff --git a/voc/networking.go b/voc/networking.go
index 5d2c97f9..607f62d9 100644
--- a/voc/networking.go
+++ b/voc/networking.go
@@ -26,5 +26,5 @@
 package voc
 
 type Networking struct {
-	*CloudResource
+	*Resource
 }
diff --git a/voc/object_storage.go b/voc/object_storage.go
index 53d88bdb..a04fefc8 100644
--- a/voc/object_storage.go
+++ b/voc/object_storage.go
@@ -27,5 +27,4 @@ package voc
 
 type ObjectStorage struct {
 	*Storage
-	HttpEndpoint *HttpEndpoint `json:"httpEndpoint"`
 }
diff --git a/voc/object_storage_request.go b/voc/object_storage_request.go
index 089c3260..565b91f6 100644
--- a/voc/object_storage_request.go
+++ b/voc/object_storage_request.go
@@ -26,7 +26,7 @@
 package voc
 
 type ObjectStorageRequest struct {
-	*Functionality
+	*Operation
 	ObjectStorage []ResourceID `json:"objectStorage"`
 	Source        string       `json:"source"`
 	Type          string       `json:"type"`
diff --git a/voc/operation.go b/voc/operation.go
new file mode 100644
index 00000000..8b29f23b
--- /dev/null
+++ b/voc/operation.go
@@ -0,0 +1,30 @@
+// 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.
+
+package voc
+
+type Operation struct {
+	*Functionality
+}
diff --git a/voc/os_logging.go b/voc/os_logging.go
new file mode 100644
index 00000000..6e446386
--- /dev/null
+++ b/voc/os_logging.go
@@ -0,0 +1,30 @@
+// 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.
+
+package voc
+
+type OSLogging struct {
+	*Logging
+}
diff --git a/voc/proxied_endpoint.go b/voc/proxied_endpoint.go
index 0be7df73..d9efd78a 100644
--- a/voc/proxied_endpoint.go
+++ b/voc/proxied_endpoint.go
@@ -27,4 +27,5 @@ package voc
 
 type ProxiedEndpoint struct {
 	*HttpEndpoint
+	ProxyTarget *HttpEndpoint `json:"proxyTarget"`
 }
diff --git a/voc/storage.go b/voc/storage.go
index 4226c7ae..5bad8258 100644
--- a/voc/storage.go
+++ b/voc/storage.go
@@ -26,7 +26,6 @@
 package voc
 
 type Storage struct {
-	*CloudResource
-
+	*Resource
 	AtRestEncryption HasAtRestEncryption `json:"atRestEncryption"`
 }
diff --git a/voc/storage_service.go b/voc/storage_service.go
new file mode 100644
index 00000000..b932130f
--- /dev/null
+++ b/voc/storage_service.go
@@ -0,0 +1,32 @@
+// 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.
+
+package voc
+
+type StorageService struct {
+	*NetworkService
+	Storages     []ResourceID  `json:"storages"`
+	HttpEndpoint *HttpEndpoint `json:"httpEndpoint"`
+}
diff --git a/voc/virtual_machine.go b/voc/virtual_machine.go
index 8f378a60..33fe38cd 100644
--- a/voc/virtual_machine.go
+++ b/voc/virtual_machine.go
@@ -27,8 +27,8 @@ package voc
 
 type VirtualMachine struct {
 	*Compute
-	BlockStorage     []ResourceID `json:"blockStorage"`
-	NetworkInterface []ResourceID `json:"networkInterface"`
-	BootLog          *BootLog     `json:"bootLog"`
-	OSLog            *OSLog       `json:"oSLog"`
+	BlockStorage      []ResourceID       `json:"blockStorage"`
+	BootLogging       *BootLogging       `json:"bootLogging"`
+	MalwareProtection *MalwareProtection `json:"malwareProtection"`
+	OSLogging         *OSLogging         `json:"oSLogging"`
 }
diff --git a/voc/voc.go b/voc/voc.go
index 67a7dfb7..cc3d8665 100644
--- a/voc/voc.go
+++ b/voc/voc.go
@@ -45,8 +45,8 @@ type IsCloudResource interface {
 
 type ResourceID string
 
-// CloudResource file from Ontology currently not used. How do we merge this file with the 'CloudResource Ontology file'
-type CloudResource struct {
+// Resource file from Ontology currently not used. How do we merge this file with the 'Resource Ontology file'
+type Resource struct {
 	ID           ResourceID `json:"id"`
 	Name         string     `json:"name"`
 	CreationTime int64      `json:"creationTime"` // is set to 0 if no creation time is available
@@ -56,20 +56,20 @@ type CloudResource struct {
 	Labels      map[string]string `json:"labels"`
 }
 
-func (r *CloudResource) GetID() ResourceID {
+func (r *Resource) GetID() ResourceID {
 	return r.ID
 }
 
-func (r *CloudResource) GetName() string {
+func (r *Resource) GetName() string {
 	return r.Name
 }
 
-func (r *CloudResource) GetType() []string {
+func (r *Resource) GetType() []string {
 	return r.Type
 }
 
 // HasType checks whether the resource has the particular resourceType
-func (r *CloudResource) HasType(resourceType string) (ok bool) {
+func (r *Resource) HasType(resourceType string) (ok bool) {
 	for _, value := range r.Type {
 		if value == resourceType {
 			ok = true
@@ -80,7 +80,7 @@ func (r *CloudResource) HasType(resourceType string) (ok bool) {
 	return
 }
 
-func (r *CloudResource) GetCreationTime() *time.Time {
+func (r *Resource) GetCreationTime() *time.Time {
 	t := time.Unix(r.CreationTime, 0)
 	return &t
 }


Test patch:
diff --git a/api/evidence/evidence_test.go b/api/evidence/evidence_test.go
index 080b1aae..4ae86d28 100644
--- a/api/evidence/evidence_test.go
+++ b/api/evidence/evidence_test.go
@@ -85,7 +85,7 @@ func Test_ValidateEvidence(t *testing.T) {
 					Timestamp: timestamppb.Now(),
 					Resource: toStruct(voc.VirtualMachine{
 						Compute: &voc.Compute{
-							CloudResource: &voc.CloudResource{
+							Resource: &voc.Resource{
 								ID:   "my-resource-id",
 								Type: []string{"VirtualMachine"}},
 						},
@@ -103,7 +103,7 @@ func Test_ValidateEvidence(t *testing.T) {
 					ToolId: "mock",
 					Resource: toStruct(voc.VirtualMachine{
 						Compute: &voc.Compute{
-							CloudResource: &voc.CloudResource{
+							Resource: &voc.Resource{
 								ID:   "my-resource-id",
 								Type: []string{"VirtualMachine"}},
 						},
@@ -122,7 +122,7 @@ func Test_ValidateEvidence(t *testing.T) {
 					ToolId:    "mock",
 					Resource: toStruct(voc.VirtualMachine{
 						Compute: &voc.Compute{
-							CloudResource: &voc.CloudResource{
+							Resource: &voc.Resource{
 								ID:   "my-resource-id",
 								Type: []string{"VirtualMachine"}},
 						},
diff --git a/cli/commands/evidence/evidence_test.go b/cli/commands/evidence/evidence_test.go
index 97130bb2..96e2bc1e 100644
--- a/cli/commands/evidence/evidence_test.go
+++ b/cli/commands/evidence/evidence_test.go
@@ -57,7 +57,7 @@ func TestMain(m *testing.M) {
 		Id:        "11111111-1111-1111-1111-111111111111",
 		ToolId:    "mock",
 		Timestamp: timestamppb.Now(),
-		Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}),
+		Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}),
 	}})
 	if err != nil {
 		panic(err)
diff --git a/cli/commands/resource/resource_test.go b/cli/commands/resource/resource_test.go
index 2bb71462..a2f710ad 100644
--- a/cli/commands/resource/resource_test.go
+++ b/cli/commands/resource/resource_test.go
@@ -103,12 +103,24 @@ func (m mockDiscoverer) List() ([]voc.IsCloudResource, error) {
 		return []voc.IsCloudResource{
 			&voc.ObjectStorage{
 				Storage: &voc.Storage{
-					CloudResource: &voc.CloudResource{
+					Resource: &voc.Resource{
 						ID:   "some-id",
 						Name: "some-name",
 						Type: []string{"ObjectStorage", "Storage", "Resource"},
 					},
 				},
+			},
+			&voc.StorageService{
+				Storages: []voc.ResourceID{"some-id"},
+				NetworkService: &voc.NetworkService{
+					Networking: &voc.Networking{
+						Resource: &voc.Resource{
+							ID:   "some-storage-service-id",
+							Name: "some-storage-service-name",
+							Type: []string{"StorageService", "NetworkService", "Networking", "Resource"},
+						},
+					},
+				},
 				HttpEndpoint: &voc.HttpEndpoint{
 					TransportEncryption: &voc.TransportEncryption{
 						Enforced:   false,
diff --git a/cli/commands/service/discovery/discovery_test.go b/cli/commands/service/discovery/discovery_test.go
index 1f61a74c..ad49724c 100644
--- a/cli/commands/service/discovery/discovery_test.go
+++ b/cli/commands/service/discovery/discovery_test.go
@@ -118,12 +118,24 @@ func (m mockDiscoverer) List() ([]voc.IsCloudResource, error) {
 		return []voc.IsCloudResource{
 			&voc.ObjectStorage{
 				Storage: &voc.Storage{
-					CloudResource: &voc.CloudResource{
+					Resource: &voc.Resource{
 						ID:   "some-id",
 						Name: "some-name",
 						Type: []string{"ObjectStorage", "Storage", "Resource"},
 					},
 				},
+			},
+			&voc.StorageService{
+				Storages: []voc.ResourceID{"some-id"},
+				NetworkService: &voc.NetworkService{
+					Networking: &voc.Networking{
+						Resource: &voc.Resource{
+							ID:   "some-storage-service-id",
+							Name: "some-storage-service-name",
+							Type: []string{"StorageService", "NetworkService", "Networking", "Resource"},
+						},
+					},
+				},
 				HttpEndpoint: &voc.HttpEndpoint{
 					TransportEncryption: &voc.TransportEncryption{
 						Enforced:   false,
diff --git a/policies/policies_test.go b/policies/policies_test.go
index ca294a23..f20faf2f 100644
--- a/policies/policies_test.go
+++ b/policies/policies_test.go
@@ -78,7 +78,7 @@ func TestRunEvidence(t *testing.T) {
 			fields: fields{
 				resource: voc.ObjectStorage{
 					Storage: &voc.Storage{
-						CloudResource: &voc.CloudResource{
+						Resource: &voc.Resource{
 							ID:           mockObjStorage1ResourceID,
 							CreationTime: 1621086669,
 							Type:         []string{"ObjectStorage", "Storage", "Resource"},
@@ -92,20 +92,6 @@ func TestRunEvidence(t *testing.T) {
 							KeyUrl: "SomeUrl",
 						},
 					},
-					HttpEndpoint: &voc.HttpEndpoint{
-						Functionality: nil,
-						Authenticity:  nil,
-						TransportEncryption: &voc.TransportEncryption{
-							Enforced:   true,
-							Enabled:    true,
-							TlsVersion: "TLS1.3",
-							Algorithm:  "TLS",
-						},
-						Url:     "https://aybazestorage.blob.core.windows.net/",
-						Method:  "",
-						Handler: "",
-						Path:    "",
-					},
 				},
 				evidenceID: mockObjStorage1EvidenceID,
 			},
@@ -118,7 +104,7 @@ func TestRunEvidence(t *testing.T) {
 			fields: fields{
 				resource: voc.ObjectStorage{
 					Storage: &voc.Storage{
-						CloudResource: &voc.CloudResource{
+						Resource: &voc.Resource{
 							ID:           mockObjStorage2ResourceID,
 							CreationTime: 1621086669,
 							Type:         []string{"ObjectStorage", "Storage", "Resource"},
@@ -129,20 +115,6 @@ func TestRunEvidence(t *testing.T) {
 							Enabled:   false,
 						},
 					},
-					HttpEndpoint: &voc.HttpEndpoint{
-						Functionality: nil,
-						Authenticity:  nil,
-						TransportEncryption: &voc.TransportEncryption{
-							Enforced:   false,
-							Enabled:    false,
-							TlsVersion: "1.0",
-							Algorithm:  "NoTLS",
-						},
-						Url:     "https://aybazestorage.blob.core.windows.net/",
-						Method:  "",
-						Handler: "",
-						Path:    "",
-					},
 				},
 				evidenceID: mockObjStorage2EvidenceID,
 			},
@@ -156,7 +128,7 @@ func TestRunEvidence(t *testing.T) {
 			fields: fields{
 				resource: voc.ObjectStorage{
 					Storage: &voc.Storage{
-						CloudResource: &voc.CloudResource{
+						Resource: &voc.Resource{
 							ID:           mockObjStorage2ResourceID,
 							CreationTime: 1621086669,
 							Type:         []string{"ObjectStorage", "Storage", "Resource"},
@@ -170,20 +142,6 @@ func TestRunEvidence(t *testing.T) {
 							},
 						},
 					},
-					HttpEndpoint: &voc.HttpEndpoint{
-						Functionality: nil,
-						Authenticity:  nil,
-						TransportEncryption: &voc.TransportEncryption{
-							Enforced:   false,
-							Enabled:    false,
-							TlsVersion: "1.0",
-							Algorithm:  "NoTLS",
-						},
-						Url:     "https://aybazestorage.blob.core.windows.net/",
-						Method:  "",
-						Handler: "",
-						Path:    "",
-					},
 				},
 				evidenceID: mockObjStorage2EvidenceID,
 			},
@@ -197,26 +155,37 @@ func TestRunEvidence(t *testing.T) {
 			fields: fields{
 				resource: voc.VirtualMachine{
 					Compute: &voc.Compute{
-						CloudResource: &voc.CloudResource{
+						Resource: &voc.Resource{
 							ID:   mockVM1ResourceID,
-							Type: []string{"Compute", "Virtual Machine", "Resource"},
+							Type: []string{"Virtual Machine", "Compute", "Resource"},
 						}},
-					NetworkInterface: nil,
-					BlockStorage:     nil,
-					BootLog: &voc.BootLog{
-						Log: &voc.Log{
-							Output:          []voc.ResourceID{"SomeResourceId1", "SomeResourceId2"},
+					BlockStorage: nil,
+					BootLogging: &voc.BootLogging{
+						Logging: &voc.Logging{
+							LoggingService:  []voc.ResourceID{"SomeResourceId1", "SomeResourceId2"},
 							Enabled:         true,
 							RetentionPeriod: 36,
 						},
 					},
-					OSLog: &voc.OSLog{
-						Log: &voc.Log{
-							Output:          []voc.ResourceID{"SomeResourceId2"},
+					OSLogging: &voc.OSLogging{
+						Logging: &voc.Logging{
+							LoggingService:  []voc.ResourceID{"SomeResourceId2"},
 							Enabled:         true,
 							RetentionPeriod: 36,
 						},
 					},
+					MalwareProtection: &voc.MalwareProtection{
+						Enabled:              true,
+						DaysSinceActive:      5,
+						NumberOfThreatsFound: 5,
+						ApplicationLogging: &voc.ApplicationLogging{
+							Logging: &voc.Logging{
+								Enabled:         true,
+								RetentionPeriod: 36,
+								LoggingService:  []voc.ResourceID{"SomeAnalyticsService?"},
+							},
+						},
+					},
 				},
 				evidenceID: mockVM1EvidenceID,
 			},
@@ -230,22 +199,21 @@ func TestRunEvidence(t *testing.T) {
 			fields: fields{
 				resource: voc.VirtualMachine{
 					Compute: &voc.Compute{
-						CloudResource: &voc.CloudResource{
+						Resource: &voc.Resource{
 							ID:   mockVM2ResourceID,
 							Type: []string{"Compute", "Virtual Machine", "Resource"},
 						}},
-					NetworkInterface: nil,
-					BlockStorage:     nil,
-					BootLog: &voc.BootLog{
-						Log: &voc.Log{
-							Output:          []voc.ResourceID{},
+					BlockStorage: nil,
+					BootLogging: &voc.BootLogging{
+						Logging: &voc.Logging{
+							LoggingService:  []voc.ResourceID{},
 							Enabled:         false,
 							RetentionPeriod: 1,
 						},
 					},
-					OSLog: &voc.OSLog{
-						Log: &voc.Log{
-							Output:          []voc.ResourceID{"SomeResourceId3"},
+					OSLogging: &voc.OSLogging{
+						Logging: &voc.Logging{
+							LoggingService:  []voc.ResourceID{"SomeResourceId3"},
 							Enabled:         false,
 							RetentionPeriod: 1,
 						},
diff --git a/service/assessment/assessment_test.go b/service/assessment/assessment_test.go
index 52e2fefb..41e70012 100644
--- a/service/assessment/assessment_test.go
+++ b/service/assessment/assessment_test.go
@@ -166,7 +166,7 @@ func TestAssessEvidence(t *testing.T) {
 				evidence: &evidence.Evidence{
 					Id:       "11111111-1111-1111-1111-111111111111",
 					ToolId:   "mock",
-					Resource: toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
+					Resource: toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
 				},
 			},
 			hasRPCConnection: true,
@@ -184,7 +184,7 @@ func TestAssessEvidence(t *testing.T) {
 					Id:        "11111111-1111-1111-1111-111111111111",
 					ToolId:    "mock",
 					Timestamp: timestamppb.Now(),
-					Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
+					Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
 				},
 			},
 			hasRPCConnection: true,
@@ -201,7 +201,7 @@ func TestAssessEvidence(t *testing.T) {
 					Id:        "11111111-1111-1111-1111-111111111111",
 					ToolId:    "mock",
 					Timestamp: timestamppb.Now(),
-					Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
+					Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
 				},
 			},
 			hasRPCConnection: false,
@@ -268,7 +268,7 @@ func TestAssessEvidences(t *testing.T) {
 				streamToServer: createMockAssessmentServerStream(&assessment.AssessEvidenceRequest{
 					Evidence: &evidence.Evidence{
 						Timestamp: timestamppb.Now(),
-						Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t)}}),
+						Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t)}}),
 			},
 			wantErr: false,
 			wantRespMessage: &assessment.AssessEvidenceResponse{
@@ -286,7 +286,7 @@ func TestAssessEvidences(t *testing.T) {
 					Evidence: &evidence.Evidence{
 						Timestamp: timestamppb.Now(),
 						ToolId:    "2134",
-						Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t)}}),
+						Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t)}}),
 			},
 			wantErr: false,
 			wantRespMessage: &assessment.AssessEvidenceResponse{
@@ -303,7 +303,7 @@ func TestAssessEvidences(t *testing.T) {
 					Evidence: &evidence.Evidence{
 						Timestamp: timestamppb.Now(),
 						ToolId:    "2134",
-						Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t)}}),
+						Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t)}}),
 			},
 			wantErr: false,
 			wantRespMessage: &assessment.AssessEvidenceResponse{
@@ -321,7 +321,7 @@ func TestAssessEvidences(t *testing.T) {
 					Evidence: &evidence.Evidence{
 						Timestamp: timestamppb.Now(),
 						ToolId:    "2134",
-						Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t)}}),
+						Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t)}}),
 			},
 			wantErr:        true,
 			wantErrMessage: "rpc error: code = Unknown desc = cannot send response to the client",
@@ -336,7 +336,7 @@ func TestAssessEvidences(t *testing.T) {
 					Evidence: &evidence.Evidence{
 						Timestamp: timestamppb.Now(),
 						ToolId:    "2134",
-						Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t)}}),
+						Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t)}}),
 			},
 			wantErr:        true,
 			wantErrMessage: "rpc error: code = Unknown desc = cannot receive stream request",
@@ -388,9 +388,10 @@ func TestAssessmentResultHooks(t *testing.T) {
 	var (
 		hookCallCounter = 0
 		wg              sync.WaitGroup
+		hookCounts      = 16
 	)
 
-	wg.Add(12)
+	wg.Add(hookCounts)
 
 	firstHookFunction := func(assessmentResult *assessment.AssessmentResult, err error) {
 		hookCallCounter++
@@ -424,11 +425,36 @@ func TestAssessmentResultHooks(t *testing.T) {
 						Id:        "11111111-1111-1111-1111-111111111111",
 						ToolId:    "mock",
 						Timestamp: timestamppb.Now(),
-						Resource: toStruct(voc.VirtualMachine{
+						Resource: toStruct(&voc.VirtualMachine{
 							Compute: &voc.Compute{
-								CloudResource: &voc.CloudResource{
+								Resource: &voc.Resource{
 									ID:   "my-resource-id",
-									Type: []string{"VirtualMachine"}},
+									Type: []string{"VirtualMachine", "Compute", "Resource"}},
+							},
+							BootLogging: &voc.BootLogging{
+								Logging: &voc.Logging{
+									LoggingService:  []voc.ResourceID{"SomeResourceId2"},
+									Enabled:         true,
+									RetentionPeriod: 36,
+								},
+							},
+							OSLogging: &voc.OSLogging{
+								Logging: &voc.Logging{
+									LoggingService:  []voc.ResourceID{"SomeResourceId2"},
+									Enabled:         true,
+									RetentionPeriod: 36,
+								},
+							},
+							MalwareProtection: &voc.MalwareProtection{
+								Enabled:              true,
+								NumberOfThreatsFound: 5,
+								DaysSinceActive:      20,
+								ApplicationLogging: &voc.ApplicationLogging{
+									Logging: &voc.Logging{
+										Enabled:        true,
+										LoggingService: []voc.ResourceID{"SomeAnalyticsService?"},
+									},
+								},
 							},
 						}, t),
 					}},
@@ -459,7 +485,7 @@ func TestAssessmentResultHooks(t *testing.T) {
 			// To test the hooks we have to call a function that calls the hook function
 			gotResp, err := s.AssessEvidence(tt.args.in0, tt.args.evidence)
 
-			// wait for all hooks (6 metrics * 2 hooks)
+			// wait for all hooks (2 metrics * 2 hooks)
 			wg.Wait()
 
 			if (err != nil) != tt.wantErr {
@@ -472,7 +498,7 @@ func TestAssessmentResultHooks(t *testing.T) {
 
 			assert.Equal(t, tt.wantResp, gotResp)
 			assert.NotEmpty(t, s.results)
-			assert.Equal(t, 12, hookCallCounter)
+			assert.Equal(t, hookCounts, hookCallCounter)
 		})
 	}
 }
@@ -486,7 +512,7 @@ func TestListAssessmentResults(t *testing.T) {
 			Id:        "11111111-1111-1111-1111-111111111111",
 			ToolId:    "mock",
 			Timestamp: timestamppb.Now(),
-			Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
+			Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
 		}})
 	assert.NoError(t, err)
 	var results *assessment.ListAssessmentResultsResponse
@@ -742,7 +768,7 @@ func TestHandleEvidence(t *testing.T) {
 					Id:        "11111111-1111-1111-1111-111111111111",
 					ToolId:    "mock",
 					Timestamp: timestamppb.Now(),
-					Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
+					Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
 				},
 				resourceId: "my-resource-id",
 			},
@@ -762,7 +788,7 @@ func TestHandleEvidence(t *testing.T) {
 					Id:        "11111111-1111-1111-1111-111111111111",
 					ToolId:    "mock",
 					Timestamp: timestamppb.Now(),
-					Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{}}}}, t),
+					Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{}}}}, t),
 				},
 				resourceId: "my-resource-id",
 			},
@@ -784,7 +810,7 @@ func TestHandleEvidence(t *testing.T) {
 					Id:        "11111111-1111-1111-1111-111111111111",
 					ToolId:    "mock",
 					Timestamp: timestamppb.Now(),
-					Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
+					Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
 				},
 				resourceId: "my-resource-id",
 			},
@@ -807,7 +833,7 @@ func TestHandleEvidence(t *testing.T) {
 					Id:        "11111111-1111-1111-1111-111111111111",
 					ToolId:    "mock",
 					Timestamp: timestamppb.Now(),
-					Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{CloudResource: &voc.CloudResource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
+					Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
 				},
 				resourceId: "my-resource-id",
 			},
diff --git a/service/discovery/aws/compute_test.go b/service/discovery/aws/compute_test.go
index c09e9694..a7f0d19c 100644
--- a/service/discovery/aws/compute_test.go
+++ b/service/discovery/aws/compute_test.go
@@ -247,8 +247,8 @@ func TestComputeDiscovery_discoverVirtualMachines(t *testing.T) {
 	assert.Equal(t, mockVM1, testMachine.Name)
 	assert.Equal(t, voc.ResourceID("arn:aws:ec2:eu-central-1:MockAccountID1234:instance/mockVM1ID"), testMachine.ID)
 	assert.NotEmpty(t, testMachine.BlockStorage)
-	assert.False(t, testMachine.BootLog.Enabled)
-	assert.False(t, testMachine.OSLog.Enabled)
+	assert.False(t, testMachine.BootLogging.Enabled)
+	assert.False(t, testMachine.OSLogging.Enabled)
 	assert.Equal(t, int64(0), testMachine.CreationTime)
 	assert.Equal(t, mockFunction1Region, testMachine.GeoLocation.Region)
 
@@ -346,7 +346,7 @@ func TestComputeDiscovery_discoverFunctions(t *testing.T) {
 			//args: args{client: mockClient},
 			[]voc.Function{
 				{Compute: &voc.Compute{
-					CloudResource: &voc.CloudResource{
+					Resource: &voc.Resource{
 						ID:           mockFunction1ID,
 						Name:         mockFunction1,
 						CreationTime: int64(0),
diff --git a/service/discovery/aws/storage_test.go b/service/discovery/aws/storage_test.go
index 5ddd3c32..f63d7ae5 100644
--- a/service/discovery/aws/storage_test.go
+++ b/service/discovery/aws/storage_test.go
@@ -354,7 +354,7 @@ func TestAwsS3Discovery_getEncryptionAtRest(t *testing.T) {
 	}
 
 	// First case: SSE-S3 encryption
-	encryptionAtRest, err = d.getEncryptionAtRest(bucket{name: mockBucket1})
+	encryptionAtRest, err = d.getEncryptionAtRest(&bucket{name: mockBucket1})
 	assert.NoError(t, err)
 	managedEncryption, ok = encryptionAtRest.(voc.ManagedKeyEncryption)
 	assert.True(t, ok)
@@ -362,7 +362,7 @@ func TestAwsS3Discovery_getEncryptionAtRest(t *testing.T) {
 	assert.Equal(t, "AES256", managedEncryption.Algorithm)
 
 	// Second case: SSE-KMS encryption
-	encryptionAtRest, err = d.getEncryptionAtRest(bucket{name: mockBucket2, region: mockBucket2Region})
+	encryptionAtRest, err = d.getEncryptionAtRest(&bucket{name: mockBucket2, region: mockBucket2Region})
 	customerEncryption, ok = encryptionAtRest.(voc.CustomerKeyEncryption)
 	assert.True(t, ok)
 	assert.NoError(t, err)
@@ -371,7 +371,7 @@ func TestAwsS3Discovery_getEncryptionAtRest(t *testing.T) {
 	assert.Equal(t, "arn:aws:kms:"+mockBucket2Region+":"+mockAccountID+":key/"+mockBucket2KeyId, customerEncryption.KeyUrl)
 
 	// Third case: No encryption
-	encryptionAtRest, err = d.getEncryptionAtRest(bucket{name: "mockbucket3"})
+	encryptionAtRest, err = d.getEncryptionAtRest(&bucket{name: "mockbucket3"})
 	assert.NoError(t, err)
 	assert.False(t, encryptionAtRest.GetAtRestEncryption().Enabled)
 
@@ -380,7 +380,7 @@ func TestAwsS3Discovery_getEncryptionAtRest(t *testing.T) {
 		storageAPI:    mockS3APIWitHErrors{},
 		isDiscovering: false,
 	}
-	_, err = d.getEncryptionAtRest(bucket{name: "mockbucket4"})
+	_, err = d.getEncryptionAtRest(&bucket{name: "mockbucket4"})
 	assert.Error(t, err)
 }
 
@@ -464,15 +464,14 @@ func TestAwsS3Discovery_List(t *testing.T) {
 		isDiscovering: false,
 		awsConfig: &Client{
 			cfg: aws.Config{
-				Region:           mockBucket1Region,
-				Credentials:      nil,
-				HTTPClient:       nil,
-				EndpointResolver: nil,
-				Retryer:          nil,
-				ConfigSources:    nil,
-				APIOptions:       nil,
-				Logger:           nil,
-				ClientLogMode:    0,
+				Region:        mockBucket1Region,
+				Credentials:   nil,
+				HTTPClient:    nil,
+				Retryer:       nil,
+				ConfigSources: nil,
+				APIOptions:    nil,
+				Logger:        nil,
+				ClientLogMode: 0,
 			},
 			accountID: aws.String("123456789"),
 		},
@@ -481,15 +480,20 @@ func TestAwsS3Discovery_List(t *testing.T) {
 	assert.NotNil(t, err, "EXPECTED error because MockBucket2 should throw JSON error. But GOT no error")
 
 	log.Println("Testing number of resources (buckets)")
-	assert.Equal(t, 1, len(resources))
+	assert.Equal(t, 2, len(resources))
 
 	expectedResourceNames := []string{mockBucket1, "mockbucket2", "mockbucket3"}
 	//expectedResourceAtRestEncryptions := []bool{true, true, false}
 	//expectedResourceTransportEncryptions := []bool{true, false, false}
-	for i, r := range resources {
-		log.Println("Testing name for resource (bucket)", i+1)
-		assert.Equal(t, expectedResourceNames[i], r.GetName())
-		log.Println("Testing type of resource", i+1)
-		assert.True(t, r.HasType("ObjectStorage"))
-	}
+	// Check first element: voc.ObjectStorage
+	log.Println("Testing name for resource (bucket)", 1)
+	assert.Equal(t, expectedResourceNames[0], resources[0].GetName())
+	log.Println("Testing type of resource", 1)
+	assert.True(t, resources[0].HasType("ObjectStorage"))
+
+	// Check second element: voc.StorageService
+	log.Println("Testing name for resource (bucket)", 2)
+	assert.Equal(t, expectedResourceNames[0], resources[1].GetName())
+	log.Println("Testing type of resource", 2)
+	assert.True(t, resources[1].HasType("StorageService"))
 }
diff --git a/service/discovery/azure/arm_template_test.go b/service/discovery/azure/arm_template_test.go
index 4d6142c3..6c2a35ec 100644
--- a/service/discovery/azure/arm_template_test.go
+++ b/service/discovery/azure/arm_template_test.go
@@ -343,13 +343,17 @@ func TestObjectStorageProperties(t *testing.T) {
 	objectStorage, ok := list[2].(*voc.ObjectStorage)
 	assert.True(t, ok)
 
+	// Check ObjectStorage properties
 	assert.Equal(t, "container1", objectStorage.Name)
-	assert.Equal(t, "TLS1_1", objectStorage.HttpEndpoint.TransportEncryption.TlsVersion)
 	assert.Equal(t, "ObjectStorage", objectStorage.Type[0])
 	assert.Equal(t, "eastus", objectStorage.GeoLocation.Region)
-	assert.Equal(t, true, objectStorage.HttpEndpoint.TransportEncryption.Enabled)
-	assert.Equal(t, true, objectStorage.HttpEndpoint.TransportEncryption.Enforced)
-	assert.Equal(t, "TLS", objectStorage.HttpEndpoint.TransportEncryption.Algorithm)
+
+	//TODO(garuppel): Update when implemented
+	//Check StorageService properties
+	//assert.Equal(t, true, objectStorage.HttpEndpoint.TransportEncryption.Enforced)
+	//assert.Equal(t, "TLS", objectStorage.HttpEndpoint.TransportEncryption.Algorithm)
+	//assert.Equal(t, "TLS1_1", objectStorage.HttpEndpoint.TransportEncryption.TlsVersion)
+	//assert.Equal(t, true, objectStorage.HttpEndpoint.TransportEncryption.Enabled)
 
 	// Check ManagedKeyEncryption
 	atRestEncryption := *objectStorage.GetAtRestEncryption()
@@ -382,13 +386,17 @@ func TestFileStorageProperties(t *testing.T) {
 	fileStorage, ok := list[3].(*voc.FileStorage)
 	assert.True(t, ok)
 
+	// Check FileStorage properties
 	assert.Equal(t, "share1", fileStorage.Name)
-	assert.Equal(t, "TLS1_1", fileStorage.HttpEndpoint.TransportEncryption.TlsVersion)
 	assert.Equal(t, "FileStorage", fileStorage.Type[0])
 	assert.Equal(t, "eastus", fileStorage.GeoLocation.Region)
-	assert.Equal(t, true, fileStorage.HttpEndpoint.TransportEncryption.Enabled)
-	assert.Equal(t, true, fileStorage.HttpEndpoint.TransportEncryption.Enforced)
-	assert.Equal(t, "TLS", fileStorage.HttpEndpoint.TransportEncryption.Algorithm)
+
+	//TODO(garuppel): Update when implemented
+	//Check StorageService properties
+	//assert.Equal(t, true, fileStorage.HttpEndpoint.TransportEncryption.Enabled)
+	//assert.Equal(t, true, fileStorage.HttpEndpoint.TransportEncryption.Enforced)
+	//assert.Equal(t, "TLS", fileStorage.HttpEndpoint.TransportEncryption.Algorithm)
+	//assert.Equal(t, "TLS1_1", fileStorage.HttpEndpoint.TransportEncryption.TlsVersion)
 
 	// Check ManagedKeyEncryption
 	atRestEncryption := *fileStorage.GetAtRestEncryption()
@@ -414,9 +422,9 @@ func TestVmProperties(t *testing.T) {
 	assert.Equal(t, "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/virtualMachines/vm1-2", (string)(resourceVM.GetID()))
 	assert.Equal(t, "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/disks/blockStorage3", (string)(resourceVM.BlockStorage[0]))
 	assert.Equal(t, "eastus", resourceVM.GeoLocation.Region)
-	assert.True(t, resourceVM.BootLog.Enabled)
-	assert.Equal(t, voc.ResourceID("https://storage1.blob.core.windows.net/"), resourceVM.BootLog.Output[0])
-	assert.False(t, resourceVM.OSLog.Enabled)
+	assert.True(t, resourceVM.BootLogging.Enabled)
+	assert.Equal(t, []voc.ResourceID{voc.ResourceID("https://storage1.blob.core.windows.net/")}, resourceVM.BootLogging.LoggingService)
+	assert.False(t, resourceVM.OSLogging.Enabled)
 }
 
 func TestLoadBalancerProperties(t *testing.T) {
diff --git a/service/discovery/azure/compute_test.go b/service/discovery/azure/compute_test.go
index 05114854..372d7c75 100644
--- a/service/discovery/azure/compute_test.go
+++ b/service/discovery/azure/compute_test.go
@@ -224,13 +224,13 @@ func TestVirtualMachine(t *testing.T) {
 	assert.Equal(t, "data_disk_1", string(virtualMachine.BlockStorage[1]))
 	assert.Equal(t, "123", string(virtualMachine.NetworkInterface[0]))
 	assert.Equal(t, "eastus", virtualMachine.GeoLocation.Region)
-	assert.Equal(t, true, virtualMachine.BootLog.Enabled)
-	assert.Equal(t, voc.ResourceID("https://logstoragevm1.blob.core.windows.net/"), virtualMachine.BootLog.Output[0])
-	assert.Equal(t, time.Duration(0), virtualMachine.BootLog.RetentionPeriod)
+	assert.Equal(t, true, virtualMachine.BootLogging.Enabled)
+	assert.Equal(t, voc.ResourceID("https://logstoragevm1.blob.core.windows.net/"), virtualMachine.BootLogging.LoggingService[0])
+	assert.Equal(t, time.Duration(0), virtualMachine.BootLogging.RetentionPeriod)
 
 	virtualMachine2, ok := list[1].(*voc.VirtualMachine)
 	assert.True(t, ok)
-	assert.Equal(t, voc.ResourceID(""), virtualMachine2.BootLog.Output[0])
+	assert.Equal(t, voc.ResourceID(""), virtualMachine2.BootLogging.LoggingService[0])
 }
 
 func TestFunction(t *testing.T) {
diff --git a/service/discovery/azure/storage_test.go b/service/discovery/azure/storage_test.go
index 6f8c1870..5031a3dc 100644
--- a/service/discovery/azure/storage_test.go
+++ b/service/discovery/azure/storage_test.go
@@ -279,7 +279,7 @@ func TestStorage(t *testing.T) {
 
 	assert.NoError(t, err)
 	assert.NotNil(t, list)
-	assert.Equal(t, 8, len(list))
+	assert.Equal(t, 10, len(list))
 	assert.NotEmpty(t, d.Name())
 }
 
@@ -314,30 +314,35 @@ func TestObjectStorage(t *testing.T) {
 
 	objectStorage, ok := list[0].(*voc.ObjectStorage)
 
+	// Check ObjectStorage properties
 	assert.True(t, ok)
 	assert.Equal(t, "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Storage/storageAccounts/account1/blobServices/default/containers/container1", string(objectStorage.ID))
 	assert.Equal(t, "container1", objectStorage.Name)
 	assert.NotNil(t, objectStorage.CreationTime)
 	assert.Equal(t, "ObjectStorage", objectStorage.Type[0])
 	assert.Equal(t, "eastus", objectStorage.GeoLocation.Region)
-	assert.Equal(t, true, objectStorage.AtRestEncryption.GetAtRestEncryption().Enabled)
-	assert.Equal(t, "https://account1.blob.core.windows.net/container1", objectStorage.HttpEndpoint.Url)
-	assert.Equal(t, true, objectStorage.HttpEndpoint.TransportEncryption.Enabled)
-	assert.Equal(t, true, objectStorage.HttpEndpoint.TransportEncryption.Enforced)
-	assert.Equal(t, "TLS1_2", objectStorage.HttpEndpoint.TransportEncryption.TlsVersion)
-	assert.Equal(t, "TLS", objectStorage.HttpEndpoint.TransportEncryption.Algorithm)
+	assert.Equal(t, true, objectStorage.Storage.AtRestEncryption.GetAtRestEncryption().Enabled)
+
+	// Check StorageService properties
+	storageService, ok := list[4].(*voc.StorageService)
+	assert.True(t, ok)
+	assert.Equal(t, "https://account1.[file,blob].core.windows.net/", storageService.HttpEndpoint.Url)
+	assert.Equal(t, true, storageService.HttpEndpoint.TransportEncryption.Enabled)
+	assert.Equal(t, true, storageService.HttpEndpoint.TransportEncryption.Enforced)
+	assert.Equal(t, "TLS1_2", storageService.HttpEndpoint.TransportEncryption.TlsVersion)
+	assert.Equal(t, "TLS", storageService.HttpEndpoint.TransportEncryption.Algorithm)
 
 	// Check ManagedKeyEncryption
-	atRestEncryption := *objectStorage.GetAtRestEncryption()
+	atRestEncryption := *objectStorage.Storage.GetAtRestEncryption()
 	managedKeyEncryption, ok := atRestEncryption.(voc.ManagedKeyEncryption)
 	assert.True(t, ok)
 	assert.Equal(t, true, managedKeyEncryption.Enabled)
 	assert.Equal(t, "AES256", managedKeyEncryption.Algorithm)
 
 	// Check CustomerKeyEncryption
-	objectStorage, ok = list[4].(*voc.ObjectStorage)
+	objectStorage, ok = list[5].(*voc.ObjectStorage)
 	assert.True(t, ok)
-	atRestEncryption = *objectStorage.GetAtRestEncryption()
+	atRestEncryption = *objectStorage.Storage.GetAtRestEncryption()
 	customerKeyEncryption, ok := atRestEncryption.(voc.CustomerKeyEncryption)
 	assert.True(t, ok)
 	assert.Equal(t, true, customerKeyEncryption.Enabled)
@@ -381,12 +386,15 @@ func TestFileStorage(t *testing.T) {
 	assert.NotNil(t, fileStorage.CreationTime)
 	assert.Equal(t, "FileStorage", fileStorage.Type[0])
 	assert.Equal(t, "eastus", fileStorage.GeoLocation.Region)
-	assert.Equal(t, true, fileStorage.AtRestEncryption.GetAtRestEncryption().Enabled)
-	assert.Equal(t, "https://account1.file.core.windows.net/fileshare1", fileStorage.HttpEndpoint.Url)
-	assert.Equal(t, true, fileStorage.HttpEndpoint.TransportEncryption.Enabled)
-	assert.Equal(t, true, fileStorage.HttpEndpoint.TransportEncryption.Enforced)
-	assert.Equal(t, "TLS1_2", fileStorage.HttpEndpoint.TransportEncryption.TlsVersion)
-	assert.Equal(t, "TLS", fileStorage.HttpEndpoint.TransportEncryption.Algorithm)
+	assert.Equal(t, true, fileStorage.Storage.AtRestEncryption.GetAtRestEncryption().Enabled)
+
+	storageService, ok := list[4].(*voc.StorageService)
+	assert.True(t, ok)
+	assert.Equal(t, "https://account1.[file,blob].core.windows.net/", storageService.HttpEndpoint.Url)
+	assert.Equal(t, true, storageService.HttpEndpoint.TransportEncryption.Enabled)
+	assert.Equal(t, true, storageService.HttpEndpoint.TransportEncryption.Enforced)
+	assert.Equal(t, "TLS1_2", storageService.HttpEndpoint.TransportEncryption.TlsVersion)
+	assert.Equal(t, "TLS", storageService.HttpEndpoint.TransportEncryption.Algorithm)
 }
 
 func TestListBlockStorage(t *testing.T) {
@@ -418,7 +426,7 @@ func TestBlockStorage(t *testing.T) {
 	assert.NoError(t, err)
 	assert.NotNil(t, list)
 
-	blockStorage, ok := list[6].(*voc.BlockStorage)
+	blockStorage, ok := list[8].(*voc.BlockStorage)
 
 	assert.True(t, ok)
 	assert.Equal(t, "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/res1/providers/Microsoft.Compute/disks/disk1", string(blockStorage.ID))
@@ -467,7 +475,7 @@ func TestStorageHandleMethodsWhenInputIsInvalid(t *testing.T) {
 	// Clear KeySource
 	disk.Encryption.Type = ""
 
-	handleBlockStorageResponse, err := d.handleBlockStorage(disk)
+	handleBlockStorageResponse, err := d.handleBlockStorage(&disk)
 	assert.Error(t, err)
 	assert.Nil(t, handleBlockStorageResponse)
 }
@@ -491,8 +499,6 @@ func TestStorageMethodsWhenInputIsInvalid(t *testing.T) {
 	managedKeyEncryption := voc.ManagedKeyEncryption{AtRestEncryption: &voc.AtRestEncryption{Algorithm: "AES256", Enabled: true}}
 	assert.Equal(t, managedKeyEncryption, atRestEncryption)
 
-	// Test method blockStorageAtRestEncryption
-	// Todo(garuppel): How to test? Problem: Azure call again
 }
 
 func TestStorageDiscoverMethodsWhenInputIsInvalid(t *testing.T) {
diff --git a/service/discovery/discovery_test.go b/service/discovery/discovery_test.go
index 1f0ba494..6fb9f85c 100644
--- a/service/discovery/discovery_test.go
+++ b/service/discovery/discovery_test.go
@@ -168,11 +168,11 @@ func TestStartDiscovery(t *testing.T) {
 				assert.NotEmpty(t, e.Resource)
 				// Check if ID of mockDiscovery's resource is mapped to resource id of the evidence
 				list, _ := tt.fields.discoverer.List()
-				assert.Equal(t, string(list[0].GetID()), e.Resource.GetStructValue().AsMap()["id"].(string))
+				// Only the last element sent can be checked
+				assert.Equal(t, string(list[len(list)-1].GetID()), e.Resource.GetStructValue().AsMap()["id"].(string))
 			}
 		})
 	}
-
 }
 
 func TestQuery(t *testing.T) {
@@ -208,7 +208,7 @@ func TestQuery(t *testing.T) {
 		{
 			name:                     "No filtering",
 			fields:                   fields{queryRequest: &discovery.QueryRequest{}},
-			numberOfQueriedResources: 1,
+			numberOfQueriedResources: 2,
 		},
 	}
 
@@ -551,12 +551,24 @@ func (m mockDiscoverer) List() ([]voc.IsCloudResource, error) {
 		return []voc.IsCloudResource{
 			&voc.ObjectStorage{
 				Storage: &voc.Storage{
-					CloudResource: &voc.CloudResource{
+					Resource: &voc.Resource{
 						ID:   "some-id",
 						Name: "some-name",
 						Type: []string{"ObjectStorage", "Storage", "Resource"},
 					},
 				},
+			},
+			&voc.StorageService{
+				Storages: []voc.ResourceID{("some-id")},
+				NetworkService: &voc.NetworkService{
+					Networking: &voc.Networking{
+						Resource: &voc.Resource{
+							ID:   "some-storage-account-id",
+							Name: "some-storage-account-name",
+							Type: []string{"StorageService", "NetworkService", "Networking", "Resource"},
+						},
+					},
+				},
 				HttpEndpoint: &voc.HttpEndpoint{
 					TransportEncryption: &voc.TransportEncryption{
 						Enforced:   false,
diff --git a/service/evidence/evidence_store_test.go b/service/evidence/evidence_store_test.go
index 3d89eea0..76a1ae50 100644
--- a/service/evidence/evidence_store_test.go
+++ b/service/evidence/evidence_store_test.go
@@ -94,7 +94,7 @@ func TestStoreEvidence(t *testing.T) {
 						Timestamp: timestamppb.Now(),
 						Raw:       "",
 						Resource: toStruct(voc.VirtualMachine{
-							Compute: &voc.Compute{CloudResource: &voc.CloudResource{
+							Compute: &voc.Compute{Resource: &voc.Resource{
 								ID: "mock-id",
 							}},
 						}, t),
@@ -115,7 +115,7 @@ func TestStoreEvidence(t *testing.T) {
 						Raw:       "",
 						Resource: toStruct(voc.VirtualMachine{
 							Compute: &voc.Compute{
-								CloudResource: &voc.CloudResource{
+								Resource: &voc.Resource{
 									ID: "mock-id-1",
 								},
 							},
@@ -205,7 +205,7 @@ func TestStoreEvidences(t *testing.T) {
 							Raw:       "",
 							Resource: toStructWithoutTest(voc.VirtualMachine{
 								Compute: &voc.Compute{
-									CloudResource: &voc.CloudResource{
+									Resource: &voc.Resource{
 										ID: "mock-id-1",
 									},
 								},
@@ -347,7 +347,7 @@ func TestEvidenceHook(t *testing.T) {
 					ToolId:    "mockToolId-1",
 					Resource: toStruct(voc.VirtualMachine{
 						Compute: &voc.Compute{
-							CloudResource: &voc.CloudResource{
+							Resource: &voc.Resource{
 								ID: "mock-id-1",
 							},
 						},
@@ -399,7 +399,7 @@ func createStoreEvidenceRequestMocks(count int) []*evidence.StoreEvidenceRequest
 				Raw:       "",
 				Resource: toStructWithoutTest(voc.VirtualMachine{
 					Compute: &voc.Compute{
-						CloudResource: &voc.CloudResource{
+						Resource: &voc.Resource{
 							ID: "mock-id-1",
 						},
 					},