@@ -20,74 +20,14 @@ package azure
2020import (
2121 "context"
2222 "fmt"
23- "strings"
2423
24+ "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork"
25+ accesscontrol "github.com/app-net-interface/awi-infra-guard/azure/accessControl"
26+ "github.com/app-net-interface/awi-infra-guard/connector/helper"
27+ "github.com/app-net-interface/awi-infra-guard/grpc/go/infrapb"
2528 "github.com/app-net-interface/awi-infra-guard/types"
2629)
2730
28- type vpcPolicy string
29-
30- const (
31- vpcPolicyAllow = "allow"
32- vpcPolicyDeny = "deny"
33- )
34-
35- // func (c *Client) refreshVnetSubnetsWithVPCPolicy(
36- // ctx context.Context,
37- // vnet armnetwork.VirtualNetwork,
38- // inboundVnet string,
39- // policy vpcPolicy,
40- // ) error {
41- // c.logger.Trace(
42- // "updating virtual network '%s' subnets with VPC Policy %s",
43- // vnet,
44- // )
45- // if vnet.Properties == nil {
46- // c.logger.Warnf(
47- // "virtual network '%s' has no properties - skipping policy update",
48- // helper.StringPointerToString(vnet.ID),
49- // )
50- // return nil
51- // }
52-
53- // for i := range vnet.Properties.Subnets {
54- // if vnet.Properties.Subnets[i] == nil {
55- // c.logger.Warnf(
56- // "virtual network '%s' has a nil subnet pointer - skipping subnet entry",
57- // helper.StringPointerToString(vnet.ID),
58- // )
59- // continue
60- // }
61- // if vnet.Properties.Subnets[i].Properties == nil {
62- // c.logger.Warnf(
63- // "virtual network '%s' has a subnet %s with no properties - skipping subnet entry",
64- // helper.StringPointerToString(vnet.ID),
65- // helper.StringPointerToString(vnet.Properties.Subnets[i].ID),
66- // )
67- // continue
68- // }
69- // }
70-
71- // return nil
72- // }
73-
74- func getVnetSourceIDFromAWITags (tags map [string ]string ) (string , error ) {
75- tagValue , ok := tags ["awi" ]
76- if ! ok {
77- return "" , fmt .Errorf (
78- "expected request key tag 'awi' with source ID but found none. Got tags: %v" ,
79- tags ,
80- )
81- }
82- if ! strings .HasPrefix (tagValue , "default-" ) {
83- return "" , fmt .Errorf (
84- "the value of 'awi' tag from request has invalid prefix. Expected 'default-' but got: %s" ,
85- tagValue ,
86- )
87- }
88- return strings .TrimPrefix (tagValue , "default-" ), nil
89- }
90-
9131// AccessControl interface implementation
9232func (c * Client ) AddInboundAllowRuleInVPC (
9333 ctx context.Context ,
@@ -98,7 +38,6 @@ func (c *Client) AddInboundAllowRuleInVPC(
9838 ruleName string ,
9939 tags map [string ]string ,
10040) error {
101-
10241 vnet , vnetAccount , err := c .getVPC (
10342 ctx , destinationVpcID , region ,
10443 )
@@ -113,38 +52,150 @@ func (c *Client) AddInboundAllowRuleInVPC(
11352 account = vnetAccount
11453 }
11554
116- sourceID , err := getVnetSourceIDFromAWITags ( tags )
117- if err != nil {
118- return fmt . Errorf (
119- "failed to obtain the ID of Source VPC: %w" , err ,
120- )
121- }
55+ ruleset := accesscontrol. AccessControlRuleSet {}
56+ ruleset . NewDirectedVPCRules (
57+ accesscontrol . CustomRuleName ( ruleName ),
58+ accesscontrol . AccessAllow ,
59+ cidrsToAllow ,
60+ )
12261
123- err = c .refreshSubnetSecurityGroupWithVPCInbound (
62+ err = c .ApplyAccessRulesToVPC (
12463 ctx ,
12564 account ,
126- region ,
127- cidrsToAllow ,
128- vpcPolicyAllow ,
12965 vnet ,
130- sourceID ,
131- ruleName ,
66+ ruleset ,
13267 )
13368 if err != nil {
13469 return fmt .Errorf (
135- "failed to refresh Security Groups for subnets from VNet %s: %w" ,
136- destinationVpcID , err ,
70+ "failed to apply rules %v to VPC %s: %w" ,
71+ ruleset , destinationVpcID , err ,
13772 )
13873 }
13974
14075 return nil
14176}
14277
78+ func (c * Client ) getSubnetsFromInstances (
79+ ctx context.Context , instances []types.Instance ,
80+ ) ([]armnetwork.Subnet , error ) {
81+
82+ type subnetInfo struct {
83+ VNetID string
84+ SubnetID string
85+ }
86+
87+ subnetInfos := helper.Set [subnetInfo ]{}
88+
89+ for _ , instance := range instances {
90+ subnetInfos .Set (subnetInfo {
91+ VNetID : instance .VPCID ,
92+ SubnetID : instance .SubnetID ,
93+ })
94+ }
95+
96+ infos := subnetInfos .Keys ()
97+ subnets := make ([]armnetwork.Subnet , 0 , len (infos ))
98+
99+ for _ , info := range infos {
100+ subnet , _ , err := c .getSubnet (
101+ ctx ,
102+ parseResourceGroupName (info .SubnetID ),
103+ parseResourceName (info .VNetID ),
104+ parseResourceName (info .SubnetID ),
105+ )
106+ if err != nil {
107+ return nil , fmt .Errorf (
108+ "failed to get subnet %s: %w" ,
109+ info .SubnetID , err ,
110+ )
111+ }
112+ subnets = append (subnets , subnet )
113+ }
114+
115+ return subnets , nil
116+ }
117+
118+ func (c * Client ) prepareCustomAccessRules (
119+ instances []types.Instance ,
120+ ruleName string ,
121+ cidrsToAllow []string ,
122+ protocolsAndPorts types.ProtocolsAndPorts ,
123+ ) (accesscontrol.AccessControlRuleSet , error ) {
124+ ruleset := accesscontrol.AccessControlRuleSet {}
125+
126+ for _ , instance := range instances {
127+ err := ruleset .NewCustomRules (
128+ accesscontrol .CustomRuleName (ruleName ),
129+ accesscontrol .AccessAllow ,
130+ []string {instance .SubnetID },
131+ cidrsToAllow ,
132+ []string {instance .PrivateIP },
133+ protocolsAndPorts ,
134+ )
135+ if err != nil {
136+ return accesscontrol.AccessControlRuleSet {}, fmt .Errorf (
137+ "failed to create custom rule: %w" , err ,
138+ )
139+ }
140+ }
141+
142+ return ruleset , nil
143+ }
144+
143145func (c * Client ) AddInboundAllowRuleByLabelsMatch (ctx context.Context , account , region string ,
144146 vpcID string , ruleName string , labels map [string ]string , cidrsToAllow []string ,
145147 protocolsAndPorts types.ProtocolsAndPorts ) (ruleId string , instances []types.Instance , err error ) {
146- // TBD
147- return "" , nil , nil
148+
149+ instances , err = c .ListInstances (ctx , & infrapb.ListInstancesRequest {
150+ VpcId : vpcID ,
151+ Zone : region ,
152+ AccountId : account ,
153+ Labels : labels ,
154+ Region : region ,
155+ })
156+ if err != nil {
157+ return "" , nil , fmt .Errorf (
158+ "failed to list Instances: %w" , err ,
159+ )
160+ }
161+
162+ subnets , err := c .getSubnetsFromInstances (ctx , instances )
163+ if err != nil {
164+ return "" , nil , fmt .Errorf (
165+ "failed to extract subnets associated with matched instances: %w" , err ,
166+ )
167+ }
168+
169+ ruleset , err := c .prepareCustomAccessRules (
170+ instances ,
171+ ruleName ,
172+ cidrsToAllow ,
173+ protocolsAndPorts ,
174+ )
175+ if err != nil {
176+ return "" , nil , fmt .Errorf (
177+ "failed to prepare custom access rules: %w" , err ,
178+ )
179+ }
180+
181+ for _ , subnet := range subnets {
182+ err = c .ApplyAccessRulesToSubnet (
183+ ctx ,
184+ account ,
185+ region ,
186+ subnet ,
187+ ruleset ,
188+ )
189+ if err != nil {
190+ return "" , nil , fmt .Errorf (
191+ "failed to apply access rules to subnet %s: %w" ,
192+ helper .StringPointerToString (subnet .ID ),
193+ err ,
194+ )
195+ }
196+ }
197+
198+ return ruleName , instances , nil
148199}
149200
150201func (c * Client ) AddInboundAllowRuleBySubnetMatch (ctx context.Context , account , region string ,
@@ -168,7 +219,7 @@ func (c *Client) AddInboundAllowRuleForLoadBalancerByDNS(ctx context.Context, ac
168219}
169220
170221func (c * Client ) RemoveInboundAllowRuleFromVPCByName (ctx context.Context , account , region string , vpcID string , ruleName string ) error {
171- vnet , vnetAccount , err := c .getVPC (
222+ vnet , _ , err := c .getVPC (
172223 ctx , vpcID , region ,
173224 )
174225 if err != nil {
@@ -177,16 +228,13 @@ func (c *Client) RemoveInboundAllowRuleFromVPCByName(ctx context.Context, accoun
177228 vpcID , err ,
178229 )
179230 }
180- if account == "" {
181- account = vnetAccount
182- }
183231
184- err = c .deleteVPCInboundFromSubnets (
232+ err = c .DeleteAccessRulesFromVPC (
185233 ctx ,
186- account ,
187- region ,
188234 vnet ,
189- ruleName ,
235+ accesscontrol.RuleNames {
236+ accesscontrol .CustomRuleName (ruleName ),
237+ },
190238 )
191239 if err != nil {
192240 return fmt .Errorf (
0 commit comments