feat(misconf): Update AppService schema (#9792)

Signed-off-by: nikpivkin <nikita.pivkin@smartforce.io>
Co-authored-by: Nikita Pivkin <nikita.pivkin@smartforce.io>
This commit is contained in:
yagreut
2025-11-19 09:21:09 +02:00
committed by GitHub
parent a6ceff7e83
commit c6d95d7cd2
8 changed files with 120 additions and 120 deletions

View File

@@ -3,7 +3,6 @@ package appservice
import ( import (
"github.com/aquasecurity/trivy/pkg/iac/providers/azure/appservice" "github.com/aquasecurity/trivy/pkg/iac/providers/azure/appservice"
"github.com/aquasecurity/trivy/pkg/iac/scanners/azure" "github.com/aquasecurity/trivy/pkg/iac/scanners/azure"
iacTypes "github.com/aquasecurity/trivy/pkg/iac/types"
) )
func Adapt(deployment azure.Deployment) appservice.AppService { func Adapt(deployment azure.Deployment) appservice.AppService {
@@ -32,27 +31,36 @@ func adaptServices(deployment azure.Deployment) []appservice.Service {
func adaptFunctionApp(resource azure.Resource) appservice.FunctionApp { func adaptFunctionApp(resource azure.Resource) appservice.FunctionApp {
return appservice.FunctionApp{ return appservice.FunctionApp{
Metadata: resource.Metadata, Metadata: resource.Metadata,
HTTPSOnly: resource.Properties.GetMapValue("httpsOnly").AsBoolValue(false, resource.Properties.GetMetadata()), HTTPSOnly: resource.Properties.GetMapValue("httpsOnly").
AsBoolValue(false, resource.Properties.GetMetadata()),
} }
} }
func adaptService(resource azure.Resource) appservice.Service { func adaptService(resource azure.Resource) appservice.Service {
props := resource.Properties
identity := props.GetMapValue("identity")
siteAuthSettings := props.GetMapValue("siteAuthSettings")
siteConfig := props.GetMapValue("siteConfig")
return appservice.Service{ return appservice.Service{
Metadata: resource.Metadata, Metadata: resource.Metadata,
EnableClientCert: resource.Properties.GetMapValue("clientCertEnabled").AsBoolValue(false, resource.Properties.GetMetadata()), EnableClientCert: props.GetMapValue("clientCertEnabled").AsBoolValue(false, props.GetMetadata()),
Identity: struct{ Type iacTypes.StringValue }{ HTTPSOnly: props.GetMapValue("httpsOnly").AsBoolValue(false, props.GetMetadata()),
Type: resource.Properties.GetMapValue("identity").GetMapValue("type").AsStringValue("", resource.Properties.GetMetadata()), Identity: appservice.Identity{
Metadata: identity.GetMetadata(),
Type: identity.GetMapValue("type").
AsStringValue("", props.GetMetadata()),
}, },
Authentication: struct{ Enabled iacTypes.BoolValue }{ Authentication: appservice.Authentication{
Enabled: resource.Properties.GetMapValue("siteAuthSettings").GetMapValue("enabled").AsBoolValue(false, resource.Properties.GetMetadata()), Metadata: siteAuthSettings.GetMetadata(),
Enabled: siteAuthSettings.GetMapValue("enabled").AsBoolValue(false, props.GetMetadata()),
}, },
Site: struct { Site: appservice.Site{
EnableHTTP2 iacTypes.BoolValue EnableHTTP2: siteConfig.GetMapValue("http20Enabled").AsBoolValue(false, siteConfig.GetMetadata()),
MinimumTLSVersion iacTypes.StringValue MinimumTLSVersion: siteConfig.GetMapValue("minTlsVersion").AsStringValue("", siteConfig.GetMetadata()),
}{ PHPVersion: siteConfig.GetMapValue("phpVersion").AsStringValue("", siteConfig.GetMetadata()),
EnableHTTP2: resource.Properties.GetMapValue("httpsOnly").AsBoolValue(false, resource.Properties.GetMetadata()), PythonVersion: siteConfig.GetMapValue("pythonVersion").AsStringValue("", siteConfig.GetMetadata()),
MinimumTLSVersion: resource.Properties.GetMapValue("minTlsVersion").AsStringValue("", resource.Properties.GetMetadata()), FTPSState: siteConfig.GetMapValue("ftpsState").AsStringValue("", siteConfig.GetMetadata()),
}, },
} }
} }

View File

@@ -25,8 +25,8 @@ func TestAdapt(t *testing.T) {
] ]
}`, }`,
expected: appservice.AppService{ expected: appservice.AppService{
FunctionApps: []appservice.FunctionApp{{}},
Services: []appservice.Service{{}}, Services: []appservice.Service{{}},
FunctionApps: []appservice.FunctionApp{{}},
}, },
}, },
{ {
@@ -44,7 +44,14 @@ func TestAdapt(t *testing.T) {
"siteAuthSettings": { "siteAuthSettings": {
"enabled": true "enabled": true
}, },
"minTlsVersion": "1.3" "minTlsVersion": "1.3",
"siteConfig": {
"http20Enabled": true,
"minTlsVersion": "1.2",
"phpVersion": "8.1",
"pythonVersion": "3.11",
"ftpsState": "FtpsOnly"
}
} }
} }
] ]
@@ -52,18 +59,19 @@ func TestAdapt(t *testing.T) {
expected: appservice.AppService{ expected: appservice.AppService{
Services: []appservice.Service{{ Services: []appservice.Service{{
EnableClientCert: types.BoolTest(true), EnableClientCert: types.BoolTest(true),
Identity: struct{ Type types.StringValue }{ HTTPSOnly: types.BoolTest(true),
Identity: appservice.Identity{
Type: types.StringTest("SystemAssigned"), Type: types.StringTest("SystemAssigned"),
}, },
Authentication: struct{ Enabled types.BoolValue }{ Authentication: appservice.Authentication{
Enabled: types.BoolTest(true), Enabled: types.BoolTest(true),
}, },
Site: struct { Site: appservice.Site{
EnableHTTP2 types.BoolValue
MinimumTLSVersion types.StringValue
}{
EnableHTTP2: types.BoolTest(true), EnableHTTP2: types.BoolTest(true),
MinimumTLSVersion: types.StringTest("1.3"), MinimumTLSVersion: types.StringTest("1.2"),
PHPVersion: types.StringTest("8.1"),
PythonVersion: types.StringTest("3.11"),
FTPSState: types.StringTest("FtpsOnly"),
}, },
}}, }},
FunctionApps: []appservice.FunctionApp{{ FunctionApps: []appservice.FunctionApp{{
@@ -78,5 +86,4 @@ func TestAdapt(t *testing.T) {
adaptertest.AdaptAndCompare(t, tt.source, tt.expected, Adapt) adaptertest.AdaptAndCompare(t, tt.source, tt.expected, Adapt)
}) })
} }
} }

View File

@@ -1,9 +1,10 @@
package appservice package appservice
import ( import (
"github.com/samber/lo"
"github.com/aquasecurity/trivy/pkg/iac/providers/azure/appservice" "github.com/aquasecurity/trivy/pkg/iac/providers/azure/appservice"
"github.com/aquasecurity/trivy/pkg/iac/terraform" "github.com/aquasecurity/trivy/pkg/iac/terraform"
iacTypes "github.com/aquasecurity/trivy/pkg/iac/types"
) )
func Adapt(modules terraform.Modules) appservice.AppService { func Adapt(modules terraform.Modules) appservice.AppService {
@@ -15,80 +16,50 @@ func Adapt(modules terraform.Modules) appservice.AppService {
func adaptServices(modules terraform.Modules) []appservice.Service { func adaptServices(modules terraform.Modules) []appservice.Service {
var services []appservice.Service var services []appservice.Service
for _, resource := range modules.GetResourcesByType("azurerm_app_service") {
for _, module := range modules { services = append(services, adaptService(resource))
for _, resource := range module.GetResourcesByType("azurerm_app_service") {
services = append(services, adaptService(resource))
}
} }
return services return services
} }
func adaptFunctionApps(modules terraform.Modules) []appservice.FunctionApp { func adaptFunctionApps(modules terraform.Modules) []appservice.FunctionApp {
var functionApps []appservice.FunctionApp var functionApps []appservice.FunctionApp
for _, resource := range modules.GetResourcesByType("azurerm_function_app") {
for _, module := range modules { functionApps = append(functionApps, adaptFunctionApp(resource))
for _, resource := range module.GetResourcesByType("azurerm_function_app") {
functionApps = append(functionApps, adaptFunctionApp(resource))
}
} }
return functionApps return functionApps
} }
func adaptService(resource *terraform.Block) appservice.Service { func adaptService(resource *terraform.Block) appservice.Service {
enableClientCertAttr := resource.GetAttribute("client_cert_enabled")
enableClientCertVal := enableClientCertAttr.AsBoolValueOrDefault(false, resource)
identityBlock := resource.GetBlock("identity")
typeVal := iacTypes.String("", resource.GetMetadata())
if identityBlock.IsNotNil() {
typeAttr := identityBlock.GetAttribute("type")
typeVal = typeAttr.AsStringValueOrDefault("", identityBlock)
}
authBlock := resource.GetBlock("auth_settings")
enabledVal := iacTypes.Bool(false, resource.GetMetadata())
if authBlock.IsNotNil() {
enabledAttr := authBlock.GetAttribute("enabled")
enabledVal = enabledAttr.AsBoolValueOrDefault(false, authBlock)
}
siteBlock := resource.GetBlock("site_config") siteBlock := resource.GetBlock("site_config")
enableHTTP2Val := iacTypes.Bool(false, resource.GetMetadata()) identityBlock := resource.GetBlock("identity")
minTLSVersionVal := iacTypes.String("1.2", resource.GetMetadata()) authBlock := resource.GetBlock("auth_settings")
if siteBlock.IsNotNil() {
enableHTTP2Attr := siteBlock.GetAttribute("http2_enabled")
enableHTTP2Val = enableHTTP2Attr.AsBoolValueOrDefault(false, siteBlock)
minTLSVersionAttr := siteBlock.GetAttribute("min_tls_version")
minTLSVersionVal = minTLSVersionAttr.AsStringValueOrDefault("1.2", siteBlock)
}
return appservice.Service{ return appservice.Service{
Metadata: resource.GetMetadata(), Metadata: resource.GetMetadata(),
EnableClientCert: enableClientCertVal, EnableClientCert: resource.GetAttribute("client_cert_enabled").AsBoolValueOrDefault(false, resource),
Identity: struct{ Type iacTypes.StringValue }{ HTTPSOnly: resource.GetAttribute("https_only").AsBoolValueOrDefault(false, resource),
Type: typeVal, Identity: appservice.Identity{
Metadata: lo.TernaryF(identityBlock.IsNil(), resource.GetMetadata, identityBlock.GetMetadata),
Type: identityBlock.GetAttribute("type").AsStringValueOrDefault("", identityBlock),
}, },
Authentication: struct{ Enabled iacTypes.BoolValue }{ Authentication: appservice.Authentication{
Enabled: enabledVal, Metadata: lo.TernaryF(identityBlock.IsNil(), resource.GetMetadata, authBlock.GetMetadata),
Enabled: authBlock.GetAttribute("enabled").AsBoolValueOrDefault(false, authBlock),
}, },
Site: struct { Site: appservice.Site{
EnableHTTP2 iacTypes.BoolValue Metadata: lo.TernaryF(identityBlock.IsNil(), resource.GetMetadata, siteBlock.GetMetadata),
MinimumTLSVersion iacTypes.StringValue EnableHTTP2: siteBlock.GetAttribute("http2_enabled").AsBoolValueOrDefault(false, siteBlock),
}{ MinimumTLSVersion: siteBlock.GetAttribute("min_tls_version").AsStringValueOrDefault("1.2", siteBlock),
EnableHTTP2: enableHTTP2Val, PHPVersion: siteBlock.GetAttribute("php_version").AsStringValueOrDefault("", siteBlock),
MinimumTLSVersion: minTLSVersionVal, PythonVersion: siteBlock.GetAttribute("python_version").AsStringValueOrDefault("", siteBlock),
FTPSState: siteBlock.GetAttribute("ftps_state").AsStringValueOrDefault("", siteBlock),
}, },
} }
} }
func adaptFunctionApp(resource *terraform.Block) appservice.FunctionApp { func adaptFunctionApp(resource *terraform.Block) appservice.FunctionApp {
HTTPSOnlyAttr := resource.GetAttribute("https_only")
HTTPSOnlyVal := HTTPSOnlyAttr.AsBoolValueOrDefault(false, resource)
return appservice.FunctionApp{ return appservice.FunctionApp{
Metadata: resource.GetMetadata(), Metadata: resource.GetMetadata(),
HTTPSOnly: HTTPSOnlyVal, HTTPSOnly: resource.GetAttribute("https_only").AsBoolValueOrDefault(false, resource),
} }
} }

View File

@@ -40,20 +40,16 @@ func Test_adaptService(t *testing.T) {
} }
`, `,
expected: appservice.Service{ expected: appservice.Service{
Metadata: iacTypes.NewTestMetadata(), EnableClientCert: iacTypes.BoolTest(true),
EnableClientCert: iacTypes.Bool(true, iacTypes.NewTestMetadata()), Identity: appservice.Identity{
Identity: struct{ Type iacTypes.StringValue }{ Type: iacTypes.StringTest("UserAssigned"),
Type: iacTypes.String("UserAssigned", iacTypes.NewTestMetadata()),
}, },
Authentication: struct{ Enabled iacTypes.BoolValue }{ Authentication: appservice.Authentication{
Enabled: iacTypes.Bool(true, iacTypes.NewTestMetadata()), Enabled: iacTypes.BoolTest(true),
}, },
Site: struct { Site: appservice.Site{
EnableHTTP2 iacTypes.BoolValue EnableHTTP2: iacTypes.BoolTest(true),
MinimumTLSVersion iacTypes.StringValue MinimumTLSVersion: iacTypes.StringTest("1.0"),
}{
EnableHTTP2: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
MinimumTLSVersion: iacTypes.String("1.0", iacTypes.NewTestMetadata()),
}, },
}, },
}, },
@@ -64,20 +60,8 @@ func Test_adaptService(t *testing.T) {
} }
`, `,
expected: appservice.Service{ expected: appservice.Service{
Metadata: iacTypes.NewTestMetadata(), Site: appservice.Site{
EnableClientCert: iacTypes.Bool(false, iacTypes.NewTestMetadata()), MinimumTLSVersion: iacTypes.StringTest("1.2"),
Identity: struct{ Type iacTypes.StringValue }{
Type: iacTypes.String("", iacTypes.NewTestMetadata()),
},
Authentication: struct{ Enabled iacTypes.BoolValue }{
Enabled: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
},
Site: struct {
EnableHTTP2 iacTypes.BoolValue
MinimumTLSVersion iacTypes.StringValue
}{
EnableHTTP2: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
MinimumTLSVersion: iacTypes.String("1.2", iacTypes.NewTestMetadata()),
}, },
}, },
}, },
@@ -107,8 +91,7 @@ func Test_adaptFunctionApp(t *testing.T) {
} }
`, `,
expected: appservice.FunctionApp{ expected: appservice.FunctionApp{
Metadata: iacTypes.NewTestMetadata(), HTTPSOnly: iacTypes.BoolTest(true),
HTTPSOnly: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
}, },
}, },
{ {
@@ -118,8 +101,7 @@ func Test_adaptFunctionApp(t *testing.T) {
} }
`, `,
expected: appservice.FunctionApp{ expected: appservice.FunctionApp{
Metadata: iacTypes.NewTestMetadata(), HTTPSOnly: iacTypes.BoolTest(false),
HTTPSOnly: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
}, },
}, },
} }

View File

@@ -9,19 +9,32 @@ type AppService struct {
FunctionApps []FunctionApp FunctionApps []FunctionApp
} }
type Identity struct {
Metadata iacTypes.Metadata
Type iacTypes.StringValue
}
type Authentication struct {
Metadata iacTypes.Metadata
Enabled iacTypes.BoolValue
}
type Service struct { type Service struct {
Metadata iacTypes.Metadata Metadata iacTypes.Metadata
EnableClientCert iacTypes.BoolValue EnableClientCert iacTypes.BoolValue
Identity struct { HTTPSOnly iacTypes.BoolValue
Type iacTypes.StringValue Identity Identity
} Authentication Authentication
Authentication struct { Site Site
Enabled iacTypes.BoolValue }
}
Site struct { type Site struct {
EnableHTTP2 iacTypes.BoolValue Metadata iacTypes.Metadata
MinimumTLSVersion iacTypes.StringValue EnableHTTP2 iacTypes.BoolValue
} MinimumTLSVersion iacTypes.StringValue
PHPVersion iacTypes.StringValue
PythonVersion iacTypes.StringValue
FTPSState iacTypes.StringValue
} }
type FunctionApp struct { type FunctionApp struct {

View File

@@ -4528,13 +4528,17 @@
"type": "object", "type": "object",
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.BoolValue" "$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.BoolValue"
}, },
"httpsonly": {
"type": "object",
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.BoolValue"
},
"identity": { "identity": {
"type": "object", "type": "object",
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.azure.appservice.Service.Identity" "$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.azure.appservice.Service.Identity"
}, },
"site": { "site": {
"type": "object", "type": "object",
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.azure.appservice.Service.Site" "$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.azure.appservice.Site"
} }
} }
}, },
@@ -4556,16 +4560,28 @@
} }
} }
}, },
"github.com.aquasecurity.trivy.pkg.iac.providers.azure.appservice.Service.Site": { "github.com.aquasecurity.trivy.pkg.iac.providers.azure.appservice.Site": {
"type": "object", "type": "object",
"properties": { "properties": {
"enablehttp2": { "enablehttp2": {
"type": "object", "type": "object",
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.BoolValue" "$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.BoolValue"
}, },
"ftpsstate": {
"type": "object",
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.StringValue"
},
"minimumtlsversion": { "minimumtlsversion": {
"type": "object", "type": "object",
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.StringValue" "$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.StringValue"
},
"phpversion": {
"type": "object",
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.StringValue"
},
"pythonversion": {
"type": "object",
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.StringValue"
} }
} }
}, },

View File

@@ -106,7 +106,7 @@ func NewExprValue(value string, metadata types.Metadata) Value {
} }
} }
func (v *Value) GetMetadata() types.Metadata { func (v Value) GetMetadata() types.Metadata {
return lo.FromPtr(v.metadata) return lo.FromPtr(v.metadata)
} }

View File

@@ -138,6 +138,9 @@ func (b *Block) Reference() Reference {
} }
func (b *Block) GetMetadata() iacTypes.Metadata { func (b *Block) GetMetadata() iacTypes.Metadata {
if b.IsNil() {
return iacTypes.NewUnmanagedMetadata()
}
return b.metadata return b.metadata
} }