istio.io/istio@v0.0.0-20240520182934-d79c90f27776/cni/pkg/plugin/cnieventclient.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package plugin 16 17 import ( 18 "bytes" 19 "context" 20 "encoding/json" 21 "fmt" 22 "net" 23 "net/http" 24 "time" 25 26 "github.com/containernetworking/cni/pkg/skel" 27 cniv1 "github.com/containernetworking/cni/pkg/types/100" 28 29 "istio.io/istio/cni/pkg/nodeagent" 30 ) 31 32 // newCNIClient is a unit test override variable for mocking. 33 var newCNIClient = buildClient 34 35 // An udsCore write entries to an UDS server with HTTP Post. Log messages will be encoded into a JSON array. 36 type CNIEventClient struct { 37 client *http.Client 38 url string 39 } 40 41 func buildClient(address, path string) CNIEventClient { 42 c := &http.Client{ 43 Transport: &http.Transport{ 44 DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { 45 return net.Dial("unix", address) 46 }, 47 }, 48 Timeout: 1000 * time.Millisecond, 49 } 50 eventC := CNIEventClient{ 51 client: c, 52 url: "http://unix" + path, 53 } 54 return eventC 55 } 56 57 func PushCNIEvent(cniClient CNIEventClient, event *skel.CmdArgs, prevResIps []*cniv1.IPConfig, podName, podNamespace string) error { 58 if event == nil { 59 return fmt.Errorf("unable to push CNI event, CmdArgs event was nil") 60 } 61 62 var ncconfigs []nodeagent.IPConfig 63 for _, ipc := range prevResIps { 64 ncconfigs = append(ncconfigs, nodeagent.IPConfig{Interface: ipc.Interface, Address: ipc.Address, Gateway: ipc.Gateway}) 65 } 66 // Currently we only use the netns from the original CNI event 67 addEvent := nodeagent.CNIPluginAddEvent{Netns: event.Netns, PodName: podName, PodNamespace: podNamespace, IPs: ncconfigs} 68 eventData, err := json.Marshal(addEvent) 69 if err != nil { 70 return err 71 } 72 var response *http.Response 73 response, err = cniClient.client.Post(cniClient.url, "application/json", bytes.NewBuffer(eventData)) 74 if err != nil { 75 return err 76 } 77 defer response.Body.Close() 78 79 if response.StatusCode != http.StatusOK { 80 return fmt.Errorf("unable to push CNI event, error was %d", response.StatusCode) 81 } 82 83 return nil 84 }