From 41f1ac0d0e6821562cf9af03af29a6cdc8fa2109 Mon Sep 17 00:00:00 2001 From: Alexei Kravtsov Date: Thu, 27 Jul 2023 19:08:26 +0300 Subject: [PATCH 01/11] rebase api gen --- api/models/models.gen.go | 22 +-- api/openapi.yaml | 6 + api/server/server.gen.go | 143 +++++++++--------- pkg/backend/database/demo.go | 31 ++-- pkg/backend/database/gorm/odata.go | 16 +- runtime_scan/pkg/provider/aws/client.go | 90 +++++++++-- runtime_scan/pkg/provider/aws/helpers.go | 38 +++-- runtime_scan/pkg/provider/aws/instance.go | 26 ++-- .../detail-displays/AssetDetails/index.js | 6 +- 9 files changed, 235 insertions(+), 143 deletions(-) diff --git a/api/models/models.gen.go b/api/models/models.gen.go index c7c3d4fc2..d36fa22bf 100644 --- a/api/models/models.gen.go +++ b/api/models/models.gen.go @@ -875,16 +875,18 @@ type Tag struct { // VMInfo defines model for VMInfo. type VMInfo struct { - Image string `json:"image"` - InstanceID string `json:"instanceID"` - InstanceProvider *CloudProvider `json:"instanceProvider,omitempty"` - InstanceType string `json:"instanceType"` - LaunchTime time.Time `json:"launchTime"` - Location string `json:"location"` - ObjectType string `json:"objectType"` - Platform string `json:"platform"` - SecurityGroups *[]SecurityGroup `json:"securityGroups"` - Tags *[]Tag `json:"tags"` + Image string `json:"image"` + InstanceID string `json:"instanceID"` + InstanceProvider *CloudProvider `json:"instanceProvider,omitempty"` + InstanceType string `json:"instanceType"` + LaunchTime time.Time `json:"launchTime"` + Location string `json:"location"` + ObjectType string `json:"objectType"` + Platform string `json:"platform"` + RootVolumeEncrypted bool `json:"rootVolumeEncrypted"` + RootVolumeSizeGB int `json:"rootVolumeSizeGB"` + SecurityGroups *[]SecurityGroup `json:"securityGroups"` + Tags *[]Tag `json:"tags"` } // VulnerabilitiesConfig defines model for VulnerabilitiesConfig. diff --git a/api/openapi.yaml b/api/openapi.yaml index 1de15edd5..78fca3ab6 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -1551,6 +1551,10 @@ components: launchTime: type: string format: date-time + rootVolumeSizeGB: + type: integer + rootVolumeEncrypted: + type: boolean required: - objectType - instanceID @@ -1559,6 +1563,8 @@ components: - image - platform - launchTime + - rootVolumeSizeGB + - rootVolumeEncrypted PodInfo: type: object diff --git a/api/server/server.gen.go b/api/server/server.gen.go index c57d1aa53..e2faeb512 100644 --- a/api/server/server.gen.go +++ b/api/server/server.gen.go @@ -1067,7 +1067,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+x9W3PbOLLwX0Hx26rZ3ZLtZL45D8dvjuxkVONbWc7kbG2mzkJkS8KEBDgAaFuTyn8/", + "H4sIAAAAAAAC/+x9W3PbOLLwX0Hx26rZ3ZLtZL45D8dvjuxkVONbWU7mbG2mzkJkS8KEBDgAaFuTyn8/", "BYCgwAt4kS3JzvjNFoHGpe+NbuBrELIkZRSoFMHx1yDFHCcggev/sBAgJ6fqT0KD4yDFchmMAooTCI6L", "r6OAwx8Z4RAFx5JnMApEuIQEq25ylaqmQnJCF8G3byPTaxpi2g43bzEM9pzQiNCFF/L6+zC4ZJ5gGS4L", "qEvAEfA13Mn84EI3aABDqIQFcA2HRVjiMcuoLED9kQFfrSH9LdRfG+DMGIsB0zWcs4cU08gLCMzn9oVp", @@ -1082,85 +1082,86 @@ var swaggerSpec = []string{ "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", + "b9/+LwAA//+wNhfM78IAAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/pkg/backend/database/demo.go b/pkg/backend/database/demo.go index cec2a7467..3805f6d2d 100644 --- a/pkg/backend/database/demo.go +++ b/pkg/backend/database/demo.go @@ -32,14 +32,9 @@ const ( awsRegionEUCentral1 = "eu-central-1" awsRegionUSEast1 = "us-east-1" awsVPCEUCentral11 = "vpc-1-from-eu-central-1" - awsVPCEUCentral12 = "vpc-2-from-eu-central-1" awsVPCUSEast11 = "vpc-1-from-us-east-1" - awsVPCUSEast12 = "vpc-2-from-us-east-1" awsSGUSEast111 = "sg-1-from-vpc-1-from-us-east-1" - awsSGUSEast121 = "sg-1-from-vpc-2-from-us-east-1" - awsSGUSEast122 = "sg-2-from-vpc-2-from-us-east-1" awsSGEUCentral111 = "sg-1-from-vpc-1-from-eu-central-1" - awsSGEUCentral121 = "sg-1-from-vpc-2-from-eu-central-1" awsInstanceEUCentral11 = "i-instance-1-from-eu-central-1" awsInstanceEUCentral12 = "i-instance-2-from-eu-central-1" awsInstanceUSEast11 = "i-instance-1-from-us-east-1" @@ -361,18 +356,20 @@ func createVulnerabilityFindings(ctx context.Context, base models.Finding, vulne } func createVMInfo(instanceID, location, image, instanceType, platform string, - tags []models.Tag, launchTime time.Time, instanceProvider models.CloudProvider, + tags []models.Tag, launchTime time.Time, instanceProvider models.CloudProvider, rootVolumeSizeGB int, rootVolumeEncrypted bool, ) *models.AssetType { info := models.AssetType{} err := info.FromVMInfo(models.VMInfo{ - Image: image, - InstanceID: instanceID, - InstanceProvider: &instanceProvider, - InstanceType: instanceType, - LaunchTime: launchTime, - Location: location, - Platform: platform, - Tags: &tags, + Image: image, + InstanceID: instanceID, + InstanceProvider: &instanceProvider, + InstanceType: instanceType, + LaunchTime: launchTime, + Location: location, + Platform: platform, + Tags: &tags, + RootVolumeSizeGB: rootVolumeSizeGB, + RootVolumeEncrypted: rootVolumeEncrypted, }) if err != nil { panic(err) @@ -403,7 +400,7 @@ func createAssets() []models.Asset { }, }, AssetInfo: createVMInfo(awsInstanceEUCentral11, awsRegionEUCentral1+"/"+awsVPCEUCentral11+"/"+awsSGEUCentral111, - "ami-111", "t2.large", "Linux", []models.Tag{{Key: "Name", Value: "asset1"}}, time.Now(), models.AWS), + "ami-111", "t2.large", "Linux", []models.Tag{{Key: "Name", Value: "asset1"}}, time.Now(), models.AWS, 8, false), }, { ScansCount: utils.PointerTo(1), @@ -425,7 +422,7 @@ func createAssets() []models.Asset { }, }, AssetInfo: createVMInfo(awsInstanceEUCentral12, awsRegionEUCentral1+"/"+awsVPCEUCentral11+"/"+awsSGEUCentral111, - "ami-111", "t2.large", "Linux", []models.Tag{{Key: "Name", Value: "asset2"}}, time.Now(), models.AWS), + "ami-111", "t2.large", "Linux", []models.Tag{{Key: "Name", Value: "asset2"}}, time.Now(), models.AWS, 25, true), }, { ScansCount: utils.PointerTo(1), @@ -446,7 +443,7 @@ func createAssets() []models.Asset { }, }, AssetInfo: createVMInfo(awsInstanceUSEast11, awsRegionUSEast1+"/"+awsVPCUSEast11+"/"+awsSGUSEast111, - "ami-112", "t2.micro", "Linux", []models.Tag{{Key: "Name", Value: "asset3"}}, time.Now(), models.AWS), + "ami-112", "t2.micro", "Linux", []models.Tag{{Key: "Name", Value: "asset3"}}, time.Now(), models.AWS, 512, false), }, } } diff --git a/pkg/backend/database/gorm/odata.go b/pkg/backend/database/gorm/odata.go index f9d26bd7d..3a812fb7f 100644 --- a/pkg/backend/database/gorm/odata.go +++ b/pkg/backend/database/gorm/odata.go @@ -388,13 +388,15 @@ var schemaMetas = map[string]odatasql.SchemaMeta{ }, "VMInfo": { Fields: odatasql.Schema{ - "objectType": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "instanceID": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "location": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "launchTime": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "platform": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "instanceType": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "image": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "objectType": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "instanceID": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "location": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "launchTime": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "platform": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "instanceType": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "image": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "rootVolumeSizeGB": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "rootVolumeEncrypted": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, "tags": odatasql.FieldMeta{ FieldType: odatasql.CollectionFieldType, CollectionItemMeta: &odatasql.FieldMeta{ diff --git a/runtime_scan/pkg/provider/aws/client.go b/runtime_scan/pkg/provider/aws/client.go index dbdd27f4f..d55577cc2 100644 --- a/runtime_scan/pkg/provider/aws/client.go +++ b/runtime_scan/pkg/provider/aws/client.go @@ -89,9 +89,10 @@ func (c *Client) DiscoverAssets(ctx context.Context) ([]models.AssetType, error) for _, instance := range instances { asset, err := getVMInfoFromInstance(instance) if err != nil { - return nil, FatalError{ - Err: fmt.Errorf("failed convert EC2 Instance to AssetType: %w", err), - } + //return nil, FatalError{ + // Err: fmt.Errorf("failed convert EC2 Instance to AssetType: %w", err), + //} + continue } assets = append(assets, asset) } @@ -775,20 +776,33 @@ func (c *Client) getInstancesFromDescribeInstancesOutput(ctx context.Context, re } if err := validateInstanceFields(instance); err != nil { - logger.Errorf("Instance validation failed. instance id=%v: %v", getPointerValOrEmpty(instance.InstanceId), err) + logger.Errorf("Instance validation failed. instance id=%v: %v", getStringPointerValOrEmpty(instance.InstanceId), err) continue } + rootVol, err := getRootVolumeInfo(ctx, c.ec2Client, instance, regionID) + if err != nil { + logger.Warnf("Couldn't get root volume info. instance id=%v: %v", getStringPointerValOrEmpty(instance.InstanceId), err) + rootVol = &rootVolumeInfo{ + DeviceName: getStringPointerValOrEmpty(instance.RootDeviceName), + SizeGB: 0, + Encrypted: false, + } + } + ret = append(ret, Instance{ - ID: *instance.InstanceId, - Region: regionID, - AvailabilityZone: *instance.Placement.AvailabilityZone, - Image: *instance.ImageId, - InstanceType: string(instance.InstanceType), - Platform: *instance.PlatformDetails, - Tags: getTagsFromECTags(instance.Tags), - LaunchTime: *instance.LaunchTime, - VpcID: *instance.VpcId, - SecurityGroups: getSecurityGroupsIDs(instance.SecurityGroups), + ID: *instance.InstanceId, + Region: regionID, + AvailabilityZone: *instance.Placement.AvailabilityZone, + Image: *instance.ImageId, + InstanceType: string(instance.InstanceType), + Platform: *instance.PlatformDetails, + Tags: getTagsFromECTags(instance.Tags), + LaunchTime: *instance.LaunchTime, + VpcID: *instance.VpcId, + SecurityGroups: getSecurityGroupsIDs(instance.SecurityGroups), + RootDeviceName: rootVol.DeviceName, + RootVolumeSizeGB: rootVol.SizeGB, + RootVolumeEncrypted: rootVol.Encrypted, ec2Client: c.ec2Client, }) @@ -797,6 +811,54 @@ func (c *Client) getInstancesFromDescribeInstancesOutput(ctx context.Context, re return ret } +type rootVolumeInfo struct { + DeviceName string + SizeGB int32 + Encrypted bool +} + +func getRootVolumeInfo(ctx context.Context, client *ec2.Client, i ec2types.Instance, region string) (*rootVolumeInfo, error) { + logger := log.GetLoggerFromContextOrDiscard(ctx) + for _, mapping := range i.BlockDeviceMappings { + if getStringPointerValOrEmpty(mapping.DeviceName) == getStringPointerValOrEmpty(i.RootDeviceName) { + if mapping.Ebs == nil { + return nil, fmt.Errorf("EBS of the root volume is nil") + } + if mapping.Ebs.VolumeId == nil { + return nil, fmt.Errorf("volume ID of the root volume is nil") + } + descParams := &ec2.DescribeVolumesInput{ + VolumeIds: []string{*mapping.Ebs.VolumeId}, + } + + describeOut, err := client.DescribeVolumes(ctx, descParams, func(options *ec2.Options) { + options.Region = region + }) + if err != nil { + return nil, fmt.Errorf("failed to describe the root volume") + } + + if len(describeOut.Volumes) == 0 { + return nil, fmt.Errorf("volume list is empty") + } + if len(describeOut.Volumes) > 1 { + logger.WithFields(logrus.Fields{ + "VolumeId": *mapping.Ebs.VolumeId, + "Volumes num": len(describeOut.Volumes), + }).Warnf("Found more than 1 root volume, using the first") + } + + return &rootVolumeInfo{ + DeviceName: getStringPointerValOrEmpty(mapping.DeviceName), + SizeGB: getInt32PointerValOrEmpty(describeOut.Volumes[0].Size), + Encrypted: getBoolPointerValOrFalse(describeOut.Volumes[0].Encrypted), + }, nil + } + } + + return nil, fmt.Errorf("instance doesn't have a root volume block device mapping") +} + func (c *Client) ListAllRegions(ctx context.Context) ([]Region, error) { ret := make([]Region, 0) out, err := c.ec2Client.DescribeRegions(ctx, &ec2.DescribeRegionsInput{ diff --git a/runtime_scan/pkg/provider/aws/helpers.go b/runtime_scan/pkg/provider/aws/helpers.go index 49b966688..647a1e27a 100644 --- a/runtime_scan/pkg/provider/aws/helpers.go +++ b/runtime_scan/pkg/provider/aws/helpers.go @@ -168,13 +168,27 @@ func getInstanceState(result *ec2.DescribeInstancesOutput, instanceID string) ec return ec2types.InstanceStateNamePending } -func getPointerValOrEmpty(val *string) string { +func getStringPointerValOrEmpty(val *string) string { if val == nil { return "" } return *val } +func getInt32PointerValOrEmpty(val *int32) int32 { + if val == nil { + return 0 + } + return *val +} + +func getBoolPointerValOrFalse(val *bool) bool { + if val == nil { + return false + } + return *val +} + func validateInstanceFields(instance ec2types.Instance) error { if instance.InstanceId == nil { return fmt.Errorf("instance id does not exist") @@ -231,16 +245,18 @@ func getSecurityGroupsFromEC2GroupIdentifiers(identifiers []ec2types.GroupIdenti func getVMInfoFromInstance(i Instance) (models.AssetType, error) { assetType := models.AssetType{} err := assetType.FromVMInfo(models.VMInfo{ - Image: i.Image, - InstanceID: i.ID, - InstanceProvider: utils.PointerTo(models.AWS), - InstanceType: i.InstanceType, - LaunchTime: i.LaunchTime, - Location: i.Location(), - ObjectType: "VMInfo", - Platform: i.Platform, - SecurityGroups: utils.PointerTo(i.SecurityGroups), - Tags: utils.PointerTo(i.Tags), + Image: i.Image, + InstanceID: i.ID, + InstanceProvider: utils.PointerTo(models.AWS), + InstanceType: i.InstanceType, + LaunchTime: i.LaunchTime, + Location: i.Location(), + ObjectType: "VMInfo", + Platform: i.Platform, + RootVolumeEncrypted: i.RootVolumeEncrypted, + RootVolumeSizeGB: int(i.RootVolumeSizeGB), + SecurityGroups: utils.PointerTo(i.SecurityGroups), + Tags: utils.PointerTo(i.Tags), }) if err != nil { err = fmt.Errorf("failed to create AssetType from VMInfo: %w", err) diff --git a/runtime_scan/pkg/provider/aws/instance.go b/runtime_scan/pkg/provider/aws/instance.go index 9e60da85d..5c29043be 100644 --- a/runtime_scan/pkg/provider/aws/instance.go +++ b/runtime_scan/pkg/provider/aws/instance.go @@ -31,18 +31,20 @@ import ( ) type Instance struct { - ID string - Region string - VpcID string - SecurityGroups []models.SecurityGroup - AvailabilityZone string - Image string - InstanceType string - Platform string - Tags []models.Tag - LaunchTime time.Time - RootDeviceName string - Volumes []Volume + ID string + Region string + VpcID string + SecurityGroups []models.SecurityGroup + AvailabilityZone string + Image string + InstanceType string + Platform string + Tags []models.Tag + LaunchTime time.Time + RootDeviceName string + RootVolumeSizeGB int32 + RootVolumeEncrypted bool + Volumes []Volume Metadata provider.ScanMetadata diff --git a/ui/src/layout/detail-displays/AssetDetails/index.js b/ui/src/layout/detail-displays/AssetDetails/index.js index 203494254..af239325e 100644 --- a/ui/src/layout/detail-displays/AssetDetails/index.js +++ b/ui/src/layout/detail-displays/AssetDetails/index.js @@ -52,7 +52,7 @@ const AssetDetails = ({assetData, withAssetLink=false, withAssetScansLink=false} const navigate = useNavigate(); const {id, assetInfo, firstSeen, lastSeen, terminatedOn} = assetData; - const {instanceID, objectType, location, tags, image, instanceType, platform, launchTime} = assetInfo || {}; + const {instanceID, objectType, location, tags, image, instanceType, platform, launchTime, rootVolumeSizeGB, rootVolumeEncrypted} = assetInfo || {}; return ( {platform} {formatDate(launchTime)} + + {rootVolumeSizeGB} GB + {rootVolumeEncrypted ? "Yes" : "No"} + )} rightPlaneDisplay={!withAssetScansLink ? null : () => } From d9e7da3621abe4a0117d4e64c54e83152c9653e9 Mon Sep 17 00:00:00 2001 From: Alexei Kravtsov Date: Tue, 11 Jul 2023 18:45:15 +0300 Subject: [PATCH 02/11] azure after test --- runtime_scan/pkg/provider/azure/client.go | 67 ++++++++++++++----- .../pkg/provider/azure/client_test.go | 55 +++++++++++++++ 2 files changed, 107 insertions(+), 15 deletions(-) create mode 100644 runtime_scan/pkg/provider/azure/client_test.go diff --git a/runtime_scan/pkg/provider/azure/client.go b/runtime_scan/pkg/provider/azure/client.go index 9afcd4f1a..f94ee1fbb 100644 --- a/runtime_scan/pkg/provider/azure/client.go +++ b/runtime_scan/pkg/provider/azure/client.go @@ -21,13 +21,14 @@ import ( "strings" "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v3" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources" - "github.com/openclarity/vmclarity/api/models" "github.com/openclarity/vmclarity/runtime_scan/pkg/provider" + "github.com/openclarity/vmclarity/shared/pkg/log" "github.com/openclarity/vmclarity/shared/pkg/utils" ) @@ -188,7 +189,7 @@ func (c *Client) DiscoverAssets(ctx context.Context) ([]models.AssetType, error) if err != nil { return nil, fmt.Errorf("failed to get next page: %w", err) } - ts, err := processVirtualMachineListIntoAssetTypes(page.VirtualMachineListResult) + ts, err := c.processVirtualMachineListIntoAssetTypes(ctx, page.VirtualMachineListResult) if err != nil { return nil, err } @@ -210,10 +211,10 @@ func resourceGroupAndNameFromInstanceID(instanceID string) (string, string, erro return idParts[resourceGroupPartIdx], idParts[vmNamePartIdx], nil } -func processVirtualMachineListIntoAssetTypes(vmList armcompute.VirtualMachineListResult) ([]models.AssetType, error) { +func (c *Client) processVirtualMachineListIntoAssetTypes(ctx context.Context, vmList armcompute.VirtualMachineListResult) ([]models.AssetType, error) { ret := make([]models.AssetType, 0, len(vmList.Value)) for _, vm := range vmList.Value { - info, err := getVMInfoFromVirtualMachine(vm) + info, err := getVMInfoFromVirtualMachine(vm, c.getRootVolumeInfo(ctx, vm)) if err != nil { return nil, fmt.Errorf("unable to convert instance to vminfo: %w", err) } @@ -222,19 +223,48 @@ func processVirtualMachineListIntoAssetTypes(vmList armcompute.VirtualMachineLis return ret, nil } -func getVMInfoFromVirtualMachine(vm *armcompute.VirtualMachine) (models.AssetType, error) { +type rootVolumeInfo struct { + SizeGB int32 + Encrypted bool +} + +func (c *Client) getRootVolumeInfo(ctx context.Context, vm *armcompute.VirtualMachine) *rootVolumeInfo { + logger := log.GetLoggerFromContextOrDiscard(ctx) + ret := &rootVolumeInfo{ + SizeGB: *vm.Properties.StorageProfile.OSDisk.DiskSizeGB, + Encrypted: false, + } + osDiskID, err := arm.ParseResourceID(*vm.Properties.StorageProfile.OSDisk.ManagedDisk.ID) + if err != nil { + logger.Warnf("Failed to parse disk ID. DiskID=%v: %v", *vm.Properties.StorageProfile.OSDisk.ManagedDisk.ID, err) + return ret + } + osDisk, err := c.disksClient.Get(context.TODO(), osDiskID.ResourceGroupName, osDiskID.Name, nil) + if err != nil { + logger.Warnf("Failed to get OS disk. DiskID=%v: %v", *vm.Properties.StorageProfile.OSDisk.ManagedDisk.ID, err) + return ret + } + ret.Encrypted = isEncrypted(osDisk) + ret.SizeGB = *osDisk.Disk.Properties.DiskSizeGB + + return ret +} + +func getVMInfoFromVirtualMachine(vm *armcompute.VirtualMachine, rootVol *rootVolumeInfo) (models.AssetType, error) { assetType := models.AssetType{} err := assetType.FromVMInfo(models.VMInfo{ - ObjectType: "VMInfo", - InstanceProvider: utils.PointerTo(models.Azure), - InstanceID: *vm.ID, - Image: createImageURN(vm.Properties.StorageProfile.ImageReference), - InstanceType: *vm.Type, - LaunchTime: *vm.Properties.TimeCreated, - Location: *vm.Location, - Platform: string(*vm.Properties.StorageProfile.OSDisk.OSType), - SecurityGroups: &[]models.SecurityGroup{}, - Tags: convertTags(vm.Tags), + ObjectType: "VMInfo", + InstanceProvider: utils.PointerTo(models.Azure), + InstanceID: *vm.ID, + Image: createImageURN(vm.Properties.StorageProfile.ImageReference), + InstanceType: *vm.Type, + LaunchTime: *vm.Properties.TimeCreated, + Location: *vm.Location, + Platform: string(*vm.Properties.StorageProfile.OSDisk.OSType), + RootVolumeEncrypted: rootVol.Encrypted, + RootVolumeSizeGB: int(rootVol.SizeGB), + SecurityGroups: &[]models.SecurityGroup{}, + Tags: convertTags(vm.Tags), }) if err != nil { err = fmt.Errorf("failed to create AssetType from VMInfo: %w", err) @@ -243,6 +273,13 @@ func getVMInfoFromVirtualMachine(vm *armcompute.VirtualMachine) (models.AssetTyp return assetType, err } +func isEncrypted(disk armcompute.DisksClientGetResponse) bool { + if disk.Properties.EncryptionSettingsCollection == nil { + return false + } + return *disk.Properties.EncryptionSettingsCollection.Enabled +} + func convertTags(tags map[string]*string) *[]models.Tag { ret := make([]models.Tag, 0, len(tags)) for key, val := range tags { diff --git a/runtime_scan/pkg/provider/azure/client_test.go b/runtime_scan/pkg/provider/azure/client_test.go new file mode 100644 index 000000000..081abd3d3 --- /dev/null +++ b/runtime_scan/pkg/provider/azure/client_test.go @@ -0,0 +1,55 @@ +package azure + +import ( + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4" + "github.com/openclarity/vmclarity/shared/pkg/utils" +) + +func Test_isEncrypted(t *testing.T) { + type args struct { + disk armcompute.DisksClientGetResponse + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "encrypted", + args: args{ + disk: armcompute.DisksClientGetResponse{ + Disk: armcompute.Disk{ + Properties: &armcompute.DiskProperties{ + EncryptionSettingsCollection: &armcompute.EncryptionSettingsCollection{ + Enabled: utils.PointerTo(true), + }, + }, + }, + }, + }, + want: true, + }, + { + name: "not encrypted", + args: args{ + disk: armcompute.DisksClientGetResponse{ + Disk: armcompute.Disk{ + Properties: &armcompute.DiskProperties{ + EncryptionSettingsCollection: nil, + }, + }, + }, + }, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := isEncrypted(tt.args.disk); got != tt.want { + t.Errorf("isEncrypted() = %v, want %v", got, tt.want) + } + }) + } +} From 1009f5dd8fcc1b4b6d76d0337b4043645cb4e59b Mon Sep 17 00:00:00 2001 From: Alexei Kravtsov Date: Tue, 11 Jul 2023 19:59:59 +0300 Subject: [PATCH 03/11] revert discovery error --- runtime_scan/pkg/provider/aws/client.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/runtime_scan/pkg/provider/aws/client.go b/runtime_scan/pkg/provider/aws/client.go index d55577cc2..556a6ab8d 100644 --- a/runtime_scan/pkg/provider/aws/client.go +++ b/runtime_scan/pkg/provider/aws/client.go @@ -89,10 +89,9 @@ func (c *Client) DiscoverAssets(ctx context.Context) ([]models.AssetType, error) for _, instance := range instances { asset, err := getVMInfoFromInstance(instance) if err != nil { - //return nil, FatalError{ - // Err: fmt.Errorf("failed convert EC2 Instance to AssetType: %w", err), - //} - continue + return nil, FatalError{ + Err: fmt.Errorf("failed convert EC2 Instance to AssetType: %w", err), + } } assets = append(assets, asset) } From b2c011ad3c3d211f9f362e98b28717754cd92d2c Mon Sep 17 00:00:00 2001 From: Alexei Kravtsov Date: Sun, 23 Jul 2023 19:17:22 +0300 Subject: [PATCH 04/11] review --- api/models/models.gen.go | 31 +- api/openapi.yaml | 22 +- api/server/server.gen.go | 286 ++++++++++++++++++ pkg/backend/database/demo.go | 22 +- pkg/backend/database/gorm/odata.go | 26 +- runtime_scan/pkg/provider/aws/client.go | 29 +- runtime_scan/pkg/provider/aws/helpers.go | 47 +-- runtime_scan/pkg/provider/azure/client.go | 41 +-- shared/pkg/utils/utils.go | 21 ++ .../detail-displays/AssetDetails/index.js | 7 +- 10 files changed, 425 insertions(+), 107 deletions(-) diff --git a/api/models/models.gen.go b/api/models/models.gen.go index d36fa22bf..849597aea 100644 --- a/api/models/models.gen.go +++ b/api/models/models.gen.go @@ -504,6 +504,12 @@ type PodInfo struct { // ResourceCleanupState defines model for ResourceCleanupState. type ResourceCleanupState string +// RootVolume Information about VM root volume +type RootVolume struct { + Encrypted bool `json:"encrypted"` + SizeGB int `json:"sizeGB"` +} + // Rootkit defines model for Rootkit. type Rootkit struct { Message *string `json:"message,omitempty"` @@ -875,18 +881,19 @@ type Tag struct { // VMInfo defines model for VMInfo. type VMInfo struct { - Image string `json:"image"` - InstanceID string `json:"instanceID"` - InstanceProvider *CloudProvider `json:"instanceProvider,omitempty"` - InstanceType string `json:"instanceType"` - LaunchTime time.Time `json:"launchTime"` - Location string `json:"location"` - ObjectType string `json:"objectType"` - Platform string `json:"platform"` - RootVolumeEncrypted bool `json:"rootVolumeEncrypted"` - RootVolumeSizeGB int `json:"rootVolumeSizeGB"` - SecurityGroups *[]SecurityGroup `json:"securityGroups"` - Tags *[]Tag `json:"tags"` + Image string `json:"image"` + InstanceID string `json:"instanceID"` + InstanceProvider *CloudProvider `json:"instanceProvider,omitempty"` + InstanceType string `json:"instanceType"` + LaunchTime time.Time `json:"launchTime"` + Location string `json:"location"` + ObjectType string `json:"objectType"` + Platform string `json:"platform"` + + // RootVolume Information about VM root volume + RootVolume RootVolume `json:"rootVolume"` + SecurityGroups *[]SecurityGroup `json:"securityGroups"` + Tags *[]Tag `json:"tags"` } // VulnerabilitiesConfig defines model for VulnerabilitiesConfig. diff --git a/api/openapi.yaml b/api/openapi.yaml index 78fca3ab6..281b3360b 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -1380,6 +1380,19 @@ components: - value additionalProperties: false + RootVolume: + type: object + description: Information about VM root volume + properties: + sizeGB: + type: integer + encrypted: + type: boolean + required: + - sizeGB + - encrypted + additionalProperties: false + RuntimeScheduleScanConfig: type: object minProperties: 1 # Require that at least 1 property will be set @@ -1551,10 +1564,8 @@ components: launchTime: type: string format: date-time - rootVolumeSizeGB: - type: integer - rootVolumeEncrypted: - type: boolean + rootVolume: + $ref: '#/components/schemas/RootVolume' required: - objectType - instanceID @@ -1563,8 +1574,7 @@ components: - image - platform - launchTime - - rootVolumeSizeGB - - rootVolumeEncrypted + - rootVolume PodInfo: type: object diff --git a/api/server/server.gen.go b/api/server/server.gen.go index e2faeb512..9c1567ea0 100644 --- a/api/server/server.gen.go +++ b/api/server/server.gen.go @@ -1067,6 +1067,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ +<<<<<<< HEAD "H4sIAAAAAAAC/+x9W3PbOLLwX0Hx26rZ3ZLtZL45D8dvjuxkVONbWU7mbG2mzkJkS8KEBDgAaFuTyn8/", "BYCgwAt4kS3JzvjNFoHGpe+NbuBrELIkZRSoFMHx1yDFHCcggev/sBAgJ6fqT0KD4yDFchmMAooTCI6L", "r6OAwx8Z4RAFx5JnMApEuIQEq25ylaqmQnJCF8G3byPTaxpi2g43bzEM9pzQiNCFF/L6+zC4ZJ5gGS4L", @@ -1083,11 +1084,32 @@ var swaggerSpec = []string{ "NgrgIY0ZMWzb1vnMtNMTWdvM4pozpVwharI5vTSW4Pgec+ga88I0s2MmRITaqsm4WUJn/0oHC4iDYBkP", "YaymmaVdYG7KzacSS+hWEJwx+aXHxt6YdnZuYsaSzj7TGUuKDjlpdBFxFfECQg7d05vqZsVgEstM9CI0", "1WVqmj+a2+6ymALHMxITS/FtUD45zVdm6g2CvecabiFJY43xVu5sVX7THjha8/mzVYI1Mnr2Esmz0r+i", +======= +<<<<<<< HEAD + "H4sIAAAAAAAC/+x9W3PbOLLwX0Hx26rZ3ZLtZL45D8dvjuxkVONbWU5ytjZTZyGyJWFCAhwAtK1N5b+f", +<<<<<<< HEAD + "AkBQ4AW8yJZkZ/1mi0Dj0vdGN/AtCFmSMgpUiuD4W5BijhOQwPV/WAiQk1P1J6HBcZBiuQxGAcUJBMfF", + "11HA4c+McIiCY8kzGAUiXEKCVTe5SlVTITmhi+D795HpNQ0xbYebtxgGe05oROjCC3n9fRhcMk+wDJcF", + "1CXgCPga7mR+cKEbNIAhVMICuIbDIizxmGVUFqD+zICv1pD+EuqvDXBmjMWA6RrO2UOKaeQFBOZz+8I0", + "oPcklsC9gObmcw9AVzwC/m7lhcTU99mqDdQoeDhYsIO8hwVoB5hCDKF/74T53GOm068k9YNRH/tg8pb5", + "gUjWCUOEmI4ZnRM/wZaaDKNZ0cZiYjh3fVeNRcqoAC0bplkYgtB/hoxKMDSN0zQmIZaE0aM/BKPqtzXM", + "v3CYB8fB/ztaC50j81Uc5fBu8jHMiBGIkJNUgQuO7ZAoASHwAhRZfKRfKbunZ5wz/mRTOUlJ2zTyMRHo", + "Qc1e644Krtv3+Ful5wlFbPYHhBLJJZaICMRBZpxChAhFOI5RiAUIxOZojkmccRCHwShIOUuBS2I23q7+", + "+FvAAUdXNF5Z7NWpIP/FjKo27EQJ1/rMTvV/MxAIU6QFcD7T+vhG7NM569xG1fBWTUCLZi7kFECjYc54", + "gmVwHERYwoEkCQSjuiQgUaOAiPFQQBzuiCCGAqp8aBhFFEK5vC23TOIY0SyZAVdY0W0N8pb4DhDcAUc8", + "o2jOOJJLIszerSfhjpMlCearTj4IMX1v9JSY5l0UIoEnhGIJ0VXvlXvxP2ZJUtqOyvezByJye6CO+l5o", + "V6AcQvUR2/2ShEuUUfJnBihkVEiOCZUoZMlMrZYwikKcKZ6QS91iHhNDlJvS/g3EGq5YGhXg5QPEnZZI", + "sjVnmFmHmKIZIKNnIXqBjNKxhWXG8TTeOiP1GHf7jNVNbGtF+k+Fj9995KdmoYkjjq/mwfE/N2exEiF/", + "HwXwkMaMGLZt63xm2umJrG1mcc2ZUq4QNdmcXhpLcHyPOXSNeWGa2TETIkJt1WTcLKGzf6WDBcRBsIyH", + "MFbTzNIuMDfl5lOJJXQrCM6Y/NpjY29MOzs3MWNJZ5/pjCVFh5w0uoi4ingBIYfu6U11s2IwiWUmehGa", + "6jI1zR/NbXdZTIHjGYmJpfg2KJ+c5isz9QbB3nMNt5CkscZ4K3e2Kr9pDxyt+fzZKsEaGT17ieRZ6X+i", +>>>>>>> 43449322 (review) "hOrWiK8S65lJrG7rYKAMu7E00C7LDP3URJn2XPVfRIJBeY1vaBbHeBZDhcow53hlrctbjqkgCrO3yk7q", "bbAKOy2gWaL25JLp6VKIglFwDRoJwSiYhkuIslj/qla8umV6S0fBhF5ztuAgRDAKTmaMS93olFFwdreX", "HJwWdFXZpJ7Sq7LZ30bBAhQJxMM79pRVDR2Hiqs6iL4yo95TiY0NevWTAfWOAxmyCqCVFgoToUYNStS9", "xwmJCQgTkeslT8o9cpFJgU+okJiGMOagEdYfpL9zfWl5NFX9aEOqDdZQw/oL8fJ97IO7xAZOD9t8VuPy", "G39VN0Q4DBlXEgpJpi2yBbkDikycXPRyWQuxWx7xnAipvGN3zPbREKYRSvECDpHuHANdyCVKMiHRDFDM", +<<<<<<< HEAD "7pW/zRH8keFYQVBtp+RPUNZjMYve1qxnZblS8O67jm0oU5KuchOzVYVe6KBJl068ZlGvdqeE92o3ZlRi", "osgqwQsY2EW3/m0UREThUwcUTEA6wWmqdNDx16BhgP5TGQXlwXrNaBTYxXfszSiwu9mx2aMgx04X7iyL", "rS6N3DEUYYNczWSyEWs2cOXWWFIgQvfGg5vx3zhmWXTN2R2JzBmfNblOfp0q0+nPjCsT7cP4WptP4Rd9", @@ -1162,6 +1184,270 @@ var swaggerSpec = []string{ "247q+OlxqAw14Z3egR2xYTWsyAthX1oYZ+vxm87AzWN3/GWHaZ5ZgGZ3kRlzR1CX3ukI12yfdnbhS+3D", "i+oMyDwbx2mvHtO2XaXhava7C7c8TZzlVRI8pSQoRVJeJcGrJNhNnKR3gETfP83vLI9nPA6OgyOckuDb", "b9/+LwAA//+wNhfM78IAAA==", +======= + "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", + "rNGP674AAA==", +======= + "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", + "4Dg4wikJvv/+/f8CAAD//6CoSp9YvwAA", +>>>>>>> 4fcf9896 (extend asset vm info with root volume details of encryption and size) +======= + "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", + "/r8AAA==", +>>>>>>> 6a36bd20 (review) +>>>>>>> 43449322 (review) } // GetSwagger returns the content of the embedded swagger specification file diff --git a/pkg/backend/database/demo.go b/pkg/backend/database/demo.go index 3805f6d2d..495923926 100644 --- a/pkg/backend/database/demo.go +++ b/pkg/backend/database/demo.go @@ -360,16 +360,18 @@ func createVMInfo(instanceID, location, image, instanceType, platform string, ) *models.AssetType { info := models.AssetType{} err := info.FromVMInfo(models.VMInfo{ - Image: image, - InstanceID: instanceID, - InstanceProvider: &instanceProvider, - InstanceType: instanceType, - LaunchTime: launchTime, - Location: location, - Platform: platform, - Tags: &tags, - RootVolumeSizeGB: rootVolumeSizeGB, - RootVolumeEncrypted: rootVolumeEncrypted, + Image: image, + InstanceID: instanceID, + InstanceProvider: &instanceProvider, + InstanceType: instanceType, + LaunchTime: launchTime, + Location: location, + Platform: platform, + Tags: &tags, + RootVolume: models.RootVolume{ + Encrypted: rootVolumeEncrypted, + SizeGB: rootVolumeSizeGB, + }, }) if err != nil { panic(err) diff --git a/pkg/backend/database/gorm/odata.go b/pkg/backend/database/gorm/odata.go index 3a812fb7f..50ba49b73 100644 --- a/pkg/backend/database/gorm/odata.go +++ b/pkg/backend/database/gorm/odata.go @@ -388,15 +388,17 @@ var schemaMetas = map[string]odatasql.SchemaMeta{ }, "VMInfo": { Fields: odatasql.Schema{ - "objectType": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "instanceID": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "location": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "launchTime": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "platform": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "instanceType": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "image": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "rootVolumeSizeGB": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, - "rootVolumeEncrypted": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "objectType": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "instanceID": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "location": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "launchTime": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "platform": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "instanceType": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "image": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "rootVolume": odatasql.FieldMeta{ + FieldType: odatasql.ComplexFieldType, + ComplexFieldSchemas: []string{"RootVolume"}, + }, "tags": odatasql.FieldMeta{ FieldType: odatasql.CollectionFieldType, CollectionItemMeta: &odatasql.FieldMeta{ @@ -414,6 +416,12 @@ var schemaMetas = map[string]odatasql.SchemaMeta{ "instanceProvider": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, }, }, + "RootVolume": { + Fields: odatasql.Schema{ + "sizeGB": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + "encrypted": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, + }, + }, "SecurityGroup": { Fields: odatasql.Schema{ "id": odatasql.FieldMeta{FieldType: odatasql.PrimitiveFieldType}, diff --git a/runtime_scan/pkg/provider/aws/client.go b/runtime_scan/pkg/provider/aws/client.go index 556a6ab8d..ae63dea3c 100644 --- a/runtime_scan/pkg/provider/aws/client.go +++ b/runtime_scan/pkg/provider/aws/client.go @@ -775,16 +775,15 @@ func (c *Client) getInstancesFromDescribeInstancesOutput(ctx context.Context, re } if err := validateInstanceFields(instance); err != nil { - logger.Errorf("Instance validation failed. instance id=%v: %v", getStringPointerValOrEmpty(instance.InstanceId), err) + logger.Errorf("Instance validation failed. instance id=%v: %v", utils.StringPointerValOrEmpty(instance.InstanceId), err) continue } rootVol, err := getRootVolumeInfo(ctx, c.ec2Client, instance, regionID) if err != nil { - logger.Warnf("Couldn't get root volume info. instance id=%v: %v", getStringPointerValOrEmpty(instance.InstanceId), err) - rootVol = &rootVolumeInfo{ - DeviceName: getStringPointerValOrEmpty(instance.RootDeviceName), - SizeGB: 0, - Encrypted: false, + logger.Warnf("Couldn't get root volume info. instance id=%v: %v", utils.StringPointerValOrEmpty(instance.InstanceId), err) + rootVol = &models.RootVolume{ + SizeGB: 0, + Encrypted: false, } } @@ -799,8 +798,8 @@ func (c *Client) getInstancesFromDescribeInstancesOutput(ctx context.Context, re LaunchTime: *instance.LaunchTime, VpcID: *instance.VpcId, SecurityGroups: getSecurityGroupsIDs(instance.SecurityGroups), - RootDeviceName: rootVol.DeviceName, - RootVolumeSizeGB: rootVol.SizeGB, + RootDeviceName: utils.StringPointerValOrEmpty(instance.RootDeviceName), + RootVolumeSizeGB: int32(rootVol.SizeGB), RootVolumeEncrypted: rootVol.Encrypted, ec2Client: c.ec2Client, @@ -816,10 +815,13 @@ type rootVolumeInfo struct { Encrypted bool } -func getRootVolumeInfo(ctx context.Context, client *ec2.Client, i ec2types.Instance, region string) (*rootVolumeInfo, error) { +func getRootVolumeInfo(ctx context.Context, client *ec2.Client, i ec2types.Instance, region string) (*models.RootVolume, error) { + if i.RootDeviceName == nil || *i.RootDeviceName == "" { + return nil, fmt.Errorf("RootDeviceName is not set") + } logger := log.GetLoggerFromContextOrDiscard(ctx) for _, mapping := range i.BlockDeviceMappings { - if getStringPointerValOrEmpty(mapping.DeviceName) == getStringPointerValOrEmpty(i.RootDeviceName) { + if utils.StringPointerValOrEmpty(mapping.DeviceName) == utils.StringPointerValOrEmpty(i.RootDeviceName) { if mapping.Ebs == nil { return nil, fmt.Errorf("EBS of the root volume is nil") } @@ -847,10 +849,9 @@ func getRootVolumeInfo(ctx context.Context, client *ec2.Client, i ec2types.Insta }).Warnf("Found more than 1 root volume, using the first") } - return &rootVolumeInfo{ - DeviceName: getStringPointerValOrEmpty(mapping.DeviceName), - SizeGB: getInt32PointerValOrEmpty(describeOut.Volumes[0].Size), - Encrypted: getBoolPointerValOrFalse(describeOut.Volumes[0].Encrypted), + return &models.RootVolume{ + SizeGB: int(utils.Int32PointerValOrEmpty(describeOut.Volumes[0].Size)), + Encrypted: utils.BoolPointerValOrFalse(describeOut.Volumes[0].Encrypted), }, nil } } diff --git a/runtime_scan/pkg/provider/aws/helpers.go b/runtime_scan/pkg/provider/aws/helpers.go index 647a1e27a..78929efd5 100644 --- a/runtime_scan/pkg/provider/aws/helpers.go +++ b/runtime_scan/pkg/provider/aws/helpers.go @@ -168,27 +168,6 @@ func getInstanceState(result *ec2.DescribeInstancesOutput, instanceID string) ec return ec2types.InstanceStateNamePending } -func getStringPointerValOrEmpty(val *string) string { - if val == nil { - return "" - } - return *val -} - -func getInt32PointerValOrEmpty(val *int32) int32 { - if val == nil { - return 0 - } - return *val -} - -func getBoolPointerValOrFalse(val *bool) bool { - if val == nil { - return false - } - return *val -} - func validateInstanceFields(instance ec2types.Instance) error { if instance.InstanceId == nil { return fmt.Errorf("instance id does not exist") @@ -245,18 +224,20 @@ func getSecurityGroupsFromEC2GroupIdentifiers(identifiers []ec2types.GroupIdenti func getVMInfoFromInstance(i Instance) (models.AssetType, error) { assetType := models.AssetType{} err := assetType.FromVMInfo(models.VMInfo{ - Image: i.Image, - InstanceID: i.ID, - InstanceProvider: utils.PointerTo(models.AWS), - InstanceType: i.InstanceType, - LaunchTime: i.LaunchTime, - Location: i.Location(), - ObjectType: "VMInfo", - Platform: i.Platform, - RootVolumeEncrypted: i.RootVolumeEncrypted, - RootVolumeSizeGB: int(i.RootVolumeSizeGB), - SecurityGroups: utils.PointerTo(i.SecurityGroups), - Tags: utils.PointerTo(i.Tags), + Image: i.Image, + InstanceID: i.ID, + InstanceProvider: utils.PointerTo(models.AWS), + InstanceType: i.InstanceType, + LaunchTime: i.LaunchTime, + Location: i.Location(), + ObjectType: "VMInfo", + Platform: i.Platform, + RootVolume: models.RootVolume{ + Encrypted: i.RootVolumeEncrypted, + SizeGB: int(i.RootVolumeSizeGB), + }, + SecurityGroups: utils.PointerTo(i.SecurityGroups), + Tags: utils.PointerTo(i.Tags), }) if err != nil { err = fmt.Errorf("failed to create AssetType from VMInfo: %w", err) diff --git a/runtime_scan/pkg/provider/azure/client.go b/runtime_scan/pkg/provider/azure/client.go index f94ee1fbb..8561b02c1 100644 --- a/runtime_scan/pkg/provider/azure/client.go +++ b/runtime_scan/pkg/provider/azure/client.go @@ -228,43 +228,44 @@ type rootVolumeInfo struct { Encrypted bool } -func (c *Client) getRootVolumeInfo(ctx context.Context, vm *armcompute.VirtualMachine) *rootVolumeInfo { +func (c *Client) getRootVolumeInfo(ctx context.Context, vm *armcompute.VirtualMachine) *models.RootVolume { logger := log.GetLoggerFromContextOrDiscard(ctx) - ret := &rootVolumeInfo{ - SizeGB: *vm.Properties.StorageProfile.OSDisk.DiskSizeGB, + ret := &models.RootVolume{ + SizeGB: int(utils.Int32PointerValOrEmpty(vm.Properties.StorageProfile.OSDisk.DiskSizeGB)), Encrypted: false, } - osDiskID, err := arm.ParseResourceID(*vm.Properties.StorageProfile.OSDisk.ManagedDisk.ID) + osDiskID, err := arm.ParseResourceID(utils.StringPointerValOrEmpty(vm.Properties.StorageProfile.OSDisk.ManagedDisk.ID)) if err != nil { - logger.Warnf("Failed to parse disk ID. DiskID=%v: %v", *vm.Properties.StorageProfile.OSDisk.ManagedDisk.ID, err) + logger.Warnf("Failed to parse disk ID. DiskID=%v: %v", + utils.StringPointerValOrEmpty(vm.Properties.StorageProfile.OSDisk.ManagedDisk.ID), err) return ret } osDisk, err := c.disksClient.Get(context.TODO(), osDiskID.ResourceGroupName, osDiskID.Name, nil) if err != nil { - logger.Warnf("Failed to get OS disk. DiskID=%v: %v", *vm.Properties.StorageProfile.OSDisk.ManagedDisk.ID, err) + logger.Warnf("Failed to get OS disk. DiskID=%v: %v", + utils.StringPointerValOrEmpty(vm.Properties.StorageProfile.OSDisk.ManagedDisk.ID), err) return ret } ret.Encrypted = isEncrypted(osDisk) - ret.SizeGB = *osDisk.Disk.Properties.DiskSizeGB + ret.SizeGB = int(utils.Int32PointerValOrEmpty(osDisk.Disk.Properties.DiskSizeGB)) return ret } -func getVMInfoFromVirtualMachine(vm *armcompute.VirtualMachine, rootVol *rootVolumeInfo) (models.AssetType, error) { +func getVMInfoFromVirtualMachine(vm *armcompute.VirtualMachine, rootVol *models.RootVolume) (models.AssetType, error) { assetType := models.AssetType{} err := assetType.FromVMInfo(models.VMInfo{ - ObjectType: "VMInfo", - InstanceProvider: utils.PointerTo(models.Azure), - InstanceID: *vm.ID, - Image: createImageURN(vm.Properties.StorageProfile.ImageReference), - InstanceType: *vm.Type, - LaunchTime: *vm.Properties.TimeCreated, - Location: *vm.Location, - Platform: string(*vm.Properties.StorageProfile.OSDisk.OSType), - RootVolumeEncrypted: rootVol.Encrypted, - RootVolumeSizeGB: int(rootVol.SizeGB), - SecurityGroups: &[]models.SecurityGroup{}, - Tags: convertTags(vm.Tags), + ObjectType: "VMInfo", + InstanceProvider: utils.PointerTo(models.Azure), + InstanceID: *vm.ID, + Image: createImageURN(vm.Properties.StorageProfile.ImageReference), + InstanceType: *vm.Type, + LaunchTime: *vm.Properties.TimeCreated, + Location: *vm.Location, + Platform: string(*vm.Properties.StorageProfile.OSDisk.OSType), + RootVolume: *rootVol, + SecurityGroups: &[]models.SecurityGroup{}, + Tags: convertTags(vm.Tags), }) if err != nil { err = fmt.Errorf("failed to create AssetType from VMInfo: %w", err) diff --git a/shared/pkg/utils/utils.go b/shared/pkg/utils/utils.go index fc7684330..116d28fef 100644 --- a/shared/pkg/utils/utils.go +++ b/shared/pkg/utils/utils.go @@ -57,6 +57,27 @@ func PointerTo[T any](value T) *T { return &value } +func StringPointerValOrEmpty(val *string) string { + if val == nil { + return "" + } + return *val +} + +func Int32PointerValOrEmpty(val *int32) int32 { + if val == nil { + return 0 + } + return *val +} + +func BoolPointerValOrFalse(val *bool) bool { + if val == nil { + return false + } + return *val +} + func StringKeyMapToArray[T any](m map[string]T) []T { ret := make([]T, 0, len(m)) for _, t := range m { diff --git a/ui/src/layout/detail-displays/AssetDetails/index.js b/ui/src/layout/detail-displays/AssetDetails/index.js index af239325e..c5849da4e 100644 --- a/ui/src/layout/detail-displays/AssetDetails/index.js +++ b/ui/src/layout/detail-displays/AssetDetails/index.js @@ -52,7 +52,8 @@ const AssetDetails = ({assetData, withAssetLink=false, withAssetScansLink=false} const navigate = useNavigate(); const {id, assetInfo, firstSeen, lastSeen, terminatedOn} = assetData; - const {instanceID, objectType, location, tags, image, instanceType, platform, launchTime, rootVolumeSizeGB, rootVolumeEncrypted} = assetInfo || {}; + const {instanceID, objectType, location, tags, image, instanceType, platform, launchTime, rootVolume} = assetInfo || {}; + const {sizeGB, encrypted} = rootVolume || {}; return ( {formatDate(launchTime)} - {rootVolumeSizeGB} GB - {rootVolumeEncrypted ? "Yes" : "No"} + {sizeGB} GB + {encrypted ? "Yes" : "No"} )} From 466b66be311aa82f43757225eddcf468764594a4 Mon Sep 17 00:00:00 2001 From: Alexei Kravtsov Date: Thu, 27 Jul 2023 15:02:08 +0300 Subject: [PATCH 05/11] add unknown state to encrypted volume --- api/models/models.gen.go | 14 ++- api/openapi.yaml | 6 +- api/server/server.gen.go | 102 ++++++++++++++++++ pkg/backend/database/demo.go | 8 +- runtime_scan/pkg/provider/aws/client.go | 20 ++-- runtime_scan/pkg/provider/aws/client_test.go | 59 ++++++++-- runtime_scan/pkg/provider/aws/instance.go | 2 +- runtime_scan/pkg/provider/azure/client.go | 12 ++- .../pkg/provider/azure/client_test.go | 7 +- .../detail-displays/AssetDetails/index.js | 2 +- 10 files changed, 200 insertions(+), 32 deletions(-) diff --git a/api/models/models.gen.go b/api/models/models.gen.go index 849597aea..5d68bd7e5 100644 --- a/api/models/models.gen.go +++ b/api/models/models.gen.go @@ -46,6 +46,13 @@ const ( ResourceCleanupStateSkipped ResourceCleanupState = "Skipped" ) +// Defines values for RootVolumeEncrypted. +const ( + No RootVolumeEncrypted = "No" + Unknown RootVolumeEncrypted = "Unknown" + Yes RootVolumeEncrypted = "Yes" +) + // Defines values for RootkitType. const ( APPLICATION RootkitType = "APPLICATION" @@ -506,10 +513,13 @@ type ResourceCleanupState string // RootVolume Information about VM root volume type RootVolume struct { - Encrypted bool `json:"encrypted"` - SizeGB int `json:"sizeGB"` + Encrypted RootVolumeEncrypted `json:"encrypted"` + SizeGB int `json:"sizeGB"` } +// RootVolumeEncrypted defines model for RootVolume.Encrypted. +type RootVolumeEncrypted string + // Rootkit defines model for Rootkit. type Rootkit struct { Message *string `json:"message,omitempty"` diff --git a/api/openapi.yaml b/api/openapi.yaml index 281b3360b..3f0afc84a 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -1387,7 +1387,11 @@ components: sizeGB: type: integer encrypted: - type: boolean + type: string + enum: + - Yes + - No + - Unknown required: - sizeGB - encrypted diff --git a/api/server/server.gen.go b/api/server/server.gen.go index 9c1567ea0..3f29a180b 100644 --- a/api/server/server.gen.go +++ b/api/server/server.gen.go @@ -1067,6 +1067,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ +<<<<<<< HEAD <<<<<<< HEAD "H4sIAAAAAAAC/+x9W3PbOLLwX0Hx26rZ3ZLtZL45D8dvjuxkVONbWU7mbG2mzkJkS8KEBDgAaFuTyn8/", "BYCgwAt4kS3JzvjNFoHGpe+NbuBrELIkZRSoFMHx1yDFHCcggev/sBAgJ6fqT0KD4yDFchmMAooTCI6L", @@ -1085,6 +1086,8 @@ var swaggerSpec = []string{ "YaymmaVdYG7KzacSS+hWEJwx+aXHxt6YdnZuYsaSzj7TGUuKDjlpdBFxFfECQg7d05vqZsVgEstM9CI0", "1WVqmj+a2+6ymALHMxITS/FtUD45zVdm6g2CvecabiFJY43xVu5sVX7THjha8/mzVYI1Mnr2Esmz0r+i", ======= +======= +>>>>>>> 88c0dce4 (add unknown state to encrypted volume) <<<<<<< HEAD "H4sIAAAAAAAC/+x9W3PbOLLwX0Hx26rZ3ZLtZL45D8dvjuxkVONbWU5ytjZTZyGyJWFCAhwAtK1N5b+f", <<<<<<< HEAD @@ -1447,7 +1450,106 @@ var swaggerSpec = []string{ "XaXhava7C7c8TZzlVRI8pSQoRVJeJcGrJNhNnKR3gETfP83vLI9nPAmOgyOckuDbb9/+LwAA///3i6S8", "/r8AAA==", >>>>>>> 6a36bd20 (review) +<<<<<<< HEAD >>>>>>> 43449322 (review) +======= +======= + "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", + "kuDbb9/+LwAA//9ta0ihG8AAAA==", +>>>>>>> 79cc430a (add unknown state to encrypted volume) +>>>>>>> 88c0dce4 (add unknown state to encrypted volume) } // GetSwagger returns the content of the embedded swagger specification file diff --git a/pkg/backend/database/demo.go b/pkg/backend/database/demo.go index 495923926..0b4a205fa 100644 --- a/pkg/backend/database/demo.go +++ b/pkg/backend/database/demo.go @@ -356,7 +356,7 @@ func createVulnerabilityFindings(ctx context.Context, base models.Finding, vulne } func createVMInfo(instanceID, location, image, instanceType, platform string, - tags []models.Tag, launchTime time.Time, instanceProvider models.CloudProvider, rootVolumeSizeGB int, rootVolumeEncrypted bool, + tags []models.Tag, launchTime time.Time, instanceProvider models.CloudProvider, rootVolumeSizeGB int, rootVolumeEncrypted models.RootVolumeEncrypted, ) *models.AssetType { info := models.AssetType{} err := info.FromVMInfo(models.VMInfo{ @@ -402,7 +402,7 @@ func createAssets() []models.Asset { }, }, AssetInfo: createVMInfo(awsInstanceEUCentral11, awsRegionEUCentral1+"/"+awsVPCEUCentral11+"/"+awsSGEUCentral111, - "ami-111", "t2.large", "Linux", []models.Tag{{Key: "Name", Value: "asset1"}}, time.Now(), models.AWS, 8, false), + "ami-111", "t2.large", "Linux", []models.Tag{{Key: "Name", Value: "asset1"}}, time.Now(), models.AWS, 8, models.No), }, { ScansCount: utils.PointerTo(1), @@ -424,7 +424,7 @@ func createAssets() []models.Asset { }, }, AssetInfo: createVMInfo(awsInstanceEUCentral12, awsRegionEUCentral1+"/"+awsVPCEUCentral11+"/"+awsSGEUCentral111, - "ami-111", "t2.large", "Linux", []models.Tag{{Key: "Name", Value: "asset2"}}, time.Now(), models.AWS, 25, true), + "ami-111", "t2.large", "Linux", []models.Tag{{Key: "Name", Value: "asset2"}}, time.Now(), models.AWS, 25, models.Yes), }, { ScansCount: utils.PointerTo(1), @@ -445,7 +445,7 @@ func createAssets() []models.Asset { }, }, AssetInfo: createVMInfo(awsInstanceUSEast11, awsRegionUSEast1+"/"+awsVPCUSEast11+"/"+awsSGUSEast111, - "ami-112", "t2.micro", "Linux", []models.Tag{{Key: "Name", Value: "asset3"}}, time.Now(), models.AWS, 512, false), + "ami-112", "t2.micro", "Linux", []models.Tag{{Key: "Name", Value: "asset3"}}, time.Now(), models.AWS, 512, models.Unknown), }, } } diff --git a/runtime_scan/pkg/provider/aws/client.go b/runtime_scan/pkg/provider/aws/client.go index ae63dea3c..6aa3a5bee 100644 --- a/runtime_scan/pkg/provider/aws/client.go +++ b/runtime_scan/pkg/provider/aws/client.go @@ -783,7 +783,7 @@ func (c *Client) getInstancesFromDescribeInstancesOutput(ctx context.Context, re logger.Warnf("Couldn't get root volume info. instance id=%v: %v", utils.StringPointerValOrEmpty(instance.InstanceId), err) rootVol = &models.RootVolume{ SizeGB: 0, - Encrypted: false, + Encrypted: models.Unknown, } } @@ -809,12 +809,6 @@ func (c *Client) getInstancesFromDescribeInstancesOutput(ctx context.Context, re return ret } -type rootVolumeInfo struct { - DeviceName string - SizeGB int32 - Encrypted bool -} - func getRootVolumeInfo(ctx context.Context, client *ec2.Client, i ec2types.Instance, region string) (*models.RootVolume, error) { if i.RootDeviceName == nil || *i.RootDeviceName == "" { return nil, fmt.Errorf("RootDeviceName is not set") @@ -851,7 +845,7 @@ func getRootVolumeInfo(ctx context.Context, client *ec2.Client, i ec2types.Insta return &models.RootVolume{ SizeGB: int(utils.Int32PointerValOrEmpty(describeOut.Volumes[0].Size)), - Encrypted: utils.BoolPointerValOrFalse(describeOut.Volumes[0].Encrypted), + Encrypted: encryptedToAPI(describeOut.Volumes[0].Encrypted), }, nil } } @@ -859,6 +853,16 @@ func getRootVolumeInfo(ctx context.Context, client *ec2.Client, i ec2types.Insta return nil, fmt.Errorf("instance doesn't have a root volume block device mapping") } +func encryptedToAPI(encrypted *bool) models.RootVolumeEncrypted { + if encrypted == nil { + return models.Unknown + } + if *encrypted { + return models.Yes + } + return models.No +} + func (c *Client) ListAllRegions(ctx context.Context) ([]Region, error) { ret := make([]Region, 0) out, err := c.ec2Client.DescribeRegions(ctx, &ec2.DescribeRegionsInput{ diff --git a/runtime_scan/pkg/provider/aws/client_test.go b/runtime_scan/pkg/provider/aws/client_test.go index 4b57bd5b0..7365fe39f 100644 --- a/runtime_scan/pkg/provider/aws/client_test.go +++ b/runtime_scan/pkg/provider/aws/client_test.go @@ -277,7 +277,8 @@ func TestClient_getInstancesFromDescribeInstancesOutput(t *testing.T) { Value: "val-1", }, }, - LaunchTime: launchTime, + LaunchTime: launchTime, + RootVolumeEncrypted: models.Unknown, }, { ID: "instance-2", @@ -296,7 +297,8 @@ func TestClient_getInstancesFromDescribeInstancesOutput(t *testing.T) { Value: "val-2", }, }, - LaunchTime: launchTime, + LaunchTime: launchTime, + RootVolumeEncrypted: models.Unknown, }, { ID: "instance-3", @@ -305,12 +307,13 @@ func TestClient_getInstancesFromDescribeInstancesOutput(t *testing.T) { SecurityGroups: []models.SecurityGroup{ {Id: "group3"}, }, - AvailabilityZone: "az3", - Image: "image3", - InstanceType: "t2.large", - Platform: "linux", - Tags: nil, - LaunchTime: launchTime, + AvailabilityZone: "az3", + Image: "image3", + InstanceType: "t2.large", + Platform: "linux", + Tags: nil, + LaunchTime: launchTime, + RootVolumeEncrypted: models.Unknown, }, }, }, @@ -341,3 +344,43 @@ func TestClient_getInstancesFromDescribeInstancesOutput(t *testing.T) { }) } } + +func Test_encryptedToAPI(t *testing.T) { + type args struct { + encrypted *bool + } + tests := []struct { + name string + args args + want models.RootVolumeEncrypted + }{ + { + name: "unknown", + args: args{ + encrypted: nil, + }, + want: models.Unknown, + }, + { + name: "no", + args: args{ + encrypted: utils.PointerTo(false), + }, + want: models.No, + }, + { + name: "yes", + args: args{ + encrypted: utils.PointerTo(true), + }, + want: models.Yes, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := encryptedToAPI(tt.args.encrypted); got != tt.want { + t.Errorf("encryptedToAPI() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/runtime_scan/pkg/provider/aws/instance.go b/runtime_scan/pkg/provider/aws/instance.go index 5c29043be..2e3f905da 100644 --- a/runtime_scan/pkg/provider/aws/instance.go +++ b/runtime_scan/pkg/provider/aws/instance.go @@ -43,7 +43,7 @@ type Instance struct { LaunchTime time.Time RootDeviceName string RootVolumeSizeGB int32 - RootVolumeEncrypted bool + RootVolumeEncrypted models.RootVolumeEncrypted Volumes []Volume Metadata provider.ScanMetadata diff --git a/runtime_scan/pkg/provider/azure/client.go b/runtime_scan/pkg/provider/azure/client.go index 8561b02c1..4f087b502 100644 --- a/runtime_scan/pkg/provider/azure/client.go +++ b/runtime_scan/pkg/provider/azure/client.go @@ -232,7 +232,7 @@ func (c *Client) getRootVolumeInfo(ctx context.Context, vm *armcompute.VirtualMa logger := log.GetLoggerFromContextOrDiscard(ctx) ret := &models.RootVolume{ SizeGB: int(utils.Int32PointerValOrEmpty(vm.Properties.StorageProfile.OSDisk.DiskSizeGB)), - Encrypted: false, + Encrypted: models.Unknown, } osDiskID, err := arm.ParseResourceID(utils.StringPointerValOrEmpty(vm.Properties.StorageProfile.OSDisk.ManagedDisk.ID)) if err != nil { @@ -274,11 +274,15 @@ func getVMInfoFromVirtualMachine(vm *armcompute.VirtualMachine, rootVol *models. return assetType, err } -func isEncrypted(disk armcompute.DisksClientGetResponse) bool { +func isEncrypted(disk armcompute.DisksClientGetResponse) models.RootVolumeEncrypted { if disk.Properties.EncryptionSettingsCollection == nil { - return false + return models.No } - return *disk.Properties.EncryptionSettingsCollection.Enabled + if *disk.Properties.EncryptionSettingsCollection.Enabled { + return models.Yes + } + + return models.No } func convertTags(tags map[string]*string) *[]models.Tag { diff --git a/runtime_scan/pkg/provider/azure/client_test.go b/runtime_scan/pkg/provider/azure/client_test.go index 081abd3d3..be6928449 100644 --- a/runtime_scan/pkg/provider/azure/client_test.go +++ b/runtime_scan/pkg/provider/azure/client_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4" + "github.com/openclarity/vmclarity/api/models" "github.com/openclarity/vmclarity/shared/pkg/utils" ) @@ -14,7 +15,7 @@ func Test_isEncrypted(t *testing.T) { tests := []struct { name string args args - want bool + want models.RootVolumeEncrypted }{ { name: "encrypted", @@ -29,7 +30,7 @@ func Test_isEncrypted(t *testing.T) { }, }, }, - want: true, + want: models.Yes, }, { name: "not encrypted", @@ -42,7 +43,7 @@ func Test_isEncrypted(t *testing.T) { }, }, }, - want: false, + want: models.No, }, } for _, tt := range tests { diff --git a/ui/src/layout/detail-displays/AssetDetails/index.js b/ui/src/layout/detail-displays/AssetDetails/index.js index c5849da4e..2cabd350f 100644 --- a/ui/src/layout/detail-displays/AssetDetails/index.js +++ b/ui/src/layout/detail-displays/AssetDetails/index.js @@ -83,7 +83,7 @@ const AssetDetails = ({assetData, withAssetLink=false, withAssetScansLink=false} {sizeGB} GB - {encrypted ? "Yes" : "No"} + {encrypted} )} From 806da0098524ccd3ffa7b9718790a65461f2a0ad Mon Sep 17 00:00:00 2001 From: Alexei Kravtsov Date: Thu, 27 Jul 2023 15:09:27 +0300 Subject: [PATCH 06/11] gen api --- api/server/server.gen.go | 79 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/api/server/server.gen.go b/api/server/server.gen.go index 3f29a180b..9fadaac7c 100644 --- a/api/server/server.gen.go +++ b/api/server/server.gen.go @@ -1067,6 +1067,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD "H4sIAAAAAAAC/+x9W3PbOLLwX0Hx26rZ3ZLtZL45D8dvjuxkVONbWU7mbG2mzkJkS8KEBDgAaFuTyn8/", @@ -1355,8 +1356,10 @@ var swaggerSpec = []string{ "4Dg4wikJvv/+/f8CAAD//6CoSp9YvwAA", >>>>>>> 4fcf9896 (extend asset vm info with root volume details of encryption and size) ======= +======= +>>>>>>> f6bb1ac3 (gen api) "H4sIAAAAAAAC/+x9W3PbOLLwX0Hx26rZ3aLtZL45D8dvjuxkVONbWU7mbG2mzkJkS8KEAjgAaFuTyn8/", - "BYCgwAt4kS3JzvjNFhuNW9+7AXwNIrZMGQUqRXD8NUgxx0uQwPV/WAiQ41P1J6HBcZBiuQjCgOIlBMfF", + "BYCgwAt4kS3JzvjNFhuNW9/RDXwNIrZMGQUqRXD8NUgxx0uQwPV/WAiQ41P1J6HBcZBiuQjCgOIlBMfF", "1zDg8EdGOMTBseQZhIGIFrDEqplcpQpUSE7oPPj2LTStJhGm7XhziGG4Z4TGhM69mNffh+ElsyWW0aLA", "ugAcA1/jHc8OLjRAAxpCJcyBazwsxhKPWEZlgeqPDPhqjelvkf7agGfKWAKYrvGcPaSYxl5EYD63T0wj", "ek8SCdyLaGY+90B0xWPg71ZeTEx9n67aUIXBw8GcHeQtLELbwQQSiPxrJ8znHiOdfCGpH4362Gcnb5kf", @@ -1378,6 +1381,7 @@ var swaggerSpec = []string{ "fuOvakCEo4hxJaGQZNoim5M7oMjEyUUvl7UQu+Uez4mQyjt2+2zvDWEaoxTP4RDpxgnQuVygZSYkmgJK", "2L3ytzmCPzKcKAwKdkL+BGU9FqPobc16ZpYrBe+669iGMiXpKjcxW1XohQ6adOnEaxb3gjsl3MD9FgYx", "Ucut/X0TL17iNFUq4vhrYOE60ISB7bhjXGGQT6RrmpYaV5eGRc3i2XhQ84puRMUNBLw16hWI0L2R62ak", +<<<<<<< HEAD "OkpYFl9zdkdikw6z1snJrxNlZfyZcWXNfBhdN5gY4Zp+qhsTE252tilGx0yGovGjQwiNKR7XqnRgmyzC", "3MVqoJo7MFmiWu+lzW0yEH1zMh7M6bvGj5LIpLlZxpNHmaTf/NPOzXq7PWtPt4dXquVLec2ebF9adsoG", "Gvw2aS92WE9i89Vz9HxlNFTh8wQMcwXfsaXdg8j37jHJiKr7OauQQy+tdI2jL3gOLil1aZ6SLzikYR6M", @@ -1550,6 +1554,79 @@ var swaggerSpec = []string{ "kuDbb9/+LwAA//9ta0ihG8AAAA==", >>>>>>> 79cc430a (add unknown state to encrypted volume) >>>>>>> 88c0dce4 (add unknown state to encrypted volume) +======= + "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", + "j2c8CY6DI5yS4Ntv3/4vAAD//4bRtVwmwAAA", +>>>>>>> f6bb1ac3 (gen api) } // GetSwagger returns the content of the embedded swagger specification file From e723b002ddd521f14e15377a796a003b184902c9 Mon Sep 17 00:00:00 2001 From: Alexei Kravtsov Date: Thu, 27 Jul 2023 15:14:41 +0300 Subject: [PATCH 07/11] test lic --- runtime_scan/pkg/provider/azure/client_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/runtime_scan/pkg/provider/azure/client_test.go b/runtime_scan/pkg/provider/azure/client_test.go index be6928449..38ea15b00 100644 --- a/runtime_scan/pkg/provider/azure/client_test.go +++ b/runtime_scan/pkg/provider/azure/client_test.go @@ -1,3 +1,18 @@ +// Copyright © 2023 Cisco Systems, Inc. and its affiliates. +// All rights reserved. +// +// 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. + package azure import ( From 1f50bf36296e245ea30aa1f59286386644f0b1ba Mon Sep 17 00:00:00 2001 From: Alexei Kravtsov Date: Thu, 27 Jul 2023 16:08:04 +0300 Subject: [PATCH 08/11] remove unused struct --- runtime_scan/pkg/provider/azure/client.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/runtime_scan/pkg/provider/azure/client.go b/runtime_scan/pkg/provider/azure/client.go index 4f087b502..161f5c351 100644 --- a/runtime_scan/pkg/provider/azure/client.go +++ b/runtime_scan/pkg/provider/azure/client.go @@ -223,11 +223,6 @@ func (c *Client) processVirtualMachineListIntoAssetTypes(ctx context.Context, vm return ret, nil } -type rootVolumeInfo struct { - SizeGB int32 - Encrypted bool -} - func (c *Client) getRootVolumeInfo(ctx context.Context, vm *armcompute.VirtualMachine) *models.RootVolume { logger := log.GetLoggerFromContextOrDiscard(ctx) ret := &models.RootVolume{ From 15b1bdcf2163392b45df819ba311c0e625ceaead Mon Sep 17 00:00:00 2001 From: Alexei Kravtsov Date: Thu, 27 Jul 2023 16:25:15 +0300 Subject: [PATCH 09/11] ctx --- runtime_scan/pkg/provider/azure/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime_scan/pkg/provider/azure/client.go b/runtime_scan/pkg/provider/azure/client.go index 161f5c351..694a87bc0 100644 --- a/runtime_scan/pkg/provider/azure/client.go +++ b/runtime_scan/pkg/provider/azure/client.go @@ -235,7 +235,7 @@ func (c *Client) getRootVolumeInfo(ctx context.Context, vm *armcompute.VirtualMa utils.StringPointerValOrEmpty(vm.Properties.StorageProfile.OSDisk.ManagedDisk.ID), err) return ret } - osDisk, err := c.disksClient.Get(context.TODO(), osDiskID.ResourceGroupName, osDiskID.Name, nil) + osDisk, err := c.disksClient.Get(ctx, osDiskID.ResourceGroupName, osDiskID.Name, nil) if err != nil { logger.Warnf("Failed to get OS disk. DiskID=%v: %v", utils.StringPointerValOrEmpty(vm.Properties.StorageProfile.OSDisk.ManagedDisk.ID), err) From afa70373ecc0f7966f5c6b0bd76173f5e5e73162 Mon Sep 17 00:00:00 2001 From: Alexei Kravtsov Date: Thu, 27 Jul 2023 16:39:21 +0300 Subject: [PATCH 10/11] goimports --- runtime_scan/pkg/provider/azure/client.go | 1 + runtime_scan/pkg/provider/azure/client_test.go | 1 + 2 files changed, 2 insertions(+) diff --git a/runtime_scan/pkg/provider/azure/client.go b/runtime_scan/pkg/provider/azure/client.go index 694a87bc0..90b2088ec 100644 --- a/runtime_scan/pkg/provider/azure/client.go +++ b/runtime_scan/pkg/provider/azure/client.go @@ -26,6 +26,7 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v3" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources" + "github.com/openclarity/vmclarity/api/models" "github.com/openclarity/vmclarity/runtime_scan/pkg/provider" "github.com/openclarity/vmclarity/shared/pkg/log" diff --git a/runtime_scan/pkg/provider/azure/client_test.go b/runtime_scan/pkg/provider/azure/client_test.go index 38ea15b00..084662363 100644 --- a/runtime_scan/pkg/provider/azure/client_test.go +++ b/runtime_scan/pkg/provider/azure/client_test.go @@ -19,6 +19,7 @@ import ( "testing" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4" + "github.com/openclarity/vmclarity/api/models" "github.com/openclarity/vmclarity/shared/pkg/utils" ) From 846fd8354d88457d2382927417f3291ba30155f9 Mon Sep 17 00:00:00 2001 From: Alexei Kravtsov Date: Thu, 27 Jul 2023 19:10:01 +0300 Subject: [PATCH 11/11] rebase api gen --- api/server/server.gen.go | 656 ++++++--------------------------------- 1 file changed, 96 insertions(+), 560 deletions(-) diff --git a/api/server/server.gen.go b/api/server/server.gen.go index 9fadaac7c..7d48032c4 100644 --- a/api/server/server.gen.go +++ b/api/server/server.gen.go @@ -1067,566 +1067,102 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - "H4sIAAAAAAAC/+x9W3PbOLLwX0Hx26rZ3ZLtZL45D8dvjuxkVONbWU7mbG2mzkJkS8KEBDgAaFuTyn8/", - "BYCgwAt4kS3JzvjNFoHGpe+NbuBrELIkZRSoFMHx1yDFHCcggev/sBAgJ6fqT0KD4yDFchmMAooTCI6L", - "r6OAwx8Z4RAFx5JnMApEuIQEq25ylaqmQnJCF8G3byPTaxpi2g43bzEM9pzQiNCFF/L6+zC4ZJ5gGS4L", - "qEvAEfA13Mn84EI3aABDqIQFcA2HRVjiMcuoLED9kQFfrSH9LdRfG+DMGIsB0zWcs4cU08gLCMzn9oVp", - "QO9JLIF7Ac3N5x6ArngE/N3KC4mp77NVG6hR8HCwYAd5DwvQDjCFGEL/3gnzucdMp19I6gejPvbB5C3z", - "A5GsE4YIMR0zOid+gi01GUazoo3FxHDu+qYai5RRAVo2TLMwBKH/DBmVYGgap2lMQiwJo0e/C0bVb2uY", - "f+MwD46D/3e0FjpH5qs4yuHd5GOYESMQISepAhcc2yFRAkLgBSiy+Ei/UHZPzzhn/MmmcpKStmnkYyLQ", - "g5q91h0VXLfv8ddKzxOK2Ox3CCWSSywREYiDzDiFCBGKcByjEAsQiM3RHJM44yAOg1GQcpYCl8RsvF39", - "8deAA46uaLyy2KtTQf6LGVVt2IkSrvWZner/ZiAQpkgL4Hym9fGN2Kdz1rmNquGtmoAWzVzIKYBGw5zx", - "BMvgOIiwhANJEghGdUlAokYBEeOhgDjcEUEMBVT50DCKKIRyeVtumcQxolkyA66wotsa5C3xHSC4A454", - "RtGccSSXRJi9W0/CHSdLEsxXnXwQYvre6CkxzbsoRAJPCMUSoqveK/fif8ySpLQdle9nD0Tk9kAd9b3Q", - "rkA5hOojtvslCZcoo+SPDFDIqJAcEypRyJKZWi1hFIU4Uzwhl7rFPCaGKDel/RuINVyxNCrAyweIOy2R", - "ZGvOMLMOMUUzQEbPQvQCGaVjC8uM42m8dUbqMe72Gaub2NaK9N8KH7/5yE/NQhNHHF/Ng+N/b85iJUL+", - "NgrgIY0ZMWzb1vnMtNMTWdvM4pozpVwharI5vTSW4Pgec+ga88I0s2MmRITaqsm4WUJn/0oHC4iDYBkP", - "YaymmaVdYG7KzacSS+hWEJwx+aXHxt6YdnZuYsaSzj7TGUuKDjlpdBFxFfECQg7d05vqZsVgEstM9CI0", - "1WVqmj+a2+6ymALHMxITS/FtUD45zVdm6g2CvecabiFJY43xVu5sVX7THjha8/mzVYI1Mnr2Esmz0r+i", -======= -======= ->>>>>>> 88c0dce4 (add unknown state to encrypted volume) -<<<<<<< HEAD - "H4sIAAAAAAAC/+x9W3PbOLLwX0Hx26rZ3ZLtZL45D8dvjuxkVONbWU5ytjZTZyGyJWFCAhwAtK1N5b+f", -<<<<<<< HEAD - "AkBQ4AW8yJZkZ/1mi0Dj0vdGN/AtCFmSMgpUiuD4W5BijhOQwPV/WAiQk1P1J6HBcZBiuQxGAcUJBMfF", - "11HA4c+McIiCY8kzGAUiXEKCVTe5SlVTITmhi+D795HpNQ0xbYebtxgGe05oROjCC3n9fRhcMk+wDJcF", - "1CXgCPga7mR+cKEbNIAhVMICuIbDIizxmGVUFqD+zICv1pD+EuqvDXBmjMWA6RrO2UOKaeQFBOZz+8I0", - "oPcklsC9gObmcw9AVzwC/m7lhcTU99mqDdQoeDhYsIO8hwVoB5hCDKF/74T53GOm068k9YNRH/tg8pb5", - "gUjWCUOEmI4ZnRM/wZaaDKNZ0cZiYjh3fVeNRcqoAC0bplkYgtB/hoxKMDSN0zQmIZaE0aM/BKPqtzXM", - "v3CYB8fB/ztaC50j81Uc5fBu8jHMiBGIkJNUgQuO7ZAoASHwAhRZfKRfKbunZ5wz/mRTOUlJ2zTyMRHo", - "Qc1e644Krtv3+Ful5wlFbPYHhBLJJZaICMRBZpxChAhFOI5RiAUIxOZojkmccRCHwShIOUuBS2I23q7+", - "+FvAAUdXNF5Z7NWpIP/FjKo27EQJ1/rMTvV/MxAIU6QFcD7T+vhG7NM569xG1fBWTUCLZi7kFECjYc54", - "gmVwHERYwoEkCQSjuiQgUaOAiPFQQBzuiCCGAqp8aBhFFEK5vC23TOIY0SyZAVdY0W0N8pb4DhDcAUc8", - "o2jOOJJLIszerSfhjpMlCearTj4IMX1v9JSY5l0UIoEnhGIJ0VXvlXvxP2ZJUtqOyvezByJye6CO+l5o", - "V6AcQvUR2/2ShEuUUfJnBihkVEiOCZUoZMlMrZYwikKcKZ6QS91iHhNDlJvS/g3EGq5YGhXg5QPEnZZI", - "sjVnmFmHmKIZIKNnIXqBjNKxhWXG8TTeOiP1GHf7jNVNbGtF+k+Fj9995KdmoYkjjq/mwfE/N2exEiF/", - "HwXwkMaMGLZt63xm2umJrG1mcc2ZUq4QNdmcXhpLcHyPOXSNeWGa2TETIkJt1WTcLKGzf6WDBcRBsIyH", - "MFbTzNIuMDfl5lOJJXQrCM6Y/NpjY29MOzs3MWNJZ5/pjCVFh5w0uoi4ingBIYfu6U11s2IwiWUmehGa", - "6jI1zR/NbXdZTIHjGYmJpfg2KJ+c5isz9QbB3nMNt5CkscZ4K3e2Kr9pDxyt+fzZKsEaGT17ieRZ6X+i", ->>>>>>> 43449322 (review) - "hOrWiK8S65lJrG7rYKAMu7E00C7LDP3URJn2XPVfRIJBeY1vaBbHeBZDhcow53hlrctbjqkgCrO3yk7q", - "bbAKOy2gWaL25JLp6VKIglFwDRoJwSiYhkuIslj/qla8umV6S0fBhF5ztuAgRDAKTmaMS93olFFwdreX", - "HJwWdFXZpJ7Sq7LZ30bBAhQJxMM79pRVDR2Hiqs6iL4yo95TiY0NevWTAfWOAxmyCqCVFgoToUYNStS9", - "xwmJCQgTkeslT8o9cpFJgU+okJiGMOagEdYfpL9zfWl5NFX9aEOqDdZQw/oL8fJ97IO7xAZOD9t8VuPy", - "G39VN0Q4DBlXEgpJpi2yBbkDikycXPRyWQuxWx7xnAipvGN3zPbREKYRSvECDpHuHANdyCVKMiHRDFDM", -<<<<<<< HEAD - "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", - "b9/+LwAA//+wNhfM78IAAA==", -======= - "7pW/zRH8meFYQVBtp+TfoKzHYha9rVnPynKl4N13HdtQpiRd5SZmqwq90EGTLp14zaJe7U4JN+1+HwUR", - "Udut/X0TL05wmioVcfwtsO06wIwCO3DHvEZBvpCuZVpqXF0aFjWbZ+NBzTu6ERU3EPDWqFcgQvdGrpuR", - "6jhmWXTN2R2JzHGYtU5OPk+VlfHvjCtr5sP4OhgFZw8SOMVxg7UxWpNSFUcR4QbJTeE6Zg4rGj86NNF4", - "2uMamE7bJuMw97YaCOgOzIFRbfQSnptsRd+ajDNz+q7xoyQybu6W8fhR1ul3/7JzC9+iZ+309nBQtagp", - "79mT4aUFUzbm4DdPe3HGehGb756j8iuzoQqeJ3aY6/oOlHZPIsfdY84lqp7ovEIOvRTUNQ6/4gW4pNSl", - "hEpu4ZCOeVxiSBfjNg8apOI+DOmbxxCGdGlgxS7lXAit3hBHwYX1pnrv7Cio7sQmOzYKcgIZQD+jIN/H", - "Ads8Cgym+9PBKCjR4QbE2marKHZiGY3erXrblDV2VP3NOUzZtvi8BGrOhXKORfdYIEUx7A44RGi2Qlhb", - "zMHocadmhN7hmETrA6E+E3E6mZlQUJbMgPm0yDtfQHq+Fodtm22l5nMMRtt420Br1kaI+zpkg03YYoBO", - "0L1Ur4OCbi13sQ4CVRI/zAevAZl/t8ZID61ifQydHFTbjGssl2oz1LLnJAZzXBsyKjGhAtlgVS9E5wPu", - "1XxoEPi9LUCLlB1bgO6phI8eehuA6zV0BncTkDjCEveGnUdkLmy/jYzMizIB11BcV87f/LlRDckMCUTE", - "72IZMouuc17wfPf7bwLugGutOvCkyPbTyQhCjrGEBTPnFXUqByFPO7wx1abRkWvc8xZDpj93VBGzazZp", - "OnyrE0dTkLwf59TX18lC/aTWBkziIx8nYFFt8ytZLIt2dRAXEJEsaWlwzu6Lr03xjmr7/bqJhfVdsylS", - "ePShF11kPgETkxBsduzmQ3hjKWnG45YdafhwB1w0C4mWbdtIANgt3zHfF5HY6qibx9JGQcoij4wfFmdr", - "PMp3mNQ55vxK0lSfX77HJG47yHTcxEGqz3Tyqq78ex/L8cZp2khGDY5qbzKyi9sxGblpELV9dc9FeymL", - "9SI2kO43ZUwUAv3s4urmH8Eo+O3s5vLsPBgFJ9fX55Pxye3k6lLRzeTm4vPJzVkwCj5e/nZ59fmyjXj2", - "K55vMqpcYHu2Py1KHDSdRJHOJ8DxtTOzOY4FVNPwczhI5IC0t41KeugQTeaI0XiFFCxsExUQEUiAHCEi", - "0T2JYzQDhJEgdGGhWJhRno8KZQBruCFn9JzQNUjtFGecA5VIT88OoD58CeacJfr3L4HyKIXEXOpP+YjK", - "06z5nHYQPeyMKa+stBxMo/VEMIf1THQysVmSngfPKMKyoXttiaV5GzB6OdoHdCdVNIT5HEJJ7gCpRR4G", - "oyAh1MXi22qCtAVRdz3HnK2RgOAh5SCUKtPlEPCAk1QxVfBf6Bf0d/R39LYpvlNaTkMkYQmIwkOxLCLQ", - "mhSRWLIsjpDkZLEAnoeWDh8Ry5m+u7rwsR2mOF79eyBrjdq4tXEGNnGrNn5qtHd/EbdW9xuIuF4Z0JPT", - "zuPxyalQDDIzLGtShzY3u4BGw3KYPOFDr/nWXYTSP/fBtKxl1SlhsmEiVp03YjKHcBUqiagamUCQknI5", - "I9TNmNMiGutP0Oo2cPRoF75A5a9ZgukBBxwpZNpKMKSMDWXx0QWKQGISC4RnLDOSKsZKBupFyCJh7dC7", - "HTeA82qx8tAXOFwSCsXgI/QxTYGPcQLxGAtAUkkTZyZqbK6BFVokZNTot5+EmVZ5QsWBc7FfCp3RVSaD", - "UXBF4YpfMA46em42ssiHs3u/Kjb4I4WHFEID5pLJJaGLorkt3mtEQP90ySJNcnBSdi0f21+Gk2SxJAc2", - "JcbqZUuGjeJlzUmbgM1tiHpBT0REIXHLgMkcabGSq/IChjILbC+tZynLDQyjX3TFizIJiFMz1p3T/Agh", - "42a49UeQKXE0qZhd5q/XvPNqA/Pdd8yx10OLzSRz11IfUYNWoq6ehWjbptuNc/MtHW+hEG3PdN6jHGzd", - "Y+jxl4uoXaUkOmPuPyfR3exNMr3aynyegbjps3z/wurZuXXjruQl2zO+3MFH8xwAuifKaijLnJpwGVjk", - "46QAD6vMcfo9tjbHmcPAShk3gblH1rvj9A2tenFGekQFipNy7SWXSslL/dIClFuELp0UJ+R1bSOVjDpz", - "qKIua3QT55zb16IJ0Z62144P62ly4+Da02S6RpGnxadHlgO1mczB4LK8rbvJ7bLVuc2nr75trD/ocr47", - "pebu7YtHO+shSz2et75KBmUCIoW4mCTEhghZWvHD0USqhuILVQ2uTk9uT1B+YU8Oxp5YlUGFLI4htMLf", - "JGwrGDq2lwM3gT0TRQOknMtD9F6pbRN++0L/pQMOQmmJvxZ3HRzao5cR+gmyg3sQ8uDnn/72LwPNziAf", - "4guVDP2h7IJyznjREZ18niIOC+Uff6Eel70j6NGtcvceBOk3xd0ERfrN5T8sSNK9KZsFTR5bF+otCW25", - "3cf4iZpSqt6lAoeK2rFG9eSYCf3O9JrLaqva7A82E2Om5IosRbQdqauanMNc3rKbjHqu1Kof9nXYMmnO", - "n1oM5pYN44hQI0r0SRRKM54yAeLQboK/TPBp9GGCH64xx3EM8dQ5davLpwQ/kCRLnItV3NIxk69nogPr", - "EBehKM2Br29byTNVc3jB8c9v9PGN+edtsxJ8VWBPocCUlmKZnIISex1o1kdVhCJhGhsE52Sr1wKRCcvo", - "CRrb+Qt1YzaMoxnMGQc0A33WmEmm6DzEcbxS6kHBMDMt0P9m1IPVyozhrx99ZZBXBmllkE5V+yIYpsuJ", - "8DJQJfFj+u7qIhgFnz6eX57dnLybnE9u/xGMgouT8zzdY3o2vjm7VT9NpuOry/eTDx9vbFbIzdXV7W8T", - "9fHsf67Prya3jec9065K7MrRfDV0ZMNGJAdQv7AQP1xzEvpOLCRfXeCHEykhSX2udyZgmjJp5yg8Z96u", - "OVXr4ovBumnLjeXurUm/5vu0v/nntPZSQRlieUanWGIlXhunoz7aizSavp/RBaHwyZsXqFyWubaH35PY", - "F0z5jbJ7+onwTPha5FM4JRxCyTjpaNcy1jQTadd8lPl/i79C30THTW4B2G39//Oo/N+86N/WpdXKnzsy", - "14FGYxZnief8Emhk04XqH+ckhuvGOhbFvKU6lryExbqfJi7bZJvNCV0ATzlpIoxLJuHYKA4iEGUyPxHw", - "RinalqYb+Bbn3+KNsixz7Ow4ydK5zKkuZddh136UaVewSfpRKby+nxTIKYQZJ3L1gTNzJdiAtMf8ciEU", - "xiyLFO1qSGihQVVVr4mLJoSea+ngWqrD7q6s3s488Grj4lpjkV/hrBuZFpp3loQunvqq41u8eNTeSrxA", - "RyjGM4hrM/sKzfU5dzjOenCP6m4bN223vTmkSp0k8aV4W+vLc4OD/exeb9HGYeW7MBwA3rT5GGc0XA5L", - "P3tUmn6MpRrFU4vlMNggueLwZY+sQYkX/aEreuwjsjxitoRjZ+8quBnlROLsUAk5jeTWeGS4H9lYqVCv", - "X1Ii+u94CdZY9eyB0y4jJSJCcjZo6FPTRVsUD4N6vicPhrlWwCeea54J/frImqN0XTHVM+039VZJ9qyC", - "LB+MOiWQ7mn3yl+I004345xKqupEchIOp5qLvJ8uqQrzyykeWW3lHaQ26xkWMA1Z6aTchLOcO1aLE2Zf", - "O5KkOJS+750zPC2IvnKyoH9HqdEUwg2c54dNGEUgtQuHzgnNHpDmHzLL7HlOebWT03PytcG+UIb65PR/", - "zye/naE5gThC+q4Im6OiPh+BDI+YOOAQAxbG1n9UTrg9Pva7E/UVNak5hzLKoHJH3A8N/TXBfzDtx+k/", - "DhNCGUc5wL/1Kz3wXufR22Moy+QdOw41eVh3H+wBrm/nn7wIt37La21SDVk7w3XWE82uX27POkZemXvO", - "ailwZMW7J+1nzIkOjTZkyXjyaX4li2X/1ufsvn9jU9bcv/0lLGKyILMYevTp3veGuuzxzeR2Mj45D0bB", - "r5MPvwaj4OLsdPLxIhgF51efg1FwefbhfPJh8u78rOkWW22GG77N704LPl2MY6wdwJPriQgcWRO8PXxz", - "+CYvhKI4JcFx8P8P3xy+DYz21qs6wqVrMRcmaFNUTimLI/gA0rk8c1R6IswjN9ZNjtwXpnyn2dXm+TNP", - "fZubJyf6tr5laf+JfCX9G+fvcfVtXrxt9XvlYaWf37x5upeM1ojzv6dkjN45zmLvHWrFBI9KDy59dzMf", - "FKEMuLnUlFqLBoK7ZqJMcUp9gJDvWLR6+p2xT1u572B9r6Hk7bYGrshj+1HfKhVywBIinXbwy1NSRfv7", - "VhNzmZWDSyQyNVgxlf9++t3I07EbpjPO06f16dt6SlonHT4V7epTL1g/8VNkgmAkUgjJnEBUPEnzcBCy", - "CBZAD3LKPJixaGVvWFZ/a+iOcD365jxq+L2fqD0pPYM4TOq6TyhuSepacbcT8dUhvX5588uumGPNoZNT", - "HfTXdPikItSlwcPc2TaPT1bkpPp5L/Ri38M0yN+7cN4RwX1MzQV/ZSGRR7TnWRyvnp+kfgZ88dzUxS9v", - "f97VppxJvEARiehPEmmOeTJ9pXm/TIk9FdMoSLMmoyuTr6LkVZS8ipL/OFFiaLFqdgy0crvDB6+hgxcY", - "Othp2KBPSGCr4YC9hAIaJSCicG8fm302gYCtxgD8Ulh/RjjmgKMVAt3uyf3+TTx769XnHn0EMZhjiDLt", - "nurfDfWemPabGVXKoPJwfPv6S57y86Ce3RoTW/HVDV7N8g7Ns29t6u/RqH/hYZxnFsLZXvimoIfOsM0u", - "aGIn/tVefKtWvyqXOTV/as9E9hzU5g/ltBhme5LIxys37pwbX22RV5mwX5mgjPm58wiNz4YrHqp5DWK8", - "pCBGgbYdhTHi2LkYqTWa4RDUNhRB8eLQbiMapWGbYhruo1l7jmrYqWwtrlF+vqthJnkD54K4J45q2DVu", - "IAyPvtmnEftENyw12+zS4UZUMdpTxDh2ptEtBrcZX7BIbI0xPCkCXm6koUX+/HgEojSOXEJxuZNJV3Kp", - "pS0C8fQsu2ctthMq0lsHrvLYv1PjUWQ/BI3neQ5rqn6sq/9K9puQvfXkX8l+N2RvXdmhdK8sOFG+V9pn", - "MbjXT786tS/JqXUxtzu/1r0AvMO3LZPWNiRk6bb1nXq41ZGbnNzSFf37d3Td6WzN2a2949BEmc5Etnye", - "X7myfAPZefRt/U8vH9ih+qnTc7BwdYd9Uc6wi96tOsSlR1panOLtYOTlesftsuvHJJpmJ7lKQW2O8r6o", - "aNtnhUN16K7o0LrYZbW1f3+jRY0+C255Ztr8RyqzqD4L9rgQxKtA2a1AscGLV4HyKlCeS47CJhLFOiid", - "YZ3XgM7LC+jsOpQjDtEZDpcFHUpMqKi8E9L+9mZnCGibwZ99hH06Aj7PJdKz1RBPh/TedlTHT49DZagJ", - "7/QO7IgNq2FFXgj70sI4W4/fdAZuHrvjLztM88wCNLuLzJg7grr0Tke4Zvu0swtfah9eVGdA5tk4Tnv1", - "mLbtKg1Xsz9cuOVp4iyvkuApJUEpkvIqCV4lwW7iJL0DJPr+aX5neTzjcXAcHOGUBN9///5/AQAA//8u", - "rNGP674AAA==", -======= - "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", - "4Dg4wikJvv/+/f8CAAD//6CoSp9YvwAA", ->>>>>>> 4fcf9896 (extend asset vm info with root volume details of encryption and size) -======= -======= ->>>>>>> f6bb1ac3 (gen api) - "H4sIAAAAAAAC/+x9W3PbOLLwX0Hx26rZ3aLtZL45D8dvjuxkVONbWU7mbG2mzkJkS8KEAjgAaFuTyn8/", - "BYCgwAt4kS3JzvjNFhuNW9/RDXwNIrZMGQUqRXD8NUgxx0uQwPV/WAiQ41P1J6HBcZBiuQjCgOIlBMfF", - "1zDg8EdGOMTBseQZhIGIFrDEqplcpQpUSE7oPPj2LTStJhGm7XhziGG4Z4TGhM69mNffh+ElsyWW0aLA", - "ugAcA1/jHc8OLjRAAxpCJcyBazwsxhKPWEZlgeqPDPhqjelvkf7agGfKWAKYrvGcPaSYxl5EYD63T0wj", - "ek8SCdyLaGY+90B0xWPg71ZeTEx9n67aUIXBw8GcHeQtLELbwQQSiPxrJ8znHiOdfCGpH4362Gcnb5kf", - "iWSdOESE6YjRGfETbAlkGM2KNhYTw7nrmwIWKaMCtGyYZFEEQv8ZMSrB0DRO04REWBJGj34XjKrf1jj/", - "xmEWHAf/72gtdI7MV3GU47vJ+zA9xiAiTlKFLji2XaIlCIHnoMjiI/1C2T0945zxJxvKSUrahpH3iUB3", - "atZaN1R43bbHXystTyhi098hkkgusEREIA4y4xRiRCjCSYIiLEAgNkMzTJKMgzgMwiDlLAUuiVl4O/vj", - "rwEHHF/RZGV3r04F+S+mV7VgJ0q41kd2qv+bgkCYIi2A85HW+zdin85Y5zIqwFs1AC2auZATAL0NM8aX", - "WAbHQYwlHEiyhCCsSwISNwqIBA9FxOGOCGIooMqHhlFEIZTLy3LLJE4QzZZT4GpXNKzZvAW+AwR3wBHP", - "KJoxjuSCCLN260G4/WTLJearTj6IMH1v9JSY5E3URgJfEoolxFe9Z+7d/xFbLkvLUfl+9kBEbg/Ut77X", - "titUDqH6iO1+QaIFyij5IwMUMSokx4RKFLHlVM2WMIoinCmekAsNMUuIIcpNaf8GEo1XLIwK8PIB4g4k", - "kmzNGWbUEaZoCsjoWYhfIKN0LGGZcTzAW2ekHv1un7G6iW2tSP+t9uM3H/mpUWjiSJKrWXD8781ZrETI", - "38IAHtKEEcO2bY3PDJweyNpmFtecKeUKcZPN6aWxJU7uMYeuPi8MmO1zSUSkrZqMmyl0tq80sIg4CJbx", - "CEZqmFnaheamDD6RWEK3guCMyS89FvbGwNmxiSlbdraZTNmyaJCTRhcRVzdeQMShe3gTDVZ0JrHMRC9C", - "U00mBvzR3HaXJRQ4npKEWIpvw/LJAV+ZoTcI9p5zuIVlmugdb+XOVuU36bFHaz5/tkqwRkbPXiJ5ZvpX", - "lFDdGvFVYj0zidVtHQyUYTeWBtplmaGfmijTnqv+i0gwW17jG5olCZ4mUKEyzDleWevylmMqiNrZW2Un", - "9TZYhR0W0Gyp1uSS6eFSiIMwuAa9CUEYTKIFxFmif1UzXt0yvaRhMKbXnM05CBGEwcmUcamBThkFZ3V7", - "ycFJQVeVReopvSqL/S0M5qBIIBnesKesamg4VFzVUfSVGfWWSmxs0KqfDKg3HMiQVQSttFCYCDVqUKLu", - "PV6ShIAwEble8qTcIheZFPiYColpBCMOesP6o/Q3rk8tj6aqH21ItcEaaph/IV6+j3Vwp9jA6VGbz2pc", - "fuOvakCEo4hxJaGQZNoim5M7oMjEyUUvl7UQu+Uez4mQyjt2+2zvDWEaoxTP4RDpxgnQuVygZSYkmgJK", - "2L3ytzmCPzKcKAwKdkL+BGU9FqPobc16ZpYrBe+669iGMiXpKjcxW1XohQ6adOnEaxb3gjsl3MD9FgYx", - "Ucut/X0TL17iNFUq4vhrYOE60ISB7bhjXGGQT6RrmpYaV5eGRc3i2XhQ84puRMUNBLw16hWI0L2R62ak", -<<<<<<< HEAD - "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", - "/r8AAA==", ->>>>>>> 6a36bd20 (review) -<<<<<<< HEAD ->>>>>>> 43449322 (review) -======= -======= - "H4sIAAAAAAAC/+x9W3PbOLLwX0Hx26rZ3ZLtZL45D8dvjuxkVONbWU7mbG2mzkJkS8KEBDgAaFuTyn8/", - "BYCgwAt4kS3JzvjNFhuNW9/RDXwNQpakjAKVIjj+GqSY4wQkcP0fFgLk5FT9SWhwHKRYLoNRQHECwXHx", - "dRRw+CMjHKLgWPIMRoEIl5Bg1UyuUgUqJCd0EXz7NjKtpiGm7XhziGG454RGhC68mNffh+El8wTLcFlg", - "XQKOgK/xTuYHFxqgAQ2hEhbANR4WYYnHLKOyQPVHBny1xvS3UH9twDNjLAZM13jOHlJMIy8iMJ/bJ6YR", - "vSexBO5FNDefeyC64hHwdysvJqa+z1ZtqEbBw8GCHeQtLELbwRRiCP1rJ8znHiOdfiGpH4362Gcnb5kf", - "iWSdOESI6ZjROfETbAlkGM2KNhYTw7nrmwIWKaMCtGyYZmEIQv8ZMirB0DRO05iEWBJGj34XjKrf1jj/", - "xmEeHAf/72gtdI7MV3GU47vJ+zA9RiBCTlKFLji2XaIEhMALUGTxkX6h7J6ecc74kw3lJCVtw8j7RKA7", - "NWutGyq8btvjr5WWJxSx2e8QSiSXWCIiEAeZcQoRIhThOEYhFiAQm6M5JnHGQRwGoyDlLAUuiVl4O/vj", - "rwEHHF3ReGV3r04F+S+mV7VgJ0q41kd2qv+bgUCYIi2A85HW+zdin85Z5zIqwFs1AC2auZBTAL0Nc8YT", - "LIPjIMISDiRJIBjVJQGJGgVEjIci4nBHBDEUUOVDwyiiEMrlZbllEseIZskMuNoVDWs2b4nvAMEdcMQz", - "iuaMI7kkwqzdehBuP1mSYL7q5IMQ0/dGT4lp3kRtJPCEUCwhuuo9c+/+j1mSlJaj8v3sgYjcHqhvfa9t", - "V6gcQvUR2/2ShEuUUfJHBihkVEiOCZUoZMlMzZYwikKcKZ6QSw0xj4khyk1p/wZijVcsjQrw8gHiDiSS", - "bM0ZZtQhpmgGyOhZiF4go3QsYZlxPMBbZ6Qe/W6fsbqJba1I/6324zcf+alRaOKI46t5cPzvzVmsRMjf", - "RgE8pDEjhm3bGp8ZOD2Qtc0srjlTyhWiJpvTS2MJju8xh64+LwyY7TMhItRWTcbNFDrbVxpYRBwEy3gI", - "YzXMLO1Cc1MGn0osoVtBcMbklx4Le2Pg7NjEjCWdbaYzlhQNctLoIuLqxgsIOXQPb6rBis4klpnoRWiq", - "ydSAP5rb7rKYAsczEhNL8W1YPjngKzP0BsHecw63kKSx3vFW7mxVftMee7Tm82erBGtk9Owlkmemf0UJ", - "1a0RXyXWM5NY3dbBQBl2Y2mgXZYZ+qmJMu256r+IBLPlNb6hWRzjWQwVKsOc45W1Lm85poKonb1VdlJv", - "g1XYYQHNErUml0wPl0IUjIJr0JsQjIJpuIQoi/WvasarW6aXdBRM6DVnCw5CBKPgZMa41ECnjIKzur3k", - "4LSgq8oi9ZRelcX+NgoWoEggHt6wp6xqaDhUXNVR9JUZ9ZZKbGzQqp8MqDccyJBVBK20UJgINWpQou49", - "TkhMQJiIXC95Um6Ri0wKfEKFxDSEMQe9Yf1R+hvXp5ZHU9WPNqTaYA01zL8QL9/HOrhTbOD0sM1nNS6/", - "8Vc1IMJhyLiSUEgybZEtyB1QZOLkopfLWojdco/nREjlHbt9tveGMI1QihdwiHTjGOhCLlGSCYlmgGJ2", - "r/xtjuCPDMcKg4Kdkj9BWY/FKHpbs56Z5UrBu+46tqFMSbrKTcxWFXqhgyZdOvGaRb3gTgk3cL+Ngoio", - "5db+vokXJzhNlYo4/hpYuA40o8B23DGuUZBPpGualhpXl4ZFzeLZeFDzim5ExQ0EvDXqFYjQvZHrZqQ6", - "jlkWXXN2RyJzHGatk5Nfp8rK+DPjypr5ML5uMDFGa/qpbkxEuNnZphgdMycUjR8dQmg84nGtSge2ySLM", - "XawGqrkDc0pU6720uU0Gom9OxoM5fdf4URIZNzfLePwok/Sbf9q5WW+3Z+3p9vBKtXwpr9mT7UvLTtlA", - "g98m7cUO60lsvnqOnq+Mhip8noBhruA7trR7EPnePeYwoup+zivk0EsrXePwC16AS0pdmqfkCw5pmAcj", - "hjQxvvKgTio+w5C2eeBgSJMGVuzSyIXQ6o1xFFxYF6r3yo6C6kpssmKjICeQAfQzCvJ1HLDMo8DsdH86", - "GAUlOtyAWNsMFMVOLKPRu1VvQ7LGjqq9OXwpGxS/LoGaw6CcY9E9FkhRDLsDDhGarRDWZnIwetxRGaF3", - "OCbR+hSoz0CcRmYkFJT5MmA8LfLOF4Wer8Vh22JbqfkcI9A2yDbQhLVh4b5e2GC7teigE3Uv1etsQbeW", - "u1hHfirZHuaD14DMv1tjpIdWsY6FzgiqLcY1lku1GGracxKDOaMNGZWYUIFshKrXRucd7tV8aBD4vS1A", - "uyk7tgDdowgfPfQ2ANdz6IzoJiBxhCXujTsPw1zYdhsZmRdlAq5tcV05f/UnRDVkMCQQEb+LZcgsus55", - "wfPd778JuAOuterA4yHbTmcgCDnGEhbMHFLUqRyEPO3wxhRMoyPXuOYthkx/7qhuzK7ZpOnErU4cTZHx", - "fpxTn18nC/WTWhswiY98nChFFeZnslgWcHUUFxCRLGkBOGf3xdemeEcVfr9uYmF912yKFB590kUXmU/A", - "xCQEmxK7eRfeWEqa8bhlRRo+3AEXzUKiZdk2EgB2yXfM90X4tdrr5rG0UZCyyCPjh8XZGs/vHSZ1zja/", - "kDTVh5bvMYnbTi+Nm/iJxZkZII4ifeaK42tn/nMcC6imKquFUm6IMuDxjGUSfbpAnDGJ7gy6UY1XQ75K", - "peFWO+h/gTJ6L5Urmec+N45SkD/hwztPsru7hjngyOmtcS2tczxI4ZtGXoWdf+9jL984oI3M0+Ce92Ye", - "O7kdM4+b8VFbV/cIuJeKXE9iA512U96JQo2dXVzd/CsYBb+c3VyenQej4OT6+nwyPrmdXF0qbpncXPx6", - "cnOmiPHyl8urXy+9LPNl37HLm4wqx9+mMUyLao6BbJzjQSJHpGMMqKR9D9FkjhiNV0jhwjYnAxGBBMgR", - "IhLdkzhGM0AYCUIXFovFGeWpt1BGsMYbckbPCV2j1KGAjHOgEunh2Q7Uh8/BnLNE//45UH60kJhL/Snv", - "UfnXNU/bdqK7nTHli5amg2m0HgjmsB6Jzps2U9Lj4BlFWDY0r02xNG6DRk9He77uoApAmM8hlOQOkJrk", - "YTAKEkLdXXxblasWRd3hHnO23gQEDykHoRS4rvyAB5ykiqmC/0I/oX+if6K3TVGt0nQa4idLQBQeimkR", - "gdakiMSSZXGEJCeLBfA8oHb4iAjW9N3VhY/tMMXx6s+BrDVq49bGEdgctVr/qbFZ+ou4tZGzgYjrlew9", - "Oe3MBJicCsUgM8OyJktqc2MTaDQsXcsTNPUard31Nv3TPAxkLYFQCZMNc87qvBGTOYSrUElEBWTCX0rK", - "5YxQN95Oixi0Pxet26zTvV34wrM/ZwmmBxxwpDbTFr0hZWwoO5cuUAQSk1jklp2SVDFWMlBPQha5eYfe", - "5bgBnBfGlbu+wOGSUCg6H6GPaQp8jBOIx1gAkkqaOCNRfXONrNAiIaNGv/0gzLDKAyrO1ov1UtsZXWUy", - "GAVXFK74BeOgzwzMQhapf3btV8UCf6TwkEJo0FwyuSR0UYDbOsXGDeifGVpkhA7OP6+lnvsrjpIsluTA", - "Zv9YvWzJsFG8rDlpE7S5DVGvXYqIKCRuGTGZIy1WclVe4FBmgW2l9SxluYFh9Isu7lEmAXHK47rTtx8h", - "ZNxkvv4bZKo5TdZpl/nrNe+82sB89x3u7PWoZjPJ3DXVR5TblairZ83dtul24zIES8dbqLnbM533qHxb", - "txh66Odu1K6yL50+959+6S72JkltbRVNz0Dc9Jm+f2L1ROS6cVfyku3JZu7go3mOAN0TZTWUZU49ODas", - "nsnJdh5WhOS0e2wZkjOGgUVBbq52jwR/x+kbWuDj9PSIYhsnu9xLLpXqnvr9DCi3CF06KfIC6tpGKhl1", - "5lBFXdZoEOd03wfRtNEe2GvHh/WA3Dh77QGZrrfIA/HpkZVPbSZzMLgCcetucrtsdS4u6qtvG0stupzv", - "Tqm5e/vi0c56yFKP561vzUGZgEhtXEwSYkOELK344WgiFaD4TBXA1enJ7QnK7ybK0dhzujKqkMUxhFb4", - "m9x0hUPH9nLkJrBnomiAlHN5iN4rtW3Cb5/pf3TAQSgt8ffiWodDe+A0Qj9AdnAPQh78+MM//mOw2RHk", - "XXymkqHflV1QTo8vGqKTX6eIw0L5x5+px2XvCHp0q9y9B0H6DXE3QZF+Y/mLBUm6F2WzoMljS2C91a8t", - "FxkZP1FTStW7VOhQUSbXqJ4cM6HfmV5zBXFVm/3OZmLMlFyRpYi2I3UVyDnM5S27yajnQLV+2Ndhy6Q5", - "f2oxmFs2jCOyPiLGMUoznjIB4tAugr8i8mn0YYIfrjHHcQzx1Dl1q8unBD+QJEucO2TcKjmTpWiiA+sQ", - "F6EozZGvL5bJ83NzfMHxj2/08Y35522zEnxVYE+hwJSWYpmcghJ7Hdusj6oIRcIAmw3OyVbPBSITltED", - "NLbzZ+rGbBhHM5gzDmgG+qwxk0zReYjjeKXUg8JhRlps/5tRD1YrM4a/VPaVQV4ZpJVBOlXti2CYLifC", - "y0CVxI/pu6uLYBR8+nh+eXZz8m5yPrn9VzAKLk7O83SP6dn45uxW/TSZjq8u308+fLyxWSE3V1e3v0zU", - "x7P/uT6/mtw2nvdMu4rOK0fz1dCRDRuRHEH9bkb8cM1J6DuxkHx1gR9OpIQk9bnemYBpyqQdo/Ccebvm", - "VK2JLwbrJms3Vva3pjqb79P+5p8D7aWCMsbyiE6xxEq8Ng5HfbR3hjR9P6MLQuGTNxtSuSxzbQ+/J7Ev", - "mPILZff0E+GZ8EHkQzglHELJOOmAa+lrmom0azzK/L/FX6BveucmFx7s9qqD53HJweb3G9hqvFrRd0e+", - "PtBozOIs8ZxfAo1sulD945zEcN1YvaOYt1S9kxfuWPfTxGWbbLM5oQvgKSdNhHHJJBwbxUEEokzmJwLe", - "KEXb1DSAb3L+Jd4oyzLfnR0nWTr3VtWl7Drs2o8y7Qw2ST8qhdf3kwI5hTDjRK4+cGZuPxuQ9pjfo4TC", - "mGWRol2NCS00qqrqNXHRhNBzLR1cS3XYNZ3Vi6gH3uJc3OAs8tuqNZCB0LyzJHTx1Lc63+LFo9ZW4gU6", - "QjGeQVwb2Rdorkq6w3HWg3tUcwvctNz2kpQqdZLEl+JtrS/PvRX2s3uTRxuHla/9cBB4iwVinNFwOSz9", - "7FHFCTGWqhdvQvu6NqDrYC+HNEd0a8YcJI8cfu6RbSjxoj92Rcd9RJ1HPJdow1nzyp6OcuJyVra0qaVF", - "baTZxnPH/QjYSnF//X4X0X/5S7jGqmWPDe6ydCIiJGeDuj41TbRZ8jCo5XvyYDh0BXziuRab0C+PLNdK", - "18VmPXOHU2+Bac8C0vLpqlM96h6Zr/w1TO10M86ppKqTJCfhcKq5yNvparQwv9fjkYVq3k5qo55hAdOQ", - "lY7bTUzMuZO2OKb2wZEkxaH0fe8c4WlB9JXjCf07So26EW70PT+xwigCqf1AdE5o9oA0/5BZZg+FyrOd", - "nJ6TLw1GirL2J6f/ez755QzNCcQR0tds2EQX9fkIZHjExAGHGLAwDsOjEsvtGbTfJ6nPqElXOpRRRpV7", - "835s6O8J/p1pZ1D/cZgQyjjKEf6jX/2C9yaU3m5HWSbv2PuoycO6D2JPgX0r/+T1y/VbcWuDakj9Ga6z", - "nmh0/RKE1oH2ythzVkuBIyvePblDY050fLUh1caTlPMzWSz7Q5+z+/7ApiK8P/wlLGKyILMYerTpXveG", - "kvbxzeR2Mj45D0bBz5MPPwej4OLsdPLxIhgF51e/BqPg8uzD+eTD5N35WdOtv9qWN3ybXzsXfLoYx1h7", - "kSfXExE4siZ4e/jm8E1eTUVxSoLj4P8fvjl8GxjtrWd1hEvXiC5M5Kcov1IWR/ABpHPZ6Kj0pJpHbqxB", - "jtwXuXxH4lXw/FmsvuDmiY6+0Lcs7T+QL6Q/cP5+WV/w4i2w3yoPUf345s3Tvfy03jj/+1PG6J3jLPZe", - "P1cM8Kj0QNU3N31CEcqAm15NlbpoILhrJsoUp9QHCPmORaunXxn7FJj7bti32pa83VbHFXlsP+oLuUIO", - "WEKkcxd+ekqqaH8PbGLuAXP2EolMdVYM5b+ffjXynO6G4YzzHGx9hLcektZJh09Fu/roDNZPIhXpJBiJ", - "FEIyJxAVT/g8HIQsggXQg5wyD2YsWtkbqdXfGrsjXI++Oo9Afusnak9Kz0YOk7ruk5NbkrpW3O1EfHVI", - "r5/e/LQr5lhz6ORUnxxoOnxSEerS4GHubJvHOityUv28F3qx74eazd+7cN4RwX1Mzd2IZSGRh8XnWRyv", - "np+kfgZ88dzUxU9vf9zVopxJvEARiegPEmmOeTJ9pXm/TIk9FdMoSLMmoyuTr6LkVZS8ipK/nCgxtFg1", - "OwZaud3hg9fQwQsMHew0bNAnJLDVcMBeQgGNEhBRuLeP8z6bQMBWYwB+Kaw/IxxzwNEKgYZ7cr9/E8/e", - "evW5Rx9BDOYYoky7p/p3Q70nBn4zo0oZVB6Ob59/yVN+HtSzW2NiK7662VczvUPzTF6b+nv01r/wMM4z", - "C+FsL3xT0ENn2GYXNLET/2ovvlWrX5XLnJo/tWciew5q87tyWgyzPUnk45Ubd86Nr7bIq0zYr0xQxvzc", - "eb/HZ8MVb/y8BjFeUhCj2LYdhTHi2LldqTWa4RDUNhRB8VjTbiMapW6bYhrue2N7jmrYoWwtrlF++axh", - "JDmAc8vcE0c17Bw3EIZHX+2rkn2iG5aabXbpcCOq6O0pYhw70+h2B7cZX7Cb2BpjeNINeLmRhhb58/0R", - "iNI4cgnFDVEmXcmllrYIxNOz7J612E6oSC8duMpj/06NR5F9FzSe5zmsqfqxrv4r2W9C9taTfyX73ZC9", - "dWWH0r2y4ET5cmqfxeDeYf3q1L4kp9bdud35te4t4h2+bZm0tiEhS1e279TDrfbc5OSW7vnfv6PrDmdr", - "zm7tMYgmynQGsuXz/Mq95xvIzqOv6396+cAO1U+dloOFq9vti3KG3e3dqkNceumlxSnezo68XO+4XXZ9", - "n0TT7CRXKajNUd4XFW37rHCoDt0VHVoXu6y29u9vtKjRZ8Etz0ybf09lFtW3xR4XgngVKLsVKDZ48SpQ", - "XgXKc8lR2ESiWAelM6zzGtB5eQGdXYdyxCE6w+GyoEOJCRWVx0baH/DsDAFtM/izj7BPR8DnuUR6thri", - "6ZDe247q+OlxqAw14Z3egR2xYTWsyAthX1oYZ+vxm87AzWNX/GWHaZ5ZgGZ3kRlzR1CX3ukI12yfdnbh", - "S+3Di+oMyDwbx2mvHtO2XaXhava7C7c8TZzlVRI8pSQoRVJeJcGrJNhNnKR3gETfP83vLI9nPA6OgyOc", - "kuDbb9/+LwAA//9ta0ihG8AAAA==", ->>>>>>> 79cc430a (add unknown state to encrypted volume) ->>>>>>> 88c0dce4 (add unknown state to encrypted volume) -======= - "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", - "j2c8CY6DI5yS4Ntv3/4vAAD//4bRtVwmwAAA", ->>>>>>> f6bb1ac3 (gen api) + "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", + "lj3xPrLDAAA=", } // GetSwagger returns the content of the embedded swagger specification file