diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index b9377c89f0..014862f63f 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -53,6 +53,7 @@ mfs mgroup Mpim natgateway +networkinterface nodepool nullgroup nullstring diff --git a/providers/aws/resources/aws.lr b/providers/aws/resources/aws.lr index 8279f485fb..6bf0da9492 100644 --- a/providers/aws/resources/aws.lr +++ b/providers/aws/resources/aws.lr @@ -2393,6 +2393,8 @@ private aws.vpc.natgateway { vpc() aws.vpc // List of addresses associated with the NAT gateway addresses []aws.vpc.natgateway.address + // Subnet for the NAT gateway + subnet() aws.vpc.subnet } // Amazon VPC NAT gateway address @@ -2756,6 +2758,38 @@ private aws.ec2.instance @defaults("instanceId region state instanceType archite architecture string // The TPM version supported. NitroTPM is enabled if this value is `2.0` tpmSupport string + // List of network interfaces for the instance + networkInterfaces() []aws.ec2.networkinterface +} + +// AWS EC2 network interface +private aws.ec2.networkinterface @defaults("id macAddress description") { + // The ID of the network interface + id string + // The description of the network interface + description string + // The subnet of the network interface + subnet() aws.vpc.subnet + // The VPC of the network interface + vpc() aws.vpc + // The status of the network interface. If the network interface is not attached to an instance, the status is available; if a network interface is attached to an instance the status is in-use + status string + // Indicates whether the network interface performs source/destination checking. A value of true means checking is enabled, and false means checking is disabled. The value must be false for the network interface to perform network address translation (NAT) in your VPC. + sourceDestCheck bool + // Indicates whether the network interface is being managed by an AWS service (for example, AWS Management Console, Auto Scaling, and so on) + requesterManaged bool + // Tags set on the interface + tags map[string]string + // The availability zone of the network interface + availabilityZone string + // Security groups associated with the network interface + securityGroups() []aws.ec2.securitygroup + // Indicates whether this is an IPv6 only network interface + ipv6Native bool + // The MAC address of the network interface + macAddress string + // The private DNS name of the network interface (IPv4) + privateDnsName string } // Amazon EC2 key pair diff --git a/providers/aws/resources/aws.lr.go b/providers/aws/resources/aws.lr.go index a83861d510..17938d5f44 100644 --- a/providers/aws/resources/aws.lr.go +++ b/providers/aws/resources/aws.lr.go @@ -39,7 +39,7 @@ func init() { Create: createAwsVpcRoutetable, }, "aws.vpc.subnet": { - // to override args, implement: initAwsVpcSubnet(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) + Init: initAwsVpcSubnet, Create: createAwsVpcSubnet, }, "aws.vpc.endpoint": { @@ -658,6 +658,10 @@ func init() { Init: initAwsEc2Instance, Create: createAwsEc2Instance, }, + "aws.ec2.networkinterface": { + // to override args, implement: initAwsEc2Networkinterface(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) + Create: createAwsEc2Networkinterface, + }, "aws.ec2.keypair": { Init: initAwsEc2Keypair, Create: createAwsEc2Keypair, @@ -3488,6 +3492,9 @@ var getDataFields = map[string]func(r plugin.Resource) *plugin.DataRes{ "aws.vpc.natgateway.addresses": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlAwsVpcNatgateway).GetAddresses()).ToDataRes(types.Array(types.Resource("aws.vpc.natgateway.address"))) }, + "aws.vpc.natgateway.subnet": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsVpcNatgateway).GetSubnet()).ToDataRes(types.Resource("aws.vpc.subnet")) + }, "aws.vpc.natgateway.address.allocationId": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlAwsVpcNatgatewayAddress).GetAllocationId()).ToDataRes(types.String) }, @@ -3920,6 +3927,48 @@ var getDataFields = map[string]func(r plugin.Resource) *plugin.DataRes{ "aws.ec2.instance.tpmSupport": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlAwsEc2Instance).GetTpmSupport()).ToDataRes(types.String) }, + "aws.ec2.instance.networkInterfaces": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Instance).GetNetworkInterfaces()).ToDataRes(types.Array(types.Resource("aws.ec2.networkinterface"))) + }, + "aws.ec2.networkinterface.id": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Networkinterface).GetId()).ToDataRes(types.String) + }, + "aws.ec2.networkinterface.description": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Networkinterface).GetDescription()).ToDataRes(types.String) + }, + "aws.ec2.networkinterface.subnet": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Networkinterface).GetSubnet()).ToDataRes(types.Resource("aws.vpc.subnet")) + }, + "aws.ec2.networkinterface.vpc": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Networkinterface).GetVpc()).ToDataRes(types.Resource("aws.vpc")) + }, + "aws.ec2.networkinterface.status": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Networkinterface).GetStatus()).ToDataRes(types.String) + }, + "aws.ec2.networkinterface.sourceDestCheck": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Networkinterface).GetSourceDestCheck()).ToDataRes(types.Bool) + }, + "aws.ec2.networkinterface.requesterManaged": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Networkinterface).GetRequesterManaged()).ToDataRes(types.Bool) + }, + "aws.ec2.networkinterface.tags": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Networkinterface).GetTags()).ToDataRes(types.Map(types.String, types.String)) + }, + "aws.ec2.networkinterface.availabilityZone": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Networkinterface).GetAvailabilityZone()).ToDataRes(types.String) + }, + "aws.ec2.networkinterface.securityGroups": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Networkinterface).GetSecurityGroups()).ToDataRes(types.Array(types.Resource("aws.ec2.securitygroup"))) + }, + "aws.ec2.networkinterface.ipv6Native": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Networkinterface).GetIpv6Native()).ToDataRes(types.Bool) + }, + "aws.ec2.networkinterface.macAddress": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Networkinterface).GetMacAddress()).ToDataRes(types.String) + }, + "aws.ec2.networkinterface.privateDnsName": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsEc2Networkinterface).GetPrivateDnsName()).ToDataRes(types.String) + }, "aws.ec2.keypair.arn": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlAwsEc2Keypair).GetArn()).ToDataRes(types.String) }, @@ -8333,6 +8382,10 @@ var setDataFields = map[string]func(r plugin.Resource, v *llx.RawData) bool { r.(*mqlAwsVpcNatgateway).Addresses, ok = plugin.RawToTValue[[]interface{}](v.Value, v.Error) return }, + "aws.vpc.natgateway.subnet": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsVpcNatgateway).Subnet, ok = plugin.RawToTValue[*mqlAwsVpcSubnet](v.Value, v.Error) + return + }, "aws.vpc.natgateway.address.__id": func(r plugin.Resource, v *llx.RawData) (ok bool) { r.(*mqlAwsVpcNatgatewayAddress).__id, ok = v.Value.(string) return @@ -8985,6 +9038,66 @@ var setDataFields = map[string]func(r plugin.Resource, v *llx.RawData) bool { r.(*mqlAwsEc2Instance).TpmSupport, ok = plugin.RawToTValue[string](v.Value, v.Error) return }, + "aws.ec2.instance.networkInterfaces": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Instance).NetworkInterfaces, ok = plugin.RawToTValue[[]interface{}](v.Value, v.Error) + return + }, + "aws.ec2.networkinterface.__id": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).__id, ok = v.Value.(string) + return + }, + "aws.ec2.networkinterface.id": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).Id, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "aws.ec2.networkinterface.description": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).Description, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "aws.ec2.networkinterface.subnet": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).Subnet, ok = plugin.RawToTValue[*mqlAwsVpcSubnet](v.Value, v.Error) + return + }, + "aws.ec2.networkinterface.vpc": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).Vpc, ok = plugin.RawToTValue[*mqlAwsVpc](v.Value, v.Error) + return + }, + "aws.ec2.networkinterface.status": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).Status, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "aws.ec2.networkinterface.sourceDestCheck": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).SourceDestCheck, ok = plugin.RawToTValue[bool](v.Value, v.Error) + return + }, + "aws.ec2.networkinterface.requesterManaged": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).RequesterManaged, ok = plugin.RawToTValue[bool](v.Value, v.Error) + return + }, + "aws.ec2.networkinterface.tags": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).Tags, ok = plugin.RawToTValue[map[string]interface{}](v.Value, v.Error) + return + }, + "aws.ec2.networkinterface.availabilityZone": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).AvailabilityZone, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "aws.ec2.networkinterface.securityGroups": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).SecurityGroups, ok = plugin.RawToTValue[[]interface{}](v.Value, v.Error) + return + }, + "aws.ec2.networkinterface.ipv6Native": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).Ipv6Native, ok = plugin.RawToTValue[bool](v.Value, v.Error) + return + }, + "aws.ec2.networkinterface.macAddress": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).MacAddress, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "aws.ec2.networkinterface.privateDnsName": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsEc2Networkinterface).PrivateDnsName, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, "aws.ec2.keypair.__id": func(r plugin.Resource, v *llx.RawData) (ok bool) { r.(*mqlAwsEc2Keypair).__id, ok = v.Value.(string) return @@ -21502,6 +21615,7 @@ type mqlAwsVpcNatgateway struct { Tags plugin.TValue[map[string]interface{}] Vpc plugin.TValue[*mqlAwsVpc] Addresses plugin.TValue[[]interface{}] + Subnet plugin.TValue[*mqlAwsVpcSubnet] } // createAwsVpcNatgateway creates a new instance of this resource @@ -21577,6 +21691,22 @@ func (c *mqlAwsVpcNatgateway) GetAddresses() *plugin.TValue[[]interface{}] { return &c.Addresses } +func (c *mqlAwsVpcNatgateway) GetSubnet() *plugin.TValue[*mqlAwsVpcSubnet] { + return plugin.GetOrCompute[*mqlAwsVpcSubnet](&c.Subnet, func() (*mqlAwsVpcSubnet, error) { + if c.MqlRuntime.HasRecording { + d, err := c.MqlRuntime.FieldResourceFromRecording("aws.vpc.natgateway", c.__id, "subnet") + if err != nil { + return nil, err + } + if d != nil { + return d.Value.(*mqlAwsVpcSubnet), nil + } + } + + return c.subnet() + }) +} + // mqlAwsVpcNatgatewayAddress for the aws.vpc.natgateway.address resource type mqlAwsVpcNatgatewayAddress struct { MqlRuntime *plugin.Runtime @@ -23083,6 +23213,7 @@ type mqlAwsEc2Instance struct { RootDeviceName plugin.TValue[string] Architecture plugin.TValue[string] TpmSupport plugin.TValue[string] + NetworkInterfaces plugin.TValue[[]interface{}] } // createAwsEc2Instance creates a new instance of this resource @@ -23316,6 +23447,162 @@ func (c *mqlAwsEc2Instance) GetTpmSupport() *plugin.TValue[string] { return &c.TpmSupport } +func (c *mqlAwsEc2Instance) GetNetworkInterfaces() *plugin.TValue[[]interface{}] { + return plugin.GetOrCompute[[]interface{}](&c.NetworkInterfaces, func() ([]interface{}, error) { + if c.MqlRuntime.HasRecording { + d, err := c.MqlRuntime.FieldResourceFromRecording("aws.ec2.instance", c.__id, "networkInterfaces") + if err != nil { + return nil, err + } + if d != nil { + return d.Value.([]interface{}), nil + } + } + + return c.networkInterfaces() + }) +} + +// mqlAwsEc2Networkinterface for the aws.ec2.networkinterface resource +type mqlAwsEc2Networkinterface struct { + MqlRuntime *plugin.Runtime + __id string + mqlAwsEc2NetworkinterfaceInternal + Id plugin.TValue[string] + Description plugin.TValue[string] + Subnet plugin.TValue[*mqlAwsVpcSubnet] + Vpc plugin.TValue[*mqlAwsVpc] + Status plugin.TValue[string] + SourceDestCheck plugin.TValue[bool] + RequesterManaged plugin.TValue[bool] + Tags plugin.TValue[map[string]interface{}] + AvailabilityZone plugin.TValue[string] + SecurityGroups plugin.TValue[[]interface{}] + Ipv6Native plugin.TValue[bool] + MacAddress plugin.TValue[string] + PrivateDnsName plugin.TValue[string] +} + +// createAwsEc2Networkinterface creates a new instance of this resource +func createAwsEc2Networkinterface(runtime *plugin.Runtime, args map[string]*llx.RawData) (plugin.Resource, error) { + res := &mqlAwsEc2Networkinterface{ + MqlRuntime: runtime, + } + + err := SetAllData(res, args) + if err != nil { + return res, err + } + + // to override __id implement: id() (string, error) + + if runtime.HasRecording { + args, err = runtime.ResourceFromRecording("aws.ec2.networkinterface", res.__id) + if err != nil || args == nil { + return res, err + } + return res, SetAllData(res, args) + } + + return res, nil +} + +func (c *mqlAwsEc2Networkinterface) MqlName() string { + return "aws.ec2.networkinterface" +} + +func (c *mqlAwsEc2Networkinterface) MqlID() string { + return c.__id +} + +func (c *mqlAwsEc2Networkinterface) GetId() *plugin.TValue[string] { + return &c.Id +} + +func (c *mqlAwsEc2Networkinterface) GetDescription() *plugin.TValue[string] { + return &c.Description +} + +func (c *mqlAwsEc2Networkinterface) GetSubnet() *plugin.TValue[*mqlAwsVpcSubnet] { + return plugin.GetOrCompute[*mqlAwsVpcSubnet](&c.Subnet, func() (*mqlAwsVpcSubnet, error) { + if c.MqlRuntime.HasRecording { + d, err := c.MqlRuntime.FieldResourceFromRecording("aws.ec2.networkinterface", c.__id, "subnet") + if err != nil { + return nil, err + } + if d != nil { + return d.Value.(*mqlAwsVpcSubnet), nil + } + } + + return c.subnet() + }) +} + +func (c *mqlAwsEc2Networkinterface) GetVpc() *plugin.TValue[*mqlAwsVpc] { + return plugin.GetOrCompute[*mqlAwsVpc](&c.Vpc, func() (*mqlAwsVpc, error) { + if c.MqlRuntime.HasRecording { + d, err := c.MqlRuntime.FieldResourceFromRecording("aws.ec2.networkinterface", c.__id, "vpc") + if err != nil { + return nil, err + } + if d != nil { + return d.Value.(*mqlAwsVpc), nil + } + } + + return c.vpc() + }) +} + +func (c *mqlAwsEc2Networkinterface) GetStatus() *plugin.TValue[string] { + return &c.Status +} + +func (c *mqlAwsEc2Networkinterface) GetSourceDestCheck() *plugin.TValue[bool] { + return &c.SourceDestCheck +} + +func (c *mqlAwsEc2Networkinterface) GetRequesterManaged() *plugin.TValue[bool] { + return &c.RequesterManaged +} + +func (c *mqlAwsEc2Networkinterface) GetTags() *plugin.TValue[map[string]interface{}] { + return &c.Tags +} + +func (c *mqlAwsEc2Networkinterface) GetAvailabilityZone() *plugin.TValue[string] { + return &c.AvailabilityZone +} + +func (c *mqlAwsEc2Networkinterface) GetSecurityGroups() *plugin.TValue[[]interface{}] { + return plugin.GetOrCompute[[]interface{}](&c.SecurityGroups, func() ([]interface{}, error) { + if c.MqlRuntime.HasRecording { + d, err := c.MqlRuntime.FieldResourceFromRecording("aws.ec2.networkinterface", c.__id, "securityGroups") + if err != nil { + return nil, err + } + if d != nil { + return d.Value.([]interface{}), nil + } + } + + return c.securityGroups() + }) +} + +func (c *mqlAwsEc2Networkinterface) GetIpv6Native() *plugin.TValue[bool] { + return &c.Ipv6Native +} + +func (c *mqlAwsEc2Networkinterface) GetMacAddress() *plugin.TValue[string] { + return &c.MacAddress +} + +func (c *mqlAwsEc2Networkinterface) GetPrivateDnsName() *plugin.TValue[string] { + return &c.PrivateDnsName +} + // mqlAwsEc2Keypair for the aws.ec2.keypair resource type mqlAwsEc2Keypair struct { MqlRuntime *plugin.Runtime diff --git a/providers/aws/resources/aws.lr.manifest.yaml b/providers/aws/resources/aws.lr.manifest.yaml index 06aa93e275..3102270f48 100755 --- a/providers/aws/resources/aws.lr.manifest.yaml +++ b/providers/aws/resources/aws.lr.manifest.yaml @@ -1024,6 +1024,8 @@ resources: instanceType: {} keypair: {} launchTime: {} + networkInterfaces: + min_mondoo_version: 9.0.0 patchState: {} platformDetails: min_mondoo_version: 8.11.0 @@ -1160,6 +1162,26 @@ resources: platform: name: - aws + aws.ec2.networkinterface: + fields: + availabilityZone: {} + description: {} + id: {} + ipv6Native: {} + macAddress: {} + privateDnsName: {} + requesterManaged: {} + securityGroups: {} + sourceDestCheck: {} + status: {} + subnet: {} + tags: {} + vpc: {} + is_private: true + min_mondoo_version: 9.0.0 + platform: + name: + - aws aws.ec2.securitygroup: docs: desc: | diff --git a/providers/aws/resources/aws_ec2.go b/providers/aws/resources/aws_ec2.go index 354ba88215..b2a83f6cbe 100644 --- a/providers/aws/resources/aws_ec2.go +++ b/providers/aws/resources/aws_ec2.go @@ -913,6 +913,105 @@ type mqlAwsEc2InstanceInternal struct { instanceCache ec2types.Instance } +func (i *mqlAwsEc2Instance) networkInterfaces() ([]interface{}, error) { + conn := i.MqlRuntime.Connection.(*connection.AwsConnection) + svc := conn.Ec2(i.Region.Data) + ctx := context.Background() + nextToken := aws.String("no_token_to_start_with") + params := &ec2.DescribeNetworkInterfacesInput{Filters: []ec2types.Filter{{Name: aws.String("attachment.instance-id"), Values: []string{i.InstanceId.Data}}}} + res := []interface{}{} + for nextToken != nil { + nis, err := svc.DescribeNetworkInterfaces(ctx, params) + if err != nil { + return nil, err + } + for ni := range nis.NetworkInterfaces { + n := nis.NetworkInterfaces[ni] + args := map[string]*llx.RawData{ + "id": llx.StringDataPtr(n.NetworkInterfaceId), + "description": llx.StringDataPtr(n.Description), + "status": llx.StringData(string(n.Status)), + "sourceDestCheck": llx.BoolDataPtr(n.SourceDestCheck), + "requesterManaged": llx.BoolDataPtr(n.RequesterManaged), + "tags": llx.MapData(Ec2TagsToMap(n.TagSet), types.String), + "availabilityZone": llx.StringDataPtr(n.AvailabilityZone), + "ipv6Native": llx.BoolDataPtr(n.Ipv6Native), + "macAddress": llx.StringDataPtr(n.MacAddress), + "privateDnsName": llx.StringDataPtr(n.PrivateDnsName), + } + mqlNetworkInterface, err := CreateResource(i.MqlRuntime, "aws.ec2.networkinterface", args) + if err != nil { + return nil, err + } + mqlNetworkInterface.(*mqlAwsEc2Networkinterface).networkInterfaceCache = n + mqlNetworkInterface.(*mqlAwsEc2Networkinterface).region = i.Region.Data + res = append(res, mqlNetworkInterface) + } + nextToken = nis.NextToken + if nis.NextToken != nil { + params.NextToken = nextToken + } + } + return res, nil +} + +type mqlAwsEc2NetworkinterfaceInternal struct { + networkInterfaceCache ec2types.NetworkInterface + region string +} + +func (i *mqlAwsEc2Networkinterface) securityGroups() ([]interface{}, error) { + if i.networkInterfaceCache.Groups != nil { + sgs := []interface{}{} + conn := i.MqlRuntime.Connection.(*connection.AwsConnection) + + for nig := range i.networkInterfaceCache.Groups { + g := *i.networkInterfaceCache.Groups[nig].GroupId + + mqlSg, err := NewResource(i.MqlRuntime, "aws.ec2.securitygroup", + map[string]*llx.RawData{"arn": llx.StringData(fmt.Sprintf(securityGroupArnPattern, i.region, conn.AccountId(), g))}) + if err != nil { + return nil, err + } + sgs = append(sgs, mqlSg) + } + return sgs, nil + } + i.SecurityGroups.State = plugin.StateIsSet | plugin.StateIsNull + return nil, nil +} + +func (i *mqlAwsEc2Networkinterface) subnet() (*mqlAwsVpcSubnet, error) { + subn := i.networkInterfaceCache.SubnetId + conn := i.MqlRuntime.Connection.(*connection.AwsConnection) + if subn != nil { + + arn := fmt.Sprintf(subnetArnPattern, i.region, conn.AccountId(), *subn) + res, err := NewResource(i.MqlRuntime, "aws.vpc.subnet", map[string]*llx.RawData{"arn": llx.StringData(arn)}) + if err != nil { + return nil, err + } + return res.(*mqlAwsVpcSubnet), nil + } + i.Subnet.State = plugin.StateIsNull | plugin.StateIsSet + return nil, nil +} + +func (i *mqlAwsEc2Networkinterface) vpc() (*mqlAwsVpc, error) { + vpcId := i.networkInterfaceCache.VpcId + if vpcId != nil { + conn := i.MqlRuntime.Connection.(*connection.AwsConnection) + vpcArn := fmt.Sprintf(vpcArnPattern, i.region, conn.AccountId(), convert.ToString(vpcId)) + res, err := NewResource(i.MqlRuntime, "aws.vpc", map[string]*llx.RawData{"arn": llx.StringData(vpcArn)}) + if err != nil { + return nil, err + } + return res.(*mqlAwsVpc), nil + } + i.Vpc.State = plugin.StateIsNull | plugin.StateIsSet + return nil, nil +} + func (i *mqlAwsEc2Instance) securityGroups() ([]interface{}, error) { if i.instanceCache.SecurityGroups != nil { sgs := []interface{}{} diff --git a/providers/aws/resources/aws_vpc.go b/providers/aws/resources/aws_vpc.go index d8cf54a76d..3dd8c366ff 100644 --- a/providers/aws/resources/aws_vpc.go +++ b/providers/aws/resources/aws_vpc.go @@ -135,21 +135,19 @@ func (a *mqlAwsVpcNatgateway) vpc() (*mqlAwsVpc, error) { return nil, nil } -// i think bc subnet is a subresource of vpc i'm having trouble doing this here -// not totally sure, will revisit -// func (a *mqlAwsVpcNatgateway) subnet() (*mqlAwsVpcSubnet, error) { -// if a.natGatewayCache.SubnetId != nil { -// conn := a.MqlRuntime.Connection.(*connection.AwsConnection) -// res, err := NewResource(a.MqlRuntime, "aws.vpc.subnet", map[string]*llx.RawData{"arn": llx.StringData(fmt.Sprintf(subnetArnPattern, a.region, conn.AccountId(), convert.ToString(a.natGatewayCache.SubnetId)))}) -// if err != nil { -// a.Subnet.State = plugin.StateIsNull | plugin.StateIsSet -// return nil, err -// } -// return res.(*mqlAwsVpcSubnet), nil -// } -// a.Subnet.State = plugin.StateIsNull | plugin.StateIsSet -// return nil, nil -// } +func (a *mqlAwsVpcNatgateway) subnet() (*mqlAwsVpcSubnet, error) { + if a.natGatewayCache.SubnetId != nil { + conn := a.MqlRuntime.Connection.(*connection.AwsConnection) + res, err := NewResource(a.MqlRuntime, "aws.vpc.subnet", map[string]*llx.RawData{"arn": llx.StringData(fmt.Sprintf(subnetArnPattern, a.region, conn.AccountId(), convert.ToString(a.natGatewayCache.SubnetId)))}) + if err != nil { + a.Subnet.State = plugin.StateIsNull | plugin.StateIsSet + return nil, err + } + return res.(*mqlAwsVpcSubnet), nil + } + a.Subnet.State = plugin.StateIsNull | plugin.StateIsSet + return nil, nil +} func (a *mqlAwsVpcNatgatewayAddress) publicIp() (*mqlAwsEc2Eip, error) { if a.natGatewayAddressCache.PublicIp != nil { @@ -610,7 +608,7 @@ func (a *mqlAwsVpc) subnets() ([]interface{}, error) { return res, nil } -func initAwsSubnet(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) { +func initAwsVpcSubnet(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) { if args["arn"] == nil && args["id"] == nil { return nil, nil, errors.New("id or arn required to fetch aws vpc subnet") } @@ -637,7 +635,6 @@ func initAwsSubnet(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[s } } } - if subnetId == "" { return nil, nil, errors.New("no subnet id specified") }