Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support VPC security group for PowerVS clusters #1738

Merged
merged 1 commit into from
May 22, 2024

Conversation

dharaneeshvrd
Copy link
Contributor

@dharaneeshvrd dharaneeshvrd commented Apr 19, 2024

What this PR does / why we need it:
Add support for VPC security group for PowerVS clusters

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes #
Fixes #1706

Special notes for your reviewer:

/area provider/ibmcloud

  1. Please confirm that if this PR changes any image versions, then that's the sole change this PR makes.

Release note:

Support VPC security group for PowerVS clusters

@k8s-ci-robot k8s-ci-robot added area/provider/ibmcloud Issues or PRs related to ibmcloud provider cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Apr 19, 2024
@k8s-ci-robot k8s-ci-robot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Apr 19, 2024
Copy link

netlify bot commented Apr 19, 2024

Deploy Preview for kubernetes-sigs-cluster-api-ibmcloud ready!

Name Link
🔨 Latest commit 687d1d6
🔍 Latest deploy log https://app.netlify.com/sites/kubernetes-sigs-cluster-api-ibmcloud/deploys/664c74e7addf3200085a229d
😎 Deploy Preview https://deploy-preview-1738--kubernetes-sigs-cluster-api-ibmcloud.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@dharaneeshvrd dharaneeshvrd force-pushed the vpc-security-group branch 3 times, most recently from 218dc9c to fc926e4 Compare April 19, 2024 11:09
@Prajyot-Parab
Copy link
Contributor

/cc @Karthik-K-N

@Karthik-K-N
Copy link
Contributor

/cc @cjschaef

@k8s-ci-robot
Copy link
Contributor

@Karthik-K-N: GitHub didn't allow me to request PR reviews from the following users: cjschaef.

Note that only kubernetes-sigs members and repo collaborators can review this PR, and authors cannot review their own PRs.

In response to this:

/cc @cjschaef

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

return true, fmt.Errorf("error validating existing security group: %v", err)
}
if securityGroupID != nil {
s.Logger.Info("Security group already exists", "name", *securityGroup.Name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

securityGroup.Name can be nil, so its better to handle it everywhere before directly de referring it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored it to get it from vpcv1.SecurityGroup where name is a required param.

ControllerCreated: ptr.To(false),
})

return false, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in case of multiple security groups we need to continue to process next item instead of returning from here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, Done
thanks!

}

s.SetVPCSecurityGroupID(*securityGroup.Name, infrav1beta2.ResourceReference{
ID: securityGroupID,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should update the status as soon as we create rather than doing it after creating security group rule as it might fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please have a look at the latest implementation, added ruleIDs also in status.


options := &vpcv1.CreateSecurityGroupOptions{
VPC: &vpcv1.VPCIdentity{
ID: s.GetVPCID(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s.GetVPCID() can be nil, So lets handle it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per the reconcile order, when it reaches here VPC status would have been populated right?
Do we really need to check? If its not populated, it would requeue on ReconcileVPC only I believe.

if cidrSubnet == nil {
return fmt.Errorf("subnet by name '%s' not exist", *remote.CIDRSubnetName)
}
s.Logger.Info("Creating security group rule", "securityGroupID", *securityGroupID, "direction", *direction, "protocol", *protocol, "cidrBlockSubnet", *remote.CIDRSubnetName, "cidr", *cidrSubnet.Ipv4CIDRBlock)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be lets use V level logs to dump detailed infos

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return false, fmt.Errorf("error validating security group rule: %v", err)
}
if !match {
return false, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about logging with V(3) with which security group rule did not match.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's really difficult to get that since it's not that straight forward. Let's keep it like this for now!

// validateSecurityGroupRule compares a specific security group's rule with the spec and existing security group's rule.
func (s *PowerVSClusterScope) validateSecurityGroupRule(originalSecurityGroup vpcv1.SecurityGroup, direction infrav1beta2.SecurityGroupRuleDirection, protocol string, portMin, portMax int64, icmpCode, icmpType *string, remote infrav1beta2.SecurityGroupRuleRemote) (bool, error) {
var match bool
var err error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about declaring them in return parameters?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}
}
}
if match {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this should be !match? because we should validate all the rules, If the first rule matches we should not return right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we do not return and attempt to validate only one rule matches.
I expect this function is attempting to verify only one SecurityGroupRule definition from Spec exists in the SecurityGroup. And the function (validateSecurityGroupRule) gets called once for each SecurityGroupRule defined (per SecurityGroup).

So exiting here makes sense IMO, if we only want to validate that a SG Rule exists (expecting we wouldn't have duplicates.....which I don't know if the API allows that).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes its trying to match that particular rule passed is exists or not. So exiting as soon as it finds a match.


// validateVPCSecurityGroup validates the security group and it's rules.
func (s *PowerVSClusterScope) validateVPCSecurityGroup(securityGroup infrav1beta2.SecurityGroup) (*string, error) {
securityGroupDet, err := s.IBMVPCClient.GetSecurityGroupByName(*securityGroup.Name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May we can try to fetch by id as well, if id is already set in status? also we need to make sure name is not nil.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes agree, refactored, ptal!

Copy link
Contributor

@cjschaef cjschaef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The design makes sense, handling the complexities of SecurityGroups and SecurityGroupRules definitions.

In my mind, I was thinking VPC would iterate through creating all the SecurityGroups first, then return to populate the SecurityGroupRules, as some of the Remotes depend on the SecurityGroups (CRN). I will rethink the process some compared with the expectations here, if this looping is acceptable, when to raise errors, etc. due to these additional complexities (inter SecurityGroup/SecurityGroupRule dependencies).

if _, _, err := s.IBMVPCClient.GetSecurityGroup(&vpcv1.GetSecurityGroupOptions{
ID: securityGroup.ID,
}); err != nil {
if strings.Contains(err.Error(), "not found") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't the detailedResponse provide an Http StatusCode you could check rather than rely on the error text?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it would, but this method of validating the resource deletion is followed through out this controller code.
IMO also it's fine.

if start != "" {
listSecurityGroupOptions.Start = &start
}
securityGroupCollection, _, err := s.ListSecurityGroups(&listSecurityGroupOptions)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we instead use the vpcv1.SecurityGroupsPager functionality instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion, implemented using pager.

}
}
}
if match {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we do not return and attempt to validate only one rule matches.
I expect this function is attempting to verify only one SecurityGroupRule definition from Spec exists in the SecurityGroup. And the function (validateSecurityGroupRule) gets called once for each SecurityGroupRule defined (per SecurityGroup).

So exiting here makes sense IMO, if we only want to validate that a SG Rule exists (expecting we wouldn't have duplicates.....which I don't know if the API allows that).

@dharaneeshvrd dharaneeshvrd force-pushed the vpc-security-group branch 3 times, most recently from efc2b5f to 80acbd1 Compare April 24, 2024 07:05
@dharaneeshvrd
Copy link
Contributor Author

The design makes sense, handling the complexities of SecurityGroups and SecurityGroupRules definitions.

In my mind, I was thinking VPC would iterate through creating all the SecurityGroups first, then return to populate the SecurityGroupRules, as some of the Remotes depend on the SecurityGroups (CRN). I will rethink the process some compared with the expectations here, if this looping is acceptable, when to raise errors, etc. due to these additional complexities (inter SecurityGroup/SecurityGroupRule dependencies).

@cjschaef
I have n't used security groups that much, so could n't think of this use case. With the current implementation if we pass the security groups in order which the dependancy chain is, it would still handle it. But if we really need a freedom of referring the sg's CRN from different order, then we need to redesign and it will bring more complexities than current one.
Please let me know whether the current approach is ok or not!

Also I have refactored few things from last review, ptal!

@dharaneeshvrd
Copy link
Contributor Author

/retest-required

@dharaneeshvrd dharaneeshvrd force-pushed the vpc-security-group branch 3 times, most recently from 2ed95eb to 11743b2 Compare April 24, 2024 09:37
Copy link
Contributor

@Karthik-K-N Karthik-K-N left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Few questions otherwise, Overall LGTM

setRemote := func(remote infrav1beta2.SecurityGroupRuleRemote, remoteOption *vpcv1.SecurityGroupRuleRemotePrototype) error {
switch remote.RemoteType {
case infrav1beta2.SecurityGroupRuleRemoteTypeCIDR:
cidrSubnet, err := s.IBMVPCClient.GetVPCSubnetByName(*remote.CIDRSubnetName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of now do we have any check which mandates the user to set remote.CIDRSubnetName when type is infrav1beta2.SecurityGroupRuleRemoteTypeCIDR , If not lets create an issue to add a wehbook later

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is validated in kubebuilder rules in spec.

// ReconcileVPCSecurityGroup reconciles VPC security group.
func (s *PowerVSClusterScope) ReconcileVPCSecurityGroup() (bool, error) {
for _, securityGroup := range s.IBMPowerVSCluster.Spec.VPCSecurityGroups {
securityGroupID, securityGroupRuleIDs := s.GetVPCSecurityGroupID(*securityGroup.Name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets carefully handle *securityGroup.Name when user sets securityGroup.ID

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, taken care, please check!

Copy link
Contributor

@Karthik-K-N Karthik-K-N left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
@mkumatag @Prajyot-Parab @Amulyam24 Please take a look. Thanks

SecurityGroupID: securityGroupID,
ID: rule,
}); err != nil {
return true, err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dharaneeshvrd, shouldn't we be returning false on err and not requeue?

Copy link
Contributor

@Amulyam24 Amulyam24 May 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The requeue was added for handling the state of the infra resources, maybe it can be skipped if security group doesn't need state management?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes Agree, corrected.
Thanks @Amulyam24 !

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dharaneesh, since we are returning false every time, maybe we can just return err and remove the requeue check in the controller?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected!

return false, fmt.Errorf("error validating existing security group: %v", err)
}
if securityGroupDet != nil {
s.Logger.Info("Security group already exists", "name", *securityGroupDet.Name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we set log level to 3 wherever applicable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its ok here, since its going to this block only one time. Same is there on other components too when user provided spec is already exists in cloud, wdys?

Copy link
Contributor

@Amulyam24 Amulyam24 May 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By default, we are setting the log level to 3 to keep uniformity as per the new changes in PR.
Refactoring the logs according to inputs shared here

if _, _, err := s.IBMVPCClient.GetSecurityGroup(&vpcv1.GetSecurityGroupOptions{
ID: securityGroup.ID,
}); err != nil {
if strings.Contains(err.Error(), "not found") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add not found as a constant in types.go?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}); err != nil {
if strings.Contains(err.Error(), "not found") {
s.Info("VPC security group successfully deleted", "ID", securityGroup.ID)
return false, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment applies here - please check if returning err would be enough and requeue can be avoided if not needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes true, I followed the vpc subnet deletion, but I think its bug to return from the loop after processing one item here ;)

Copy link
Contributor

@Amulyam24 Amulyam24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dharaneeshvrd, couple of things, with log refactoring changes, do you mind following the below in this PR:

  • consistent naming for VPC and infra resources in logs such as VPC, VPC subnet, VPC security group etc.
  • Error messages starting with failed to...

Apart from minor comments, overall LGTM

ControllerCreated: ptr.To(true),
})
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we log a statement on successful creation of a security group?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@dharaneeshvrd
Copy link
Contributor Author

@Amulyam24
I have refactored the logs and changed them to V(3).
Now I am not seeing any logs by default, let me know if you want to change the level here to display some if you planned, or please take care of them in your log refactor PR!
Thanks!

@Amulyam24
Copy link
Contributor

@Amulyam24 I have refactored the logs and changed them to V(3). Now I am not seeing any logs by default, let me know if you want to change the level here to display some if you planned, or please take care of them in your log refactor PR! Thanks!

Sure @dharaneeshvrd, I can take care of them in the logging PR once this is merged. Changes LGTM!
@Prajyot-Parab @mkumatag PTAL.

@@ -103,6 +103,10 @@ type IBMPowerVSClusterSpec struct {
// +optional
VPCSubnets []Subnet `json:"vpcSubnets,omitempty"`

// securityGroups to attach it to the VPC resource
// +optional
VPCSecurityGroups []SecurityGroup `json:"vpcSecurityGroups,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any specific reason for not naming this as VPCSecurityGroup?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since its a list item, named it in plural just like VPCSubnets and LoadBalancers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

n/m, this SecurityGroup struct is created earlier in the types.go file

api/v1beta2/ibmpowervscluster_types.go Outdated Show resolved Hide resolved
// id represents the id of the resource.
ID *string `json:"id,omitempty"`
// rules contains the id of rules created under the security group
RuleIDs []*string `json:"rules,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its always good to keep both the struct fieldname and the json name same.

@@ -494,6 +496,44 @@ func (s *PowerVSClusterScope) SetVPCSubnetID(name string, resource infrav1beta2.
s.IBMPowerVSCluster.Status.VPCSubnet[name] = resource
}

// GetVPCSecurityGroupID returns the VPC security group id.
func (s *PowerVSClusterScope) GetVPCSecurityGroupID(name string) (*string, []*string) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

function name says GetVPCSecurityGroupID but returning both security group id and also the rules.

Suggested change
func (s *PowerVSClusterScope) GetVPCSecurityGroupID(name string) (*string, []*string) {
func (s *PowerVSClusterScope) GetVPCSecurityGroup(name string) (*string, []*string) {

}

// GetVPCSecurityGroupRuleIDs returns the VPC security group's ruleIDs.
func (s *PowerVSClusterScope) GetVPCSecurityGroupRuleIDs(securityGroupID string) []*string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is more or less same as GetVPCSecurityGroupID but only difference is that we are supplying the id as param

we can keep the functions like GetVPCSecurityGroupByName and GetVPCSecurityGroupByID with returning same content.

}

// validateVPCSecurityGroupRules compares a specific security group rules spec with the existing security group's rules.
func (s *PowerVSClusterScope) validateVPCSecurityGroupRules(originalSecurityGroup *vpcv1.SecurityGroup, expectedSecurityGroup infrav1beta2.SecurityGroup) ([]*string, bool, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we care just about rules as a param, then lets send only rules as a param

ruleIDs, ok, err := s.validateVPCSecurityGroupRules(securityGroupDet, securityGroup.Rules)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment applies for other functions as well.

Comment on lines 1514 to 1546
switch direction {
case infrav1beta2.SecurityGroupRuleDirectionInbound:
protocol = string(expectedRule.Source.Protocol)
portMin = int64(expectedRule.Source.PortRange.MinimumPort)
portMax = int64(expectedRule.Source.PortRange.MaximumPort)
icmpCode := expectedRule.Source.ICMPCode
icmpType := expectedRule.Source.ICMPType

for _, remote := range expectedRule.Source.Remotes {
id, match, err := s.validateSecurityGroupRule(originalSecurityGroup, direction, protocol, portMin, portMax, icmpCode, icmpType, remote)
if err != nil {
return nil, false, fmt.Errorf("failed to validate security group rule: %w", err)
}
if !match {
return nil, false, nil
}
ruleIDs = append(ruleIDs, id)
}
case infrav1beta2.SecurityGroupRuleDirectionOutbound:
protocol = string(expectedRule.Destination.Protocol)
portMin = int64(expectedRule.Destination.PortRange.MinimumPort)
portMax = int64(expectedRule.Destination.PortRange.MaximumPort)
icmpCode := expectedRule.Destination.ICMPCode
icmpType := expectedRule.Destination.ICMPType

for _, remote := range expectedRule.Destination.Remotes {
id, match, err := s.validateSecurityGroupRule(originalSecurityGroup, direction, protocol, portMin, portMax, icmpCode, icmpType, remote)
if err != nil {
return nil, false, fmt.Errorf("failed to validate security group rule: %v", err)
}
if !match {
return nil, false, nil
}
ruleIDs = append(ruleIDs, id)
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except few, there is lots of common code, wondering if we can reuse some part of it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applies to other functions as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tried to reuse some parts, ptal now!

}
}
if match {
break
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can directly return from here instead.

match = true
}
case infrav1beta2.SecurityGroupRuleRemoteTypeIP:
if originalSGRemote.Address != nil && *originalSGRemote.Address == *expectedSGRemote.IP {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the field name is IP? do we need to rename this to Address

orig:

IP *string `json:"ip,omitempty"`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed to Address to keep it in sync with the VPC's field.

return false, fmt.Errorf("failed to find vpc subnet by name '%s' for getting cidr block: %w", *expectedSGRemote.CIDRSubnetName, err)
}

if originalSGRemote.CIDRBlock != nil && cidrSubnet != nil && *originalSGRemote.CIDRBlock == *cidrSubnet.Ipv4CIDRBlock {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and also here

IP *string `json:"ip,omitempty"`

@dharaneeshvrd dharaneeshvrd force-pushed the vpc-security-group branch 7 times, most recently from 8f10554 to ddaf357 Compare May 14, 2024 06:39
@dharaneeshvrd
Copy link
Contributor Author

Addressed your comments, ptal now @mkumatag

@dharaneeshvrd dharaneeshvrd force-pushed the vpc-security-group branch 2 times, most recently from 3b1b413 to c417314 Compare May 16, 2024 13:41
@mkumatag mkumatag added this to the v0.8 milestone May 17, 2024
Copy link
Contributor

@Karthik-K-N Karthik-K-N left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM

@dharaneeshvrd dharaneeshvrd force-pushed the vpc-security-group branch 2 times, most recently from abd7bea to e328d9c Compare May 21, 2024 10:09
Copy link
Member

@mkumatag mkumatag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label May 22, 2024
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: dharaneeshvrd, mkumatag

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 22, 2024
@k8s-ci-robot k8s-ci-robot merged commit b07b85a into kubernetes-sigs:main May 22, 2024
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. area/provider/ibmcloud Issues or PRs related to ibmcloud provider cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add ability to create new or attach existing security group with rules to VPC
7 participants