package server import ( "bytes" "cfTest/cloudflareApi/zone" "context" "encoding/json" "errors" "fmt" "github.com/cloudflare/cloudflare-go" "github.com/samber/lo" "io" "io/ioutil" "log" "net/http" ) type ZoneServer struct { zone.UnimplementedZoneCloudflareServer } func (s *ZoneServer) ZoneIDByNameCloudflare(ctx context.Context, requestCloudflare *zone.ZoneIDByNameRequestCloudflare) (*zone.ZoneIDByNameReplyCloudflare, error) { log.Printf("apiKey Received: %v", requestCloudflare.GetApiKey()) log.Printf("apiEmail Received: %v", requestCloudflare.GetApiEmail()) log.Printf("zoneName Received: %v", requestCloudflare.GetZoneName()) api, err := cloudflare.New(requestCloudflare.GetApiKey(), requestCloudflare.GetApiEmail()) if err != nil { return nil, err } id, err := api.ZoneIDByName(requestCloudflare.ZoneName) if err != nil { return nil, err } return &zone.ZoneIDByNameReplyCloudflare{ZoneId: id}, err } func (s *ZoneServer) ZoneDetails(ctx context.Context, requestCloudflare *zone.ZoneDetailsRequestCloudflare) (*zone.ZoneDetailsReplyCloudflare, error) { log.Printf("apiKey Received: %v", requestCloudflare.GetApiKey()) log.Printf("apiEmail Received: %v", requestCloudflare.GetApiEmail()) log.Printf("zoneId Received: %v", requestCloudflare.GetZoneId()) api, err := cloudflare.New(requestCloudflare.GetApiKey(), requestCloudflare.GetApiEmail()) if err != nil { return nil, err } ctxAPI := context.Background() details, err := api.ZoneDetails(ctxAPI, requestCloudflare.GetZoneId()) if err != nil { return nil, err } return &zone.ZoneDetailsReplyCloudflare{ Result: Go2ProtoZone(details), }, err } func (s *ZoneServer) GetZones(ctx context.Context, requestCloudflare *zone.GetZonesRequestCloudflare) (*zone.GetZonesReplyCloudflare, error) { log.Printf("apiKey Received: %v", requestCloudflare.GetApiKey()) log.Printf("apiEmail Received: %v", requestCloudflare.GetApiEmail()) log.Printf("domain Received: %v", requestCloudflare.GetDomain()) api, err := cloudflare.New(requestCloudflare.GetApiKey(), requestCloudflare.GetApiEmail()) if err != nil { return nil, err } ctxAPI := context.Background() details, err := api.ListZones(ctxAPI, "name", requestCloudflare.GetDomain()) if err != nil { return nil, err } list := make([]*zone.ZoneCloudflareEntity, len(details)) for i, detail := range details { list[i] = Go2ProtoZone(detail) } return &zone.GetZonesReplyCloudflare{ Result: list, Success: true, }, err } func (s *ZoneServer) ListZones(ctx context.Context, requestCloudflare *zone.ListZonesRequestCloudflare) (*zone.ZonesList, error) { log.Printf("apiKey Received: %v", requestCloudflare.GetApiKey()) log.Printf("apiEmail Received: %v", requestCloudflare.GetApiEmail()) api, err := cloudflare.New(requestCloudflare.GetApiKey(), requestCloudflare.GetApiEmail()) if err != nil { return nil, err } ctxAPI := context.Background() details, err := api.ListZones(ctxAPI) if err != nil { return nil, err } list := make([]*zone.ZoneCloudflareEntity, len(details)) for i, detail := range details { list[i] = Go2ProtoZone(detail) } return &zone.ZonesList{ Result: list, }, err } func (s *ZoneServer) ListZonesByAccountId(ctx context.Context, requestCloudflare *zone.ListZonesByAccountIdRequestCloudflare) (*zone.ZonesList, error) { log.Printf("apiKey Received: %v", requestCloudflare.GetApiKey()) log.Printf("apiEmail Received: %v", requestCloudflare.GetApiEmail()) log.Printf("accountId Received: %v", requestCloudflare.GetAccountId()) api, err := cloudflare.New(requestCloudflare.GetApiKey(), requestCloudflare.GetApiEmail()) if err != nil { return nil, err } ctxAPI := context.Background() opt := cloudflare.WithZoneFilters("", requestCloudflare.AccountId, "") details, err := api.ListZonesContext(ctxAPI, opt) if err != nil { return nil, err } list := make([]*zone.ZoneCloudflareEntity, len(details.Result)) for i, detail := range details.Result { list[i] = Go2ProtoZone(detail) } return &zone.ZonesList{ Result: list, }, err } func (s *ZoneServer) EditZone(ctx context.Context, requestCloudflare *zone.EditZoneRequestCloudflare) (*zone.EditZoneReplyCloudflare, error) { log.Printf("apiKey Received: %v", requestCloudflare.GetApiKey()) log.Printf("apiEmail Received: %v", requestCloudflare.GetApiEmail()) log.Printf("zoneId Received: %v", requestCloudflare.GetZoneId()) api, err := cloudflare.New(requestCloudflare.GetApiKey(), requestCloudflare.GetApiEmail()) if err != nil { return nil, err } ctxAPI := context.Background() opts := cloudflare.ZoneOptions{} opts.Paused = requestCloudflare.Paused if requestCloudflare.PlanId != nil { opts.Plan = &cloudflare.ZonePlan{ ZonePlanCommon: cloudflare.ZonePlanCommon{ ID: requestCloudflare.GetPlanId(), }, } } if requestCloudflare.Type != nil { opts.Type = requestCloudflare.GetType() } editZone, err := api.EditZone(ctxAPI, requestCloudflare.GetZoneId(), opts) if err != nil { return nil, err } return &zone.EditZoneReplyCloudflare{ Result: Go2ProtoZone(editZone), Success: true, }, nil } func (s *ZoneServer) DeleteZone(ctx context.Context, requestCloudflare *zone.DeleteZoneRequestCloudflare) (*zone.DeleteZoneReplyCloudflare, error) { log.Printf("apiKey Received: %v", requestCloudflare.GetApiKey()) log.Printf("apiEmail Received: %v", requestCloudflare.GetApiEmail()) log.Printf("zoneId Received: %v", requestCloudflare.GetZoneId()) api, err := cloudflare.New(requestCloudflare.GetApiKey(), requestCloudflare.GetApiEmail()) if err != nil { return nil, err } ctxAPI := context.Background() deleteZone, err := api.DeleteZone(ctxAPI, requestCloudflare.GetZoneId()) if err != nil { return nil, err } return &zone.DeleteZoneReplyCloudflare{ Success: true, Id: deleteZone.ID, }, nil } func (s *ZoneServer) ActivationCheck(ctx context.Context, requestCloudflare *zone.ActivationCheckRequestCloudflare) (*zone.ActivationCheckReplyCloudflare, error) { log.Printf("apiKey Received: %v", requestCloudflare.GetApiKey()) log.Printf("apiEmail Received: %v", requestCloudflare.GetApiEmail()) log.Printf("zoneId Received: %v", requestCloudflare.GetZoneId()) api, err := cloudflare.New(requestCloudflare.GetApiKey(), requestCloudflare.GetApiEmail()) if err != nil { return nil, err } ctxAPI := context.Background() activationCheck, err := api.ZoneActivationCheck(ctxAPI, requestCloudflare.GetZoneId()) if err != nil { return nil, err } return &zone.ActivationCheckReplyCloudflare{ Success: activationCheck.Success, }, nil } var phaseMap = map[zone.Phase]string{ zone.Phase_http_request_sanitize: "http_request_sanitize", zone.Phase_http_request_transform: "http_request_transform", //zone.Phase_http_request_origin: "http_request_origin", //zone.Phase_http_request_cache_settings: "http_request_cache_settings", //zone.Phase_http_config_settings: "http_config_settings", //zone.Phase_http_request_dynamic_redirect: "http_request_dynamic_redirect", //zone.Phase_ddos_l7: "ddos_l7", //zone.Phase_http_request_firewall_custom: "http_request_firewall_custom", //zone.Phase_http_ratelimit: "http_ratelimit", //zone.Phase_http_request_firewall_managed: "http_request_firewall_managed", //zone.Phase_http_request_sbfm: "http_request_sbfm", //zone.Phase_http_request_redirect: "http_request_redirect", zone.Phase_http_request_late_transform: "http_request_late_transform", //zone.Phase_http_custom_errors: "http_custom_errors", zone.Phase_http_response_headers_transform: "http_response_headers_transform", //zone.Phase_http_response_firewall_managed: "http_response_firewall_managed", //zone.Phase_http_log_custom_fields: "http_log_custom_fields", } func (s *ZoneServer) GetRuleSet(ctx context.Context, requestCloudflare *zone.GetRuleSetRequestCloudflare) (*zone.RuleList, error) { api, err := cloudflare.New(requestCloudflare.ApiKey, requestCloudflare.ApiEmail) if err != nil { return nil, err } ctxAPI := context.Background() switch phaseMap[requestCloudflare.Phase] { case "http_request_transform", "http_request_late_transform", "http_response_headers_transform": default: return nil, errors.New("未定义规则阶段") } ruleset, err := api.GetZoneRulesetPhase(ctxAPI, requestCloudflare.ZoneId, phaseMap[requestCloudflare.Phase]) if err != nil { _, ok := err.(*cloudflare.NotFoundError) if ok { ruleset.Rules = make([]cloudflare.RulesetRule, 0) err = nil } else { return nil, err } } filterMap := lo.FilterMap[cloudflare.RulesetRule, *zone.Rule](ruleset.Rules, func(rule cloudflare.RulesetRule, _ int) (*zone.Rule, bool) { phase, err := Go2ProtoRuleRuleByPhase(&rule, ruleset.Phase) if err != nil { return nil, false } return phase, true }) return &zone.RuleList{Rules: filterMap}, nil } func (s *ZoneServer) UpdateRuleSet(ctx context.Context, requestCloudflare *zone.UpdateRuleSetRequestCloudflare) (*zone.RuleList, error) { api, err := cloudflare.New(requestCloudflare.ApiKey, requestCloudflare.ApiEmail) if err != nil { return nil, err } ctxAPI := context.Background() phase := phaseMap[requestCloudflare.Phase] filterMap := lo.FilterMap[*zone.Rule, cloudflare.RulesetRule](requestCloudflare.Rules, func(rule *zone.Rule, index int) (cloudflare.RulesetRule, bool) { ruleResult, err := Proto2GoRulesetRuleByPhase(rule, requestCloudflare.Phase) if err != nil || ruleResult == nil { return cloudflare.RulesetRule{}, false } return *ruleResult, true }) //for _, rule := range requestCloudflare.Rules { // ruleResult, err := Proto2GoRulesetRuleByPhase(rule, requestCloudflare.Phase) // if err != nil { // return nil, err // } // if ruleResult != nil { // ruleSet.Rules = append(ruleSet.Rules, *ruleResult) // } //} ruleset, err := api.UpdateZoneRulesetPhase(ctxAPI, requestCloudflare.ZoneId, phase, cloudflare.Ruleset{ Rules: filterMap, }) if err != nil { return nil, err } rulesReturn := lo.FilterMap[cloudflare.RulesetRule, *zone.Rule](ruleset.Rules, func(rule cloudflare.RulesetRule, _ int) (*zone.Rule, bool) { ruleReturn, err := Go2ProtoRuleRuleByPhase(&rule, ruleset.Phase) if err != nil { return nil, false } return ruleReturn, true }) //var rulesReturn []*zone.Rule //for _, rule := range rulesetResult.Rules { // ruleReturn, err := Go2ProtoRuleRuleByPhase(&rule, rulesetResult.Phase) // if err != nil { // return nil, err // } // if ruleReturn != nil { // rulesReturn = append(rulesReturn, ruleReturn) // } //} return &zone.RuleList{Rules: rulesReturn}, nil } //func UpdateRuleSet(apiKey, apiEmail, zoneID, rulesetPhase string, ruleset cloudflare.Ruleset) (*cloudflare.Ruleset, error) { // api, err := cloudflare.New(apiKey, apiEmail) // if err != nil { // return nil, err // } // ctxAPI := context.Background() // phase, err := api.UpdateZoneRulesetPhase(ctxAPI, zoneID, rulesetPhase, ruleset) // if err != nil { // return nil, err // } // return &phase, nil //} //PageRule CURD func (s *ZoneServer) ListPageRule(ctx context.Context, requestCloudflare *zone.ListPageRuleRequestCloudflare) (*zone.PageRuleList, error) { api, err := cloudflare.New(requestCloudflare.GetApiKey(), requestCloudflare.GetApiEmail()) if err != nil { return nil, err } ctxAPI := context.Background() rules, err := api.ListPageRules(ctxAPI, requestCloudflare.GetZoneId()) if err != nil { return nil, err } filterMap := lo.FilterMap[cloudflare.PageRule, *zone.PageRule](rules, func(rule cloudflare.PageRule, _ int) (*zone.PageRule, bool) { pageRule := Go2ProtoPageRule(&rule) return pageRule, true }) return &zone.PageRuleList{PageRules: filterMap}, nil } func (s *ZoneServer) CreatePageRule(ctx context.Context, requestCloudflare *zone.CreatePageRuleRequestCloudflare) (*zone.PageRule, error) { api, err := cloudflare.New(requestCloudflare.GetApiKey(), requestCloudflare.GetApiEmail()) if err != nil { return nil, err } ctxAPI := context.Background() rule, err := Proto2GoPageRule(requestCloudflare.PageRule) if err != nil { return nil, err } pageRule, err := api.CreatePageRule(ctxAPI, requestCloudflare.GetZoneId(), *rule) if err != nil { return nil, err } return Go2ProtoPageRule(pageRule), nil } func (s *ZoneServer) UpdatePageRule(ctx context.Context, requestCloudflare *zone.UpdatePageRuleRequestCloudflare) (*zone.PageRule, error) { api, err := cloudflare.New(requestCloudflare.GetApiKey(), requestCloudflare.GetApiEmail()) if err != nil { return nil, err } ctxAPI := context.Background() rule, err := Proto2GoPageRule(requestCloudflare.PageRule) if err != nil { return nil, err } err = api.UpdatePageRule(ctxAPI, requestCloudflare.GetZoneId(), rule.ID, *rule) if err != nil { return nil, err } return requestCloudflare.PageRule, nil } func (s *ZoneServer) DeletePageRule(ctx context.Context, requestCloudflare *zone.DeletePageRuleRequestCloudflare) (*zone.PageRule, error) { api, err := cloudflare.New(requestCloudflare.GetApiKey(), requestCloudflare.GetApiEmail()) if err != nil { return nil, err } ctxAPI := context.Background() err = api.DeletePageRule(ctxAPI, requestCloudflare.ZoneId, requestCloudflare.PageRuleId) if err != nil { return nil, err } return &zone.PageRule{}, nil } //func UpdatePageRule(apiKey, apiEmail, zoneID string, rule *zone.PageRule) (*zone.PageRule, error) { // api, err := cloudflare.New(apiKey, apiEmail) // if err != nil { // return nil, err // } // // ctxAPI := context.Background() // goPageRule, err := Proto2GoPageRule(rule) // if err != nil { // return nil, err // } // pageRule, err := api.CreatePageRule(ctxAPI, zoneID, *goPageRule) // if err != nil { // return nil, err // } // // protoPageRule := Go2ProtoPageRule(pageRule) // // return protoPageRule, nil //} type PageRuleActionCacheKeyFieldsQueryString struct { Exclude interface{} `json:"exclude"` Include interface{} `json:"include"` } type PageRuleActionCacheKeyFields struct { QueryString PageRuleActionCacheKeyFieldsQueryString `json:"query_string"` } type UpdatePageRulesPrioritiesStruct struct { Id string `json:"id"` Priority int `json:"priority"` } func (s *ZoneServer) UpdatePageRulesPriorities(ctx context.Context, requestCloudflare *zone.UpdatePageRulesPrioritiesRequestCloudflare) (*zone.PageRuleList, error) { //TODO 参数检查 //设置HTTP请求 client := &http.Client{} bytesData, err := json.Marshal(requestCloudflare.Data) if err != nil { return nil, err } req, err := http.NewRequest("PUT", "https://api.cloudflare.com/client/v4/zones/"+requestCloudflare.ZoneId+"/pagerules/priorities", bytes.NewReader(bytesData)) if err != nil { return nil, err } req.Header.Add("X-Auth-Key", requestCloudflare.GetApiKey()) req.Header.Add("X-Auth-Email", requestCloudflare.GetApiEmail()) //执行HTTP请求 resp, err := client.Do(req) if err != nil { return nil, err } defer func(Body io.ReadCloser) { _ = Body.Close() }(resp.Body) body, _ := ioutil.ReadAll(resp.Body) //解析HTTP返回数据 var r cloudflare.PageRulesResponse err = json.Unmarshal(body, &r) //处理返回逻辑 if err != nil { return nil, fmt.Errorf("%s: %w", "error unmarshalling the JSON response", err) } if r.Success != true { return nil, fmt.Errorf("%s", r.Errors) } rules := r.Result filterMap := lo.FilterMap[cloudflare.PageRule, *zone.PageRule](rules, func(rule cloudflare.PageRule, _ int) (*zone.PageRule, bool) { pageRule := Go2ProtoPageRule(&rule) return pageRule, true }) return &zone.PageRuleList{PageRules: filterMap}, nil }