6 pb "ovn4nfv-k8s-plugin/internal/pkg/nfnNotify/proto"
7 "ovn4nfv-k8s-plugin/internal/pkg/node"
8 v1alpha1 "ovn4nfv-k8s-plugin/pkg/apis/k8s/v1alpha1"
9 clientset "ovn4nfv-k8s-plugin/pkg/generated/clientset/versioned"
12 "google.golang.org/grpc"
13 "google.golang.org/grpc/reflection"
14 v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
15 "k8s.io/client-go/kubernetes"
16 "k8s.io/client-go/rest"
17 logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
20 var log = logf.Log.WithName("rpc-server")
23 context *pb.SubscribeContext
24 stream pb.NfnNotify_SubscribeServer
27 type serverDB struct {
29 clientList map[string]client
32 var notifServer *serverDB
33 var stopChan chan interface{}
35 var pnClientset *clientset.Clientset
36 var kubeClientset *kubernetes.Clientset
38 func newServer() *serverDB {
39 return &serverDB{name: "nfnNotifServer", clientList: make(map[string]client)}
42 // Subscribe stores the client information & sends data
43 func (s *serverDB) Subscribe(sc *pb.SubscribeContext, ss pb.NfnNotify_SubscribeServer) error {
44 nodeName := sc.GetNodeName()
45 log.Info("Subscribe request from node", "Node Name", nodeName)
47 return fmt.Errorf("Node name can't be empty")
50 nodeIntfIPAddr, nodeIntfMacAddr, err := node.AddNodeLogicalPorts(nodeName)
52 return fmt.Errorf("Error in creating node logical port for node- %s: %v", nodeName, err)
58 s.clientList[nodeName] = cp
60 providerNetworklist, err := pnClientset.K8sV1alpha1().ProviderNetworks("default").List(v1.ListOptions{})
62 for _, pn := range providerNetworklist.Items {
63 log.Info("Send message", "Provider Network", pn.GetName())
64 SendNotif(&pn, "create", nodeName)
67 inSyncMsg := pb.Notification{
69 Payload: &pb.Notification_InSync{
71 NodeIntfIpAddress: nodeIntfIPAddr,
72 NodeIntfMacAddress: nodeIntfMacAddr,
76 log.Info("Send Insync")
77 if err = cp.stream.Send(&inSyncMsg); err != nil {
78 log.Error(err, "Unable to send sync", "node name", nodeName)
80 log.Info("Subscribe Completed")
89 func (s *serverDB) GetClient(nodeName string) client {
90 if val, ok := s.clientList[nodeName]; ok {
96 func updatePnStatus(pn *v1alpha1.ProviderNetwork, status string) error {
97 pnCopy := pn.DeepCopy()
98 pnCopy.Status.State = status
99 _, err := pnClientset.K8sV1alpha1().ProviderNetworks(pn.Namespace).Update(pnCopy)
103 func createVlanMsg(pn *v1alpha1.ProviderNetwork) pb.Notification {
104 msg := pb.Notification{
106 Payload: &pb.Notification_ProviderNwCreate{
107 ProviderNwCreate: &pb.ProviderNetworkCreate{
108 ProviderNwName: pn.Name,
110 VlanId: pn.Spec.Vlan.VlanId,
111 ProviderIntf: pn.Spec.Vlan.ProviderInterfaceName,
112 LogicalIntf: pn.Spec.Vlan.LogicalInterfaceName,
120 func deleteVlanMsg(pn *v1alpha1.ProviderNetwork) pb.Notification {
121 msg := pb.Notification{
123 Payload: &pb.Notification_ProviderNwRemove{
124 ProviderNwRemove: &pb.ProviderNetworkRemove{
125 ProviderNwName: pn.Name,
126 VlanLogicalIntf: pn.Spec.Vlan.LogicalInterfaceName,
133 func createDirectMsg(pn *v1alpha1.ProviderNetwork) pb.Notification {
134 msg := pb.Notification{
136 Payload: &pb.Notification_ProviderNwCreate{
137 ProviderNwCreate: &pb.ProviderNetworkCreate{
138 ProviderNwName: pn.Name,
139 Direct: &pb.DirectInfo{
140 ProviderIntf: pn.Spec.Direct.ProviderInterfaceName,
148 func deleteDirectMsg(pn *v1alpha1.ProviderNetwork) pb.Notification {
149 msg := pb.Notification{
151 Payload: &pb.Notification_ProviderNwRemove{
152 ProviderNwRemove: &pb.ProviderNetworkRemove{
153 ProviderNwName: pn.Name,
154 DirectProviderIntf: pn.Spec.Direct.ProviderInterfaceName,
161 //SendNotif to client
162 func SendNotif(pn *v1alpha1.ProviderNetwork, msgType string, nodeReq string) error {
163 var msg pb.Notification
167 case pn.Spec.CniType == "ovn4nfv":
169 case pn.Spec.ProviderNetType == "VLAN":
170 if msgType == "create" {
171 msg = createVlanMsg(pn)
172 } else if msgType == "delete" {
173 msg = deleteVlanMsg(pn)
175 if strings.EqualFold(pn.Spec.Vlan.VlanNodeSelector, "SPECIFIC") {
176 for _, label := range pn.Spec.Vlan.NodeLabelList {
177 l := strings.Split(label, "=")
179 log.Error(fmt.Errorf("Syntax error label: %v", label), "NodeListIterator")
183 labels := strings.Join(pn.Spec.Vlan.NodeLabelList[:], ",")
184 err = sendMsg(msg, labels, "specific", nodeReq)
185 } else if strings.EqualFold(pn.Spec.Vlan.VlanNodeSelector, "ALL") {
186 err = sendMsg(msg, "", "all", nodeReq)
187 } else if strings.EqualFold(pn.Spec.Vlan.VlanNodeSelector, "ANY") {
188 if pn.Status.State != v1alpha1.Created {
189 err = sendMsg(msg, "", "any", nodeReq)
191 updatePnStatus(pn, v1alpha1.Created)
195 case pn.Spec.ProviderNetType == "DIRECT":
196 if msgType == "create" {
197 msg = createDirectMsg(pn)
198 } else if msgType == "delete" {
199 msg = deleteDirectMsg(pn)
201 if strings.EqualFold(pn.Spec.Direct.DirectNodeSelector, "SPECIFIC") {
202 for _, label := range pn.Spec.Direct.NodeLabelList {
203 l := strings.Split(label, "=")
205 log.Error(fmt.Errorf("Syntax error label: %v", label), "NodeListIterator")
209 labels := strings.Join(pn.Spec.Direct.NodeLabelList[:], ",")
210 err = sendMsg(msg, labels, "specific", nodeReq)
211 } else if strings.EqualFold(pn.Spec.Direct.DirectNodeSelector, "ALL") {
212 err = sendMsg(msg, "", "all", nodeReq)
213 } else if strings.EqualFold(pn.Spec.Direct.DirectNodeSelector, "ANY") {
214 if pn.Status.State != v1alpha1.Created {
215 err = sendMsg(msg, "", "any", nodeReq)
217 updatePnStatus(pn, v1alpha1.Created)
222 return fmt.Errorf("Unsupported Provider Network type")
225 return fmt.Errorf("Unsupported CNI type")
230 // sendMsg send notification to client
231 func sendMsg(msg pb.Notification, labels string, option string, nodeReq string) error {
233 for name, client := range notifServer.clientList {
234 if nodeReq != "" && nodeReq != name {
237 if client.stream != nil {
238 if err := client.stream.Send(&msg); err != nil {
239 log.Error(err, "Msg Send failed", "Node name", name)
244 } else if option == "any" {
245 // Always select the first
246 for _, client := range notifServer.clientList {
247 if client.stream != nil {
248 if err := client.stream.Send(&msg); err != nil {
251 // return after first successful send
257 // This is specific case
258 for name := range nodeListIterator(labels) {
259 if nodeReq != "" && nodeReq != name {
262 client := notifServer.GetClient(name)
263 if client.stream != nil {
264 if err := client.stream.Send(&msg); err != nil {
272 func nodeListIterator(labels string) <-chan string {
273 ch := make(chan string)
275 lo := v1.ListOptions{LabelSelector: labels}
276 // List the Nodes matching the Labels
277 nodes, err := kubeClientset.CoreV1().Nodes().List(lo)
279 log.Info("No Nodes found with labels", "list:", lo)
283 for _, node := range nodes.Items {
284 log.Info("Send message to", " node:", node.ObjectMeta.Name)
285 ch <- node.ObjectMeta.Name
292 //SetupNotifServer initilizes the gRpc nfn notif server
293 func SetupNotifServer(kConfig *rest.Config) {
295 log.Info("Starting Notif Server")
298 // creates the clientset
299 pnClientset, err = clientset.NewForConfig(kConfig)
301 log.Error(err, "Error building clientset")
303 kubeClientset, err = kubernetes.NewForConfig(kConfig)
305 log.Error(err, "Error building Kuberenetes clientset")
308 stopChan = make(chan interface{})
311 lis, err := net.Listen("tcp", ":50000")
313 log.Error(err, "failed to listen")
316 s := grpc.NewServer()
317 // Intialize Notify server
318 notifServer = newServer()
319 pb.RegisterNfnNotifyServer(s, notifServer)
321 reflection.Register(s)
322 log.Info("Initialization Completed")
323 if err := s.Serve(lis); err != nil {
324 log.Error(err, "failed to serve")