From 12ab5b0d0c1a1332798d93ea7d332390e1bf2868 Mon Sep 17 00:00:00 2001 From: kanaya516 Date: Wed, 9 Aug 2023 00:05:16 +0900 Subject: [PATCH] complete grpc --- cmd/pola/sr_policy_add.go | 2 +- cmd/pola/sr_policy_delete.go | 100 +++++------------------------ pkg/server/grpc_server.go | 120 ++++++++++++++++++++++++++++------- pkg/server/session.go | 4 +- 4 files changed, 116 insertions(+), 110 deletions(-) diff --git a/cmd/pola/sr_policy_add.go b/cmd/pola/sr_policy_add.go index 1895fdb..7b0c61e 100644 --- a/cmd/pola/sr_policy_add.go +++ b/cmd/pola/sr_policy_add.go @@ -117,7 +117,7 @@ func addSRPolicyNoLinkState(input InputFormat) error { " - sid: 16002\n\n" errMsg := "invalid input\n" + - "input examplse is below\n\n" + + "input example is below\n\n" + sampleInput return errors.New(errMsg) } diff --git a/cmd/pola/sr_policy_delete.go b/cmd/pola/sr_policy_delete.go index 1e6b71a..ab070b9 100644 --- a/cmd/pola/sr_policy_delete.go +++ b/cmd/pola/sr_policy_delete.go @@ -19,7 +19,7 @@ import ( func newSRPolicyDeleteCmd() *cobra.Command { srPolicyDeleteCmd := &cobra.Command{ - Use: "add", + Use: "delete", RunE: func(cmd *cobra.Command, args []string) error { filepath, err := cmd.Flags().GetString("file") @@ -38,7 +38,6 @@ func newSRPolicyDeleteCmd() *cobra.Command { InputData := InputFormat{} if err := yaml.NewDecoder(f).Decode(&InputData); err != nil { return fmt.Errorf("file \"%s\" can't open", filepath) - } if err := deleteSRPolicy(InputData, jsonFmt); err != nil { return err @@ -54,99 +53,24 @@ func newSRPolicyDeleteCmd() *cobra.Command { } func deleteSRPolicy(input InputFormat, jsonFlag bool) error { - if err := deleteSRPolicyLinkState(input); err != nil { - return err - } - - if jsonFlag { - fmt.Printf("{\"status\": \"success\"}\n") - } else { - fmt.Printf("success!\n") - } - - return nil -} - -func deleteSRPolicyLinkState(input InputFormat) error { - sampleInputDynamic := "#case: dynamic path\n" + - "asn: 65000\n" + - "srPolicy:\n" + - " pcepSessionAddr: 192.0.2.1\n" + - " srcRouterID: 0000.0aff.0001\n" + - " dstRouterID: 0000.0aff.0004\n" + - " name: name\n" + - " color: 100\n" + - " type: dynamic\n" + - " metric: igp / te / delay\n" - sampleInputExplicit := "#case: explicit path\n" + - "asn: 65000\n" + - "srPolicy:\n" + - " pcepSessionAddr: 192.0.2.1\n" + - " srcRouterID: 0000.0aff.0001\n" + - " dstRouterID: 0000.0aff.0002\n" + - " name: name\n" + - " color: 100\n" + - " type: explicit\n" + - " segmentList:\n" + - " - sid: 16003\n" + - " - sid: 16002\n" - if input.Asn == 0 || !input.SRPolicy.PcepSessionAddr.IsValid() || input.SRPolicy.Color == 0 || input.SRPolicy.SrcRouterID == "" || input.SRPolicy.DstRouterID == "" { + if !input.SRPolicy.PcepSessionAddr.IsValid() || input.SRPolicy.Color == 0 || !input.SRPolicy.DstAddr.IsValid() || input.SRPolicy.Name == "" { + sampleInput := "srPolicy:\n" + + " pcepSessionAddr: 192.0.2.1\n" + + " dstAddr: 192.0.2.2\n" + + " color: 100\n" + + " name: name\n" errMsg := "invalid input\n" + "input example is below\n\n" + - sampleInputDynamic + - sampleInputExplicit + - "or, if create SR Policy without TED, then use `--no-link-state` flag\n" + sampleInput return errors.New(errMsg) } - var srPolicyType pb.SRPolicyType - var metric pb.MetricType - var segmentList []*pb.Segment - switch input.SRPolicy.Type { - case "explicit": - if len(input.SRPolicy.SegmentList) == 0 { - errMsg := "invalid input\n" + - "input example is below\n\n" + - sampleInputExplicit - - return errors.New(errMsg) - } - srPolicyType = pb.SRPolicyType_EXPLICIT - for _, seg := range input.SRPolicy.SegmentList { - segmentList = append(segmentList, &pb.Segment{Sid: seg.Sid}) - } - case "dynamic": - if input.SRPolicy.Metric == "" { - errMsg := "invalid input\n" + - "input example is below\n\n" + - sampleInputDynamic - return errors.New(errMsg) - } - srPolicyType = pb.SRPolicyType_DYNAMIC - switch input.SRPolicy.Metric { - case "igp": - metric = pb.MetricType_IGP - case "delay": - metric = pb.MetricType_DELAY - case "te": - metric = pb.MetricType_TE - default: - return fmt.Errorf("invalid input `metric`") - } - - default: - return fmt.Errorf("invalid input `type`") - } srPolicy := &pb.SRPolicy{ PcepSessionAddr: input.SRPolicy.PcepSessionAddr.AsSlice(), - SrcRouterID: input.SRPolicy.SrcRouterID, - DstRouterID: input.SRPolicy.DstRouterID, + DstAddr: input.SRPolicy.DstAddr.AsSlice(), Color: input.SRPolicy.Color, PolicyName: input.SRPolicy.Name, - Type: srPolicyType, - SegmentList: segmentList, - Metric: metric, } inputData := &pb.DeleteSRPolicyInput{ SRPolicy: srPolicy, @@ -156,5 +80,11 @@ func deleteSRPolicyLinkState(input InputFormat) error { return fmt.Errorf("gRPC Server Error: %s", err.Error()) } + if jsonFlag { + fmt.Printf("{\"status\": \"success\"}\n") + } else { + fmt.Printf("success!\n") + } + return nil } diff --git a/pkg/server/grpc_server.go b/pkg/server/grpc_server.go index 5a4b43b..d8f5d93 100644 --- a/pkg/server/grpc_server.go +++ b/pkg/server/grpc_server.go @@ -56,9 +56,18 @@ func (s *APIServer) CreateSRPolicyWithoutLinkState(ctx context.Context, input *p } func (s *APIServer) createSRPolicy(ctx context.Context, input *pb.CreateSRPolicyInput, withLinkState bool) (*pb.RequestStatus, error) { - err := validate(input.GetSRPolicy(), input.GetAsn(), withLinkState) - if err != nil { - return &pb.RequestStatus{IsSuccess: false}, err + var err error + + if withLinkState { + err = validate(input.GetSRPolicy(), input.GetAsn(), ValidationAdd) + if err != nil { + return &pb.RequestStatus{IsSuccess: false}, err + } + } else { + err = validate(input.GetSRPolicy(), input.GetAsn(), ValidationAddWithoutLinkState) + if err != nil { + return &pb.RequestStatus{IsSuccess: false}, err + } } inputSRPolicy := input.GetSRPolicy() @@ -117,7 +126,7 @@ func (s *APIServer) createSRPolicy(ctx context.Context, input *pb.CreateSRPolicy Preference: 100, } - if id, exists := pcepSession.SearchSRPolicyPlspID(inputSRPolicy.GetColor(), dstAddr); exists { + if id, exists := pcepSession.SearchPlspID(inputSRPolicy.GetColor(), dstAddr); exists { // Update SR Policy s.pce.logger.Info("plspID check", zap.Uint32("plspID", id), zap.String("server", "grpc")) srPolicy.PlspID = id @@ -135,35 +144,102 @@ func (s *APIServer) createSRPolicy(ctx context.Context, input *pb.CreateSRPolicy return &pb.RequestStatus{IsSuccess: true}, nil } -func validate(inputSRPolicy *pb.SRPolicy, asn uint32, withLinkState bool) error { - var validator func(policy *pb.SRPolicy, asn uint32) bool +func (s *APIServer) DeleteSRPolicy(ctx context.Context, input *pb.DeleteSRPolicyInput) (*pb.RequestStatus, error) { + return s.deleteSRPolicy(ctx, input) +} - if withLinkState { - validator = validateInput +func (s *APIServer) deleteSRPolicy(ctx context.Context, input *pb.DeleteSRPolicyInput) (*pb.RequestStatus, error) { + err := validate(input.GetSRPolicy(), input.GetAsn(), ValidationDelete) + if err != nil { + return &pb.RequestStatus{IsSuccess: false}, err + } + + inputSRPolicy := input.GetSRPolicy() + var srcAddr, dstAddr netip.Addr + var segmentList []table.Segment + + srcAddr, _ = netip.AddrFromSlice(inputSRPolicy.GetSrcAddr()) + dstAddr, _ = netip.AddrFromSlice(inputSRPolicy.GetDstAddr()) + for _, segment := range inputSRPolicy.GetSegmentList() { + seg, err := table.NewSegment(segment.GetSid()) + if err != nil { + return &pb.RequestStatus{IsSuccess: false}, err + } + segmentList = append(segmentList, seg) + } + + inputJson, err := json.Marshal(input) + if err != nil { + return nil, err + } + s.pce.logger.Info("received DeleteSRPolicy API request", zap.String("input", string(inputJson)), zap.String("server", "grpc")) + + pcepSession, err := getPcepSession(s.pce, inputSRPolicy.GetPcepSessionAddr()) + if err != nil { + return &pb.RequestStatus{IsSuccess: false}, err + } + + srPolicy := table.SRPolicy{ + Name: inputSRPolicy.GetPolicyName(), + SegmentList: segmentList, + SrcAddr: srcAddr, + DstAddr: dstAddr, + Color: inputSRPolicy.GetColor(), + Preference: 100, + } + + if id, exists := pcepSession.SearchPlspID(inputSRPolicy.GetColor(), dstAddr); exists { + // Delete SR Policy + s.pce.logger.Info("plspID check", zap.Uint32("plspID", id), zap.String("server", "grpc")) + srPolicy.PlspID = id + + if err := pcepSession.RequestSRPolicyDeleted(srPolicy); err != nil { + return &pb.RequestStatus{IsSuccess: false}, nil + } } else { - validator = validateInputWithoutLinkState + // Invalid SR Policy + return &pb.RequestStatus{IsSuccess: false}, fmt.Errorf("SR Policy not found") } - if !validator(inputSRPolicy, asn) { + return &pb.RequestStatus{IsSuccess: true}, nil +} + +func validate(inputSRPolicy *pb.SRPolicy, asn uint32, validationKind ValidationKind) error { + if !validator[validationKind](inputSRPolicy, asn) { return errors.New("invalid input") } return nil } -func validateInput(policy *pb.SRPolicy, asn uint32) bool { - return asn != 0 && - policy.PcepSessionAddr != nil && - policy.Color != 0 && - policy.SrcRouterID != "" && - policy.DstRouterID != "" -} +type ValidationKind string + +const ( + ValidationAdd ValidationKind = "Add" + ValidationAddWithoutLinkState ValidationKind = "AddWithoutLinkState" + ValidationDelete ValidationKind = "Delete" +) -func validateInputWithoutLinkState(policy *pb.SRPolicy, asn uint32) bool { - return policy.PcepSessionAddr != nil && - len(policy.SrcAddr) > 0 && - len(policy.DstAddr) > 0 && - len(policy.SegmentList) > 0 +var validator = map[ValidationKind]func(policy *pb.SRPolicy, asn uint32) bool{ + ValidationKind("Add"): func(policy *pb.SRPolicy, asn uint32) bool { + return asn != 0 && + policy.PcepSessionAddr != nil && + policy.Color != 0 && + policy.SrcRouterID != "" && + policy.DstRouterID != "" + }, + ValidationKind("AddWithoutLinkState"): func(policy *pb.SRPolicy, asn uint32) bool { + return policy.PcepSessionAddr != nil && + len(policy.SrcAddr) > 0 && + len(policy.DstAddr) > 0 && + len(policy.SegmentList) > 0 + }, + ValidationKind("Delete"): func(policy *pb.SRPolicy, asn uint32) bool { + return policy.PcepSessionAddr != nil && + policy.Color != 0 && + len(policy.DstAddr) > 0 && + policy.PolicyName != "" + }, } func getPcepSession(pce *Server, addr []byte) (*Session, error) { diff --git a/pkg/server/session.go b/pkg/server/session.go index 07af6e9..aa43763 100644 --- a/pkg/server/session.go +++ b/pkg/server/session.go @@ -409,8 +409,8 @@ func (ss *Session) SearchSRPolicy(plspID uint32) (*table.SRPolicy, bool) { return nil, false } -// SearchSRPolicyPlspID returns the PLSP-ID of a registered SR Policy, along with a boolean value indicating if it was found. -func (ss *Session) SearchSRPolicyPlspID(color uint32, endpoint netip.Addr) (uint32, bool) { +// SearchPlspID returns the PLSP-ID of a registered SR Policy, along with a boolean value indicating if it was found. +func (ss *Session) SearchPlspID(color uint32, endpoint netip.Addr) (uint32, bool) { for _, v := range ss.srPolicies { if v.Color == color && v.DstAddr == endpoint { return v.PlspID, true