Change:
<!-- Please only use this template for submitting enhancement requests --What would you like to be : Ive done preliminary testing with on calico powered clusters on some windows variants and found that the probing seems to work. Can we add wrapper to netpol suite so that we can run it on windows clusters ? Why is this needed: We need this because otherwise, CNIs such as EKS will give us This error is caused when, for example, pods that are landing on a windows node havent defined their target platform. Somehow i guess pods which are landing on linux nodes dont have this issue. Its also needed for the obvious reason that we probably want separate linux and windows test suites for policies, in general, even though we expect the logic to be identical (modulo hostports , which we dont currently test)
This issue is currently awaiting triage. If a SIG or subproject determines this is a relevant issue, they will accept it by applying the label and provide further guidance. The label can be by org members by writing in a comment. <detailsInstructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/sig windows
/assign
grepping around, I can't figure out where those are supposed to go. Can you give me pointers?
(resolved in slack, matts digging into this)
ok, these are running now on eks, lots of failures. will dig
/assign
the netpol are not being applied for the ns: Instead of failing because should not be able to access , the connection succeeds.

Discussion:
for _, pod := range ns.Pods { framework.Logf("creating/updating pod %s/%s", ns.Name, pod.Name) <ins> // note that we defer the logic of pod (i.e. node selector) specifics to the model // which is aware of linux vs windows pods </ins> kubePod, err := k.createPod(pod.KubePod()) if err != nil { return err } <del> createdPods = append(createdPods, kubePod) </del> <ins> createdPods = append(createdPods, kubePod) </ins> _, err = k.createService(pod.Service()) if err != nil { return err

} // probeConnectivity execs into a pod and checks its connectivity to another pod.. <del> func (k *kubeManager) probeConnectivity(nsFrom string, podFrom string, containerFrom string, addrTo string, protocol v1.Protocol, toPort int) (bool, string, error) { </del> <ins> func (k *kubeManager) probeConnectivity(nsFrom string, podFrom string, containerFrom string, addrTo string, protocol v1.Protocol, toPort int, timeoutSeconds int) (bool, string, error) { </ins> port := strconv.Itoa(toPort) var cmd []string <ins> timeout := fmt.Sprintf("--timeout=%vs", timeoutSeconds) </ins> switch protocol { case v1.ProtocolSCTP: <del> cmd = []string{"/agnhost", "connect", net.JoinHostPort(addrTo, port), "--timeout=1s", "--protocol=sctp"} </del> <ins> cmd = []string{"/agnhost", "connect", net.JoinHostPort(addrTo, port), timeout, "--protocol=sctp"} </ins> case v1.ProtocolTCP: <del> cmd = []string{"/agnhost", "connect", net.JoinHostPort(addrTo, port), "--timeout=1s", "--protocol=tcp"} </del> <ins> cmd = []string{"/agnhost", "connect", net.JoinHostPort(addrTo, port), timeout, "--protocol=tcp"} </ins> case v1.ProtocolUDP: <del> cmd = []string{"/agnhost", "connect", net.JoinHostPort(addrTo, port), "--timeout=1s", "--protocol=udp"} </del> <ins> cmd = []string{"/agnhost", "connect", net.JoinHostPort(addrTo, port), timeout, "--protocol=udp"} if framework.NodeOSDistroIs("windows") { framework.Logf("probing UDP for windows may result in cluster instability for certain windows nodes with low CPU/Memory, depending on CRI version") } </ins> default: framework.Failf("protocol %s not supported", protocol) }

return nil } <del> // waitForHTTPServers waits for all webservers to be up, on all protocols, and then validates them using the same probe logic as the rest of the suite. </del> <ins> // waitForHTTPServers waits for all webservers to be up, on all protocols sent in the input,  and then validates them using the same probe logic as the rest of the suite. </ins> func (k *kubeManager) waitForHTTPServers(model *Model) error { const maxTries = 10 framework.Logf("waiting for HTTP servers (ports 80 and 81) to become ready") testCases := map[string]*TestCase{} for _, port := range model.Ports { <ins> // Protocols is provided as input so that we can skip udp polling for windows </ins> for _, protocol := range model.Protocols { fromPort := 81 desc := fmt.Sprintf("%d->%d,%s", fromPort, port, protocol)

DNSDomain      string } <ins> // NewWindowsModel returns a model specific to windows testing. func NewWindowsModel(namespaces []string, podNames []string, ports []int32, dnsDomain string) *Model { return NewModel(namespaces, podNames, ports, []v1.Protocol{v1.ProtocolTCP}, dnsDomain) } // GetProbeTimeoutSeconds returns a timeout for how long the probe should work before failing a check, and takes windows heuristics into account, where requests can take longer sometimes. func (m *Model) GetProbeTimeoutSeconds() int { timeoutSeconds := 1 if framework.NodeOSDistroIs("windows") { timeoutSeconds = 3 } return timeoutSeconds } // GetWorkers returns the number of workers suggested to run when testing, taking windows heuristics into account, where parallel probing is flakier. func (m *Model) GetWorkers() int { numberOfWorkers := 3 if framework.NodeOSDistroIs("windows") { numberOfWorkers = 1 // See https://github.com/kubernetes/kubernetes/pull/97690 } return numberOfWorkers } </ins> // NewModel instantiates a model based on: // - namespaces // - pods

} } <del> // KubePod returns the kube pod </del> <ins> // KubePod returns the kube pod (will add label selectors for windows if needed). </ins> func (p *Pod) KubePod() *v1.Pod { zero := int64(0) <del> return &v1.Pod{ </del> <ins> thePod := &v1.Pod{ </ins> ObjectMeta: metav1.ObjectMeta{ Name:      p.Name, Labels:    p.LabelSelector(),

Containers:                    p.ContainerSpecs(), }, } <ins> if framework.NodeOSDistroIs("windows") { thePod.Spec.NodeSelector = map[string]string{ "kubernetes.io/os": "windows", } } return thePod </ins> } // QualifiedServiceAddress returns the address that can be used to hit a service from

z/c	.	.	.	.	.	.	.	.	. */ <del> var _ = common.SIGDescribe("Netpol [LinuxOnly]", func() { </del> <ins> var _ = common.SIGDescribe("Netpol", func() { </ins> f := framework.NewDefaultFramework("netpol") ginkgo.Context("NetworkPolicy between server and client", func() {

if addSCTPContainers { protocols = append(protocols, v1.ProtocolSCTP) } <ins> if framework.NodeOSDistroIs("windows") { return NewWindowsModel(namespaces, []string{"a", "b", "c"}, []int32{80, 81}, dnsDomain) } </ins> return NewModel(namespaces, []string{"a", "b", "c"}, []int32{80, 81}, protocols, dnsDomain) }

// ProbePodToPodConnectivity runs a series of probes in kube, and records the results in `testCase.Reachability` func ProbePodToPodConnectivity(k8s *kubeManager, model *Model, testCase *TestCase) { <del> numberOfWorkers := 3 // See https://github.com/kubernetes/kubernetes/pull/97690 </del> allPods := model.AllPods() size := len(allPods) * len(allPods) jobs := make(chan *ProbeJob, size) results := make(chan *ProbeJobResults, size) <del> for i := 0; i < numberOfWorkers; i++ { go probeWorker(k8s, jobs, results) </del> <ins> for i := 0; i < model.GetWorkers(); i++ { go probeWorker(k8s, jobs, results, model.GetProbeTimeoutSeconds()) </ins> } for _, podFrom := range allPods { for _, podTo := range allPods {

// probeWorker continues polling a pod connectivity status, until the incoming "jobs" channel is closed, and writes results back out to the "results" channel. // it only writes pass/fail status to a channel and has no failure side effects, this is by design since we do not want to fail inside a goroutine. <del> func probeWorker(k8s *kubeManager, jobs <-chan *ProbeJob, results chan<- *ProbeJobResults) { </del> <ins> func probeWorker(k8s *kubeManager, jobs <-chan *ProbeJob, results chan<- *ProbeJobResults, timeoutSeconds int) { </ins> defer ginkgo.GinkgoRecover() for job := range jobs { podFrom := job.PodFrom <del> connected, command, err := k8s.probeConnectivity(podFrom.Namespace, podFrom.Name, podFrom.Containers[0].Name(), job.PodTo.QualifiedServiceAddress(job.ToPodDNSDomain), job.Protocol, job.ToPort) </del> <ins> connected, command, err := k8s.probeConnectivity(podFrom.Namespace, podFrom.Name, podFrom.Containers[0].Name(), job.PodTo.QualifiedServiceAddress(job.ToPodDNSDomain), job.Protocol, job.ToPort, timeoutSeconds) </ins> result := &ProbeJobResults{ Job:         job, IsConnected: connected,