-
Notifications
You must be signed in to change notification settings - Fork 14
Add dynamic ranges to generated communication matrix #275
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
base: main
Are you sure you want to change the base?
Add dynamic ranges to generated communication matrix #275
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: shirmoran The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
/cc @yuvalk |
ed8384d to
4316ac0
Compare
4316ac0 to
f28b674
Compare
aabughosh
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
|
/retest |
pkg/types/types.go
Outdated
| Matrix []ComDetails | ||
| DynamicRanges []DynamicRange |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did we split the struct rather than using DynamicRanges inside the Matrix?
specifically, in the csv format it looks like a part of the matrix and in the json format it looks like a separate entity, which of these behaviors we would like to go with (because currently it looks a bit odd imo)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mainly because the needed fields are different when documenting dynamic ranges compared to single ports, so we tried going with a seperate entity. I agree the csv format doesn't represent well the new entity, and it is something we also discussed with @yuvalk. But since Nokia asked to add the ranges to the csv format we thought it is the best way to go. Though if you have any other suggestions I'll be happy to hear :)
f28b674 to
a960623
Compare
|
New changes are detected. LGTM label has been removed. |
a960623 to
9cb4066
Compare
9cb4066 to
26f013c
Compare
|
can you please split your commits into:
|
bcadc0a to
988d969
Compare
988d969 to
bcb56a4
Compare
pkg/commatrix-creator/commatrix.go
Outdated
| var customMatrix *types.ComMatrix | ||
| if cm.customEntriesPath != "" { | ||
| log.Debug("Loading custom entries from file") | ||
| customComDetails, err := cm.GetComDetailsListFromFile() | ||
| customMatrix, err = cm.GetComMatrixFromFile() | ||
| if err != nil { | ||
| log.Errorf("Failed adding custom entries: %s", err) | ||
| return nil, fmt.Errorf("failed adding custom entries: %s", err) | ||
| } | ||
| epSliceComDetails = append(epSliceComDetails, customComDetails...) | ||
| epSliceComDetails = append(epSliceComDetails, customMatrix.Ports...) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we move this logic below (so it is the last as before)?
also, instead of initializing customMatrix outside, it would be cleaner to have an empty slice customDynamicRanges, populate it after parsing the customMatrix and appending it to the existing (instead of if customMatrix != nil && ..)
pkg/types/types.go
Outdated
| } `json:"containers"` | ||
| } | ||
|
|
||
| func (dr *DynamicRange) ToString() string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: rename to Ports / PortRange
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be confusing with Ports being the name of the ComMatrix ComDetails list.
Also, I think ToString might be a good expression for what the method is doing - representing dynamic range struct as a string. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when I see a ToString / String method I assume I'm getting a string representation of an object (which could identify it). returning only the ports seems a bit too narrow, considering multiple "DynamicRanges" can return the same
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah okay I see your point.
What do you think about "ToPortRangeString"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good (I'd omit the "To" though, but both are fine)
pkg/types/types.go
Outdated
| } | ||
|
|
||
| // Append dynamic ranges as rows under ComDetails headers. | ||
| if len(m.DynamicRanges) > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: redundant if
pkg/types/types.go
Outdated
| } | ||
|
|
||
| for _, dr := range m.DynamicRanges { | ||
| rangeStr := fmt.Sprintf("%d-%d", dr.MinPort, dr.MaxPort) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can we use dr.ToString() here?
pkg/types/types.go
Outdated
| if err := json.Unmarshal(content, &cm); err == nil { | ||
| return &cm, nil | ||
| } | ||
| return nil, fmt.Errorf("failed to parse JSON as ComMatrix") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you wrap with the err here?
pkg/types/types.go
Outdated
| port, err := strconv.Atoi(portStr) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("invalid port %q: %w", portStr, err) | ||
| } | ||
| details = append(details, ComDetails{ | ||
| Direction: r.Direction, | ||
| Protocol: r.Protocol, | ||
| Port: port, | ||
| Namespace: r.Namespace, | ||
| Service: r.Service, | ||
| Pod: r.Pod, | ||
| Container: r.Container, | ||
| NodeGroup: r.NodeGroup, | ||
| Optional: r.Optional, | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same (wrap in helper)
pkg/types/types.go
Outdated
| // parsePortRange parses strings like "MIN MAX" or "MIN-MAX" into numeric bounds. | ||
| func parsePortRange(s string) (int, int, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you split this into 2 functions? (one per format)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just want to make sure I understood:
- a function parsing "MIN MAX" to range
- a function parsing "MIN-MAX" to range
If so, it seems similar to me with the same purpose, not sure why we should seperate. Can you please elaborate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
otoh it's easier to debug, is more readable and it forces the caller to be aware of what they are passing
overall, it's worth investing a few lines of code to have a more readable (and explicit) behavior, instead of allowing a function to have multiple behaviors hidden (e.g, what happens when you want to support MIN~MAX, would the existing function become longer?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point. Thanks for the note!
| return fmt.Errorf("failed deleting namespace %s: %v", namespace, err) | ||
| } | ||
|
|
||
| if pollErr := wait.PollUntilContextTimeout(context.TODO(), time.Second, 2*time.Minute, true, func(ctx context.Context) (bool, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this change (how is it related to this pr)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When adding the linux dynamic ranges to the matrix we create a namespace that has to be deleted afterwards. This logic is needed after the deletion, we used also when deleting a namespace in the generate.go file (see relevant deleted lines).
As I relalized we need to use the logic related to the deletion in both scenarios I thought it will be more logical to include it in the function. Though I agree maybe this change should be in a seperate commit or PR. Which approach is better in your opinnion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense having it in a different commit here
pkg/dynamic-ranges/dynamic-ranges.go
Outdated
| // parsePortRange parses "MIN MAX" or "MIN-MAX" formatted ranges. | ||
| func parsePortRange(s string) (int, int, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this be shared somehow instead of duplicating?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep you're right, I missed that, thanks!
pkg/dynamic-ranges/dynamic-ranges.go
Outdated
| for i := range dr { | ||
| dr[i].MinPort = minPort | ||
| dr[i].MaxPort = maxPort | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure I understand this logic, why would we want to replace this way instead of explicitly building the range?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Idea was to keep all other fields of types.KubeletNodePortDefaultDynamicRange (as dr is set to in line 53) and just change the MinPort and MaxPort field if network.Spec.ServiceNodePortRange is set.
Do you think there is a better way of doing so?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd either:
- redeclare the bits explicitly
- wrap the "kubelet node ports" in a function (and have default vars for the min/max ports)
the existing way just seems too hacky, and relies on the structure of a var (declared in a different file) which is not so intuitive
e96bcc7 to
0265d67
Compare
As we will be adding dynamice ranges to the matrix, we want to make it more clear that there are two parts of the matrix - ports and ranges, rather than the communication matrix and additional ranges.
0265d67 to
6195fd3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this file (and dir) for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't be here. I'll remove it, thanks!
| testNetwork = &configv1.Network{ | ||
| ObjectMeta: metav1.ObjectMeta{ | ||
| Name: "cluster", | ||
| }, | ||
| Spec: configv1.NetworkSpec{ | ||
| ServiceNodePortRange: "30000-32767", | ||
| }, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you change this to non-default values, and have another test where the field is not specified to see we consume the "default" var? (also it seems the test doesn't do anything with these and the linux values?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test doesn't though in the creation of the commatrix we do try to get those values. But we should have desiganted tests for that I agree. I will add them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though I think we should create a new file for tests under dynamic-ranges, and there we will test the functions getting the ranges, here we will only mock the behavior the enable the creation of the commatrix (as we do now). What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we add some unit tests around the functions here and types.go?
6195fd3 to
055c8c2
Compare
This PR is adding the following changes: As requested from the partenrs, the dynamic port ranges of the cluster (Linux dynamic\private ranges, kubelet node port dynamic range, host level services dynamic range), are added to the generated communication matrix in all of the supported formats. The dynamic ranges are extracted in the following ways: Node port dynamic range: we are looking for a custom defined range (network.Spec.ServiceNodePortRange), if there is no range set, we use a default static range (30000-32767) Linux dynamic\private range: we retrive the dynamic range by reading the host sysctl (/proc/sys/net/ipv4/ip_local_port_range). We also have added the option of using a custom entries file that include ranges, so partners will be able to add their own ranges if needed. The e2e tests have been modified the following: EPS vs SS: in the comparsion between the matrices, we also check if host level open ports (from ss matrix) which don't have an EPS are in the range specified in the generated commatrix. Doc vs EPS: in the comparison between the matrices, we also check if the ports in the generated commatrix which are not documented in the doc matrix, do appear in the doc ranges. The custom entries samples had been modified to also include ranges. commatrix.go file's unit tests had been modified to allow mocking of a debugpod in the tests. For that sense, we have added to the commatrixCreator struct a utils field similar to what's done in the ConnectionCheck struct.
As we use this logic every time we delete a namespces it makes more sense to have it inside the function.
055c8c2 to
1cd3d7a
Compare
This PR is adding the following changes:
We also have added the option of using a custom entries file that include ranges, so partners will be able to add their own ranges if needed.
The e2e tests have been modified the following: