Skip to content

Commit 2010ba8

Browse files
committed
fix: r
Signed-off-by: ashing <[email protected]>
1 parent 836c681 commit 2010ba8

File tree

12 files changed

+697
-117
lines changed

12 files changed

+697
-117
lines changed

Makefile

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ else
3030
GOBIN=$(shell go env GOBIN)
3131
endif
3232

33+
GOOS ?= linux
34+
GOARCH ?= amd64
35+
36+
ifeq ($(shell uname -s),Darwin)
37+
GOOS = darwin
38+
endif
39+
40+
ifeq ($(shell uname -m),arm64)
41+
GOARCH = arm64
42+
endif
43+
ifeq ($(shell uname -m), aarch64)
44+
GOARCH = arm64
45+
endif
46+
3347
# CONTAINER_TOOL defines the container tool to be used for building images.
3448
# Be aware that the target commands are only tested with Docker which is
3549
# scaffolded by default. However, you might want to replace it to use other
@@ -142,7 +156,7 @@ pull-infra-images:
142156

143157
.PHONY: build
144158
build: manifests generate fmt vet ## Build manager binary.
145-
CGO_ENABLED=0 go build -o bin/api7-ingress-controller -ldflags $(GO_LDFLAGS) cmd/main.go
159+
GOOS=$(GOOS) GOARCH=$(GOARCH) CGO_ENABLED=0 go build -o bin/api7-ingress-controller -ldflags $(GO_LDFLAGS) cmd/main.go
146160

147161
linux-build:
148162
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o bin/api7-ingress-controller -ldflags $(GO_LDFLAGS) cmd/main.go
@@ -158,7 +172,7 @@ run: manifests generate fmt vet ## Run a controller from your host.
158172
# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it.
159173
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
160174
.PHONY: docker-build
161-
docker-build: build ## Build docker image with the manager.
175+
docker-build: set-e2e-goos build ## Build docker image with the manager.
162176
$(CONTAINER_TOOL) build -t ${IMG} -f Dockerfile .
163177

164178
.PHONY: docker-push
@@ -268,6 +282,11 @@ gofmt: ## Apply go fmt
268282
@go fmt ./...
269283
.PHONY: gofmt
270284

285+
set-e2e-goos:
286+
$(eval GOOS=linux)
287+
@echo "e2e GOOS: $(GOOS)"
288+
.PHONY: set-e2e-goos
289+
271290
# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist
272291
# $1 - target path with name of binary
273292
# $2 - package url which can be installed

config/samples/config.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
log_level: "info" # The log level of the API7 Ingress Controller.
1+
log_level: "debug" # The log level of the API7 Ingress Controller.
22
# the default value is "info".
33

44
controller_name: gateway.api7.io/api7-ingress-controller # The controller name of the API7 Ingress Controller,
@@ -15,9 +15,9 @@ ingress_status_address: [] # The status address of the ingress.
1515
gateway_configs: # The configuration of the API7 Gateway.
1616
- name: api7 # The name of the Gateway in the Gateway API.
1717
control_plane:
18-
admin_key: "${ADMIN_KEY}" # The admin key of the control plane.
18+
admin_key: "a7adm-2BU3prqKv68BU8DNTaZJIOnIhkH0RJ1xCY3tXGOiEneBfqVF5F-0a0f8eb4d7d94fc6aed43566a6f2989a" # The admin key of the control plane.
1919
endpoints:
20-
- ${ENDPOINT} # The endpoint of the control plane.
20+
- "https://172.18.0.5:7443" # The endpoint of the control plane.
2121
tls_verify: false
2222
addresses: # record the status address of the gateway-api gateway
23-
- "172.18.0.4" # The LB IP of the gateway service.
23+
- "172.18.0.5" # The LB IP of the gateway service.

internal/controller/ingress_controller.go

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func (r *IngressReconciler) SetupWithManager(mgr ctrl.Manager) error {
4242
predicate.NewPredicateFuncs(r.checkIngressClass),
4343
),
4444
).
45-
WithEventFilter(predicate.GenerationChangedPredicate{}).
45+
WithEventFilter(CombinedPredicate{}).
4646
Watches(
4747
&networkingv1.IngressClass{},
4848
handler.EnqueueRequestsFromMapFunc(r.listIngressForIngressClass),
@@ -135,16 +135,19 @@ func (r *IngressReconciler) checkIngressClass(obj client.Object) bool {
135135
// find the ingress class that is marked as default
136136
for _, ic := range ingressClassList.Items {
137137
if IsDefaultIngressClass(&ic) && matchesController(ic.Spec.Controller) {
138+
log.Debugw("match the default ingress class")
138139
return true
139140
}
140141
}
141142

143+
log.Debugw("no default ingress class found")
142144
return false
143145
}
144146

145147
configuredClass := config.GetIngressClass()
146148
// if the ingress class name matches the configured ingress class name, return true
147149
if *ingress.Spec.IngressClassName == configuredClass {
150+
log.Debugw("match the configured ingress class name")
148151
return true
149152
}
150153

@@ -169,25 +172,55 @@ func (r *IngressReconciler) matchesIngressController(obj client.Object) bool {
169172
}
170173

171174
// listIngressForIngressClass list all ingresses that use a specific ingress class
172-
func (r *IngressReconciler) listIngressForIngressClass(ctx context.Context, ingressClass client.Object) []reconcile.Request {
173-
ingressList := &networkingv1.IngressList{}
174-
if err := r.List(ctx, ingressList, client.MatchingFields{
175-
indexer.IngressClassRef: ingressClass.GetName(),
176-
}); err != nil {
177-
r.Log.Error(err, "failed to list ingresses for ingress class", "ingressclass", ingressClass.GetName())
175+
func (r *IngressReconciler) listIngressForIngressClass(ctx context.Context, obj client.Object) []reconcile.Request {
176+
ingressClass, ok := obj.(*networkingv1.IngressClass)
177+
if !ok {
178+
r.Log.Error(fmt.Errorf("unexpected object type"), "failed to convert object to IngressClass")
178179
return nil
179180
}
180181

181-
requests := make([]reconcile.Request, 0, len(ingressList.Items))
182-
for _, ingress := range ingressList.Items {
183-
requests = append(requests, reconcile.Request{
184-
NamespacedName: client.ObjectKey{
185-
Namespace: ingress.Namespace,
186-
Name: ingress.Name,
187-
},
188-
})
182+
// check if the ingress class is the default ingress class
183+
if IsDefaultIngressClass(ingressClass) {
184+
ingressList := &networkingv1.IngressList{}
185+
if err := r.List(ctx, ingressList); err != nil {
186+
r.Log.Error(err, "failed to list ingresses for ingress class", "ingressclass", ingressClass.GetName())
187+
return nil
188+
}
189+
190+
requests := make([]reconcile.Request, 0, len(ingressList.Items))
191+
for _, ingress := range ingressList.Items {
192+
if ingress.Spec.IngressClassName == nil || *ingress.Spec.IngressClassName == "" ||
193+
*ingress.Spec.IngressClassName == ingressClass.GetName() {
194+
requests = append(requests, reconcile.Request{
195+
NamespacedName: client.ObjectKey{
196+
Namespace: ingress.Namespace,
197+
Name: ingress.Name,
198+
},
199+
})
200+
}
201+
}
202+
return requests
203+
} else {
204+
ingressList := &networkingv1.IngressList{}
205+
if err := r.List(ctx, ingressList, client.MatchingFields{
206+
indexer.IngressClassRef: ingressClass.GetName(),
207+
}); err != nil {
208+
r.Log.Error(err, "failed to list ingresses for ingress class", "ingressclass", ingressClass.GetName())
209+
return nil
210+
}
211+
212+
requests := make([]reconcile.Request, 0, len(ingressList.Items))
213+
for _, ingress := range ingressList.Items {
214+
requests = append(requests, reconcile.Request{
215+
NamespacedName: client.ObjectKey{
216+
Namespace: ingress.Namespace,
217+
Name: ingress.Name,
218+
},
219+
})
220+
}
221+
222+
return requests
189223
}
190-
return requests
191224
}
192225

193226
// listIngressesByService list all ingresses that use a specific service
@@ -211,12 +244,14 @@ func (r *IngressReconciler) listIngressesByService(ctx context.Context, obj clie
211244

212245
requests := make([]reconcile.Request, 0, len(ingressList.Items))
213246
for _, ingress := range ingressList.Items {
214-
requests = append(requests, reconcile.Request{
215-
NamespacedName: client.ObjectKey{
216-
Namespace: ingress.Namespace,
217-
Name: ingress.Name,
218-
},
219-
})
247+
if r.checkIngressClass(&ingress) {
248+
requests = append(requests, reconcile.Request{
249+
NamespacedName: client.ObjectKey{
250+
Namespace: ingress.Namespace,
251+
Name: ingress.Name,
252+
},
253+
})
254+
}
220255
}
221256
return requests
222257
}
@@ -242,12 +277,14 @@ func (r *IngressReconciler) listIngressesBySecret(ctx context.Context, obj clien
242277

243278
requests := make([]reconcile.Request, 0, len(ingressList.Items))
244279
for _, ingress := range ingressList.Items {
245-
requests = append(requests, reconcile.Request{
246-
NamespacedName: client.ObjectKey{
247-
Namespace: ingress.Namespace,
248-
Name: ingress.Name,
249-
},
250-
})
280+
if r.checkIngressClass(&ingress) {
281+
requests = append(requests, reconcile.Request{
282+
NamespacedName: client.ObjectKey{
283+
Namespace: ingress.Namespace,
284+
Name: ingress.Name,
285+
},
286+
})
287+
}
251288
}
252289
return requests
253290
}

internal/controller/utils.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@ package controller
33
import (
44
"context"
55
"fmt"
6+
"reflect"
67
"strings"
78

89
"github.com/api7/api7-ingress-controller/internal/controller/config"
10+
"github.com/api7/gopkg/pkg/log"
911
"github.com/samber/lo"
1012
corev1 "k8s.io/api/core/v1"
1113
networkingv1 "k8s.io/api/networking/v1"
1214
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1315
"k8s.io/apimachinery/pkg/labels"
1416
"sigs.k8s.io/controller-runtime/pkg/client"
17+
"sigs.k8s.io/controller-runtime/pkg/event"
18+
"sigs.k8s.io/controller-runtime/pkg/predicate"
1519
"sigs.k8s.io/controller-runtime/pkg/reconcile"
1620
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
1721
)
@@ -759,3 +763,40 @@ func SplitMetaNamespaceKey(key string) (namespace, name string, err error) {
759763

760764
return "", "", fmt.Errorf("unexpected key format: %q", key)
761765
}
766+
767+
type CombinedPredicate struct {
768+
predicate.GenerationChangedPredicate
769+
}
770+
771+
func (c CombinedPredicate) Update(e event.UpdateEvent) bool {
772+
if isNil(e.ObjectOld) {
773+
log.Debugw("Update event has no old object for update")
774+
return false
775+
}
776+
if isNil(e.ObjectNew) {
777+
log.Debugw("Update event has no new object for update")
778+
return false
779+
}
780+
781+
_, ok := e.ObjectNew.(*networkingv1.IngressClass)
782+
if ok {
783+
log.Debugw("IngressClass update event")
784+
return true
785+
}
786+
787+
log.Debugw("other update event")
788+
// if the object is not IngressClass, return the result of GenerationChangedPredicate.Update
789+
return c.GenerationChangedPredicate.Update(e)
790+
}
791+
792+
func isNil(arg any) bool {
793+
if v := reflect.ValueOf(arg); !v.IsValid() || ((v.Kind() == reflect.Ptr ||
794+
v.Kind() == reflect.Interface ||
795+
v.Kind() == reflect.Slice ||
796+
v.Kind() == reflect.Map ||
797+
v.Kind() == reflect.Chan ||
798+
v.Kind() == reflect.Func) && v.IsNil()) {
799+
return true
800+
}
801+
return false
802+
}

internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ func NewDefaultTranslateContext() *TranslateContext {
3232
EndpointSlices: make(map[types.NamespacedName][]discoveryv1.EndpointSlice),
3333
Secrets: make(map[types.NamespacedName]*corev1.Secret),
3434
PluginConfigs: make(map[types.NamespacedName]*v1alpha1.PluginConfig),
35+
Services: make(map[types.NamespacedName]*corev1.Service),
3536
}
3637
}

test/e2e/e2e_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
_ "github.com/api7/api7-ingress-controller/test/e2e/adminapi"
2727
"github.com/api7/api7-ingress-controller/test/e2e/framework"
2828
_ "github.com/api7/api7-ingress-controller/test/e2e/gatewayapi"
29+
// _ "github.com/api7/api7-ingress-controller/test/e2e/ingress"
2930
)
3031

3132
// Run e2e tests using the Ginkgo runner.

test/e2e/framework/consts.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ var (
3131
DefaultGatewayGroupKeyPrefix = fmt.Sprintf("/gateway_groups/%s", "default")
3232
)
3333

34+
var (
35+
//go:embed manifests/cert.pem
36+
TestServerCert string
37+
//go:embed manifests/key.pem
38+
TestServerKey string
39+
)
40+
3441
const (
3542
TestCACert = `-----BEGIN CERTIFICATE-----
3643
MIIDdzCCAl+gAwIBAgIUBB5PHXyymeboPDVdYeYihYnm5XIwDQYJKoZIhvcNAQEL
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIFcjCCA1qgAwIBAgIJALDqPppBVXQ3MA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNV
3+
BAYTAkNOMRAwDgYDVQQIDAdKaWFuZ3N1MQ8wDQYDVQQHDAZTdXpob3UxEDAOBgNV
4+
BAoMB2FwaTcuYWkxEDAOBgNVBAsMB2FwaTcuYWkxDzANBgNVBAMMBmp3LmNvbTAg
5+
Fw0yMTA0MDkwNzEyMDBaGA8yMDUxMDQwMjA3MTIwMFowZTELMAkGA1UEBhMCQ04x
6+
EDAOBgNVBAgMB0ppYW5nc3UxDzANBgNVBAcMBlN1emhvdTEQMA4GA1UECgwHYXBp
7+
Ny5haTEQMA4GA1UECwwHYXBpNy5haTEPMA0GA1UEAwwGancuY29tMIICIjANBgkq
8+
hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuEPPnUMlSw41CTdxUNxkQ4gAZ7cPotwY
9+
Y6sVLGtWoR8gKFSZImQIor3UF+8HhN/ZOFRv5tSeeQ/MTE72cs2T5mp6eRU8OrSV
10+
0npk/TpZfaCx7zobsfXB4YU1NZcVWKthFF5X8p//l5gxUMU8V4a01P0aDTmZ67wG
11+
3Fhr0AC067GVYvdwp1yRt6TUUk8ha7JsiySchUIFhX5QMWmrSNhc1bDnHetejMFl
12+
itFFPZkeYG89O/7Ca1K3ca/VVu+/IJ4h7fbF3rt4uP182cJdHl1L94dQSKCJukaW
13+
v+xauWnm4hxOzBK7ImpYB/2eP2D33tmuCLeSv4S+bTG1l7hIN9C/xrYPzfun415h
14+
M2jMK69aAkQL71xa+66kVxioJyNYogYz3ss5ruzDL8K/7bkdO0Zzqldd2+j8lkTl
15+
X4csA+aMHF3v/U7hL/4Wdwi8ziwToRMq9KK9vuh+mPgcdtFGFml+sU+NQfJNm/BN
16+
7fRMZKDIHLacSPE0GUkfW+x3dXOP2lWSZe/iOBZ0NOGNdrOnxTRTr7IH7DYU8aXF
17+
w2GqfAFEQbD4wazCh1AI8lkZr6mPGB1q+HnF2IF7kkgXBHtI5U2KErgcX5BirIVe
18+
v0Yg/OxbbymeTh/hNCcY1kJ1YUCbm9U3U6ZV+d8lj7dQHtugcAzWxSTwpBLVUPrO
19+
eFuhSMLVblUCAwEAAaMjMCEwHwYDVR0RBBgwFoIIYXBpNi5jb22CCiouYXBpNi5j
20+
b20wDQYJKoZIhvcNAQELBQADggIBAFgeSuMPpriYUrQByO3taiY1+56s+KoAmsyA
21+
LH15n2+thAgorusX2g1Zd7UNBHBtVO8c+ihpQb+2PnmgTTGT70ndpRbV5F6124Mt
22+
Hui/X0kjm76RYd1QKN1VFp0Zo+JVdRa+VhDsXWjO0VetINmFhNINFEJctyeHB8oi
23+
aaDL0wZrevHh47hBqtnrmLl+QVG34aLBRhZ5953leiNvXHUJNaT0nLgf0j9p4esS
24+
b2bx9uP4pFI1T9wcv/TE3K0rQbu/uqGY6MgznXHyi4qIK/I+WCa3fF2UZ5P/5EUM
25+
k2ptQneYkLLUVwwmj8C04bYhYe7Z6jkYYp17ojxIP+ejOY1eiE8SYKNjKinmphrM
26+
5aceqIyfbE4TPqvicNzIggA4yEMPbTA0PC/wqbCf61oMc15hwacdeIaQGiwsM+pf
27+
DTk+GBxp3megx/+0XwTQbguleTlHnaaES+ma0vbl6a1rUK0YAUDUrcfFLv6EFtGD
28+
6EHxFf7gH9sTfc2RiGhKxUhRbyEree+6INAvXy+AymVYmQmKuAFqkDQJ+09bTfm8
29+
bDs+00FijzHFBvC8cIhNffj0qqiv35g+9FTwnE9qpunlrtKG/sMgEXX6m8kL1YQ8
30+
m5DPGhyEZyt5Js2kzzo8TyINPKmrqriYuiD4p4EH13eSRs3ayanQh6ckC7lb+WXq
31+
3IrSc5hO
32+
-----END CERTIFICATE-----
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIJKAIBAAKCAgEAuEPPnUMlSw41CTdxUNxkQ4gAZ7cPotwYY6sVLGtWoR8gKFSZ
3+
ImQIor3UF+8HhN/ZOFRv5tSeeQ/MTE72cs2T5mp6eRU8OrSV0npk/TpZfaCx7zob
4+
sfXB4YU1NZcVWKthFF5X8p//l5gxUMU8V4a01P0aDTmZ67wG3Fhr0AC067GVYvdw
5+
p1yRt6TUUk8ha7JsiySchUIFhX5QMWmrSNhc1bDnHetejMFlitFFPZkeYG89O/7C
6+
a1K3ca/VVu+/IJ4h7fbF3rt4uP182cJdHl1L94dQSKCJukaWv+xauWnm4hxOzBK7
7+
ImpYB/2eP2D33tmuCLeSv4S+bTG1l7hIN9C/xrYPzfun415hM2jMK69aAkQL71xa
8+
+66kVxioJyNYogYz3ss5ruzDL8K/7bkdO0Zzqldd2+j8lkTlX4csA+aMHF3v/U7h
9+
L/4Wdwi8ziwToRMq9KK9vuh+mPgcdtFGFml+sU+NQfJNm/BN7fRMZKDIHLacSPE0
10+
GUkfW+x3dXOP2lWSZe/iOBZ0NOGNdrOnxTRTr7IH7DYU8aXFw2GqfAFEQbD4wazC
11+
h1AI8lkZr6mPGB1q+HnF2IF7kkgXBHtI5U2KErgcX5BirIVev0Yg/OxbbymeTh/h
12+
NCcY1kJ1YUCbm9U3U6ZV+d8lj7dQHtugcAzWxSTwpBLVUPrOeFuhSMLVblUCAwEA
13+
AQKCAgApTupoMvlVTiYNnuREYGQJz59noN5cgELndR8WCiotjLDE2dJKp2pYMX4u
14+
r2NcImKsAiHj+Z5dPXFrWfhd3EBf01cJdf0+m+VKfi3NpxsQ0smQ+9Hhn1qLmDVJ
15+
gklCy4jD7DKDLeM6tN+5X74bUROQ+/yvIk6jTk+rbhcdVks422LGAPq8SkBQjx8a
16+
JKs1XZZ/ywFbzmU2fA62RR4lAnwtW680QeO8Yk7FRAzltkHdFJMBtCcZsD13uxd0
17+
meKbCVhJ5JyPRi/WKN2oY65EdF3na+pPnc3CeLiq5e2gy2D7J6VyknBpUrXRdMXZ
18+
J3/p8ZrWUXEQhk26ZP50uNdXy/Bx1jYe+U8mpkTMYVYxgu5K4Zea3yJyRn2piiE/
19+
9LnKNy/KsINt/0QE55ldvtciyP8RDA/08eQX0gvtKWWC/UFVRZCeL48bpqLmdAfE
20+
cMwlk1b0Lmo2PxULFLMAjaTKmcMAbwl53YRit0MtvaIOwiZBUVHE0blRiKC2DMKi
21+
SA6xLbaYJVDaMcfix8kZkKbC0xBNmL4123qX4RF6IUTPufyUTz/tpjzH6eKDw/88
22+
LmSx227d7/qWp5gROCDhZOPhtr4rj70JKNqcXUX9iFga+dhloOwfHYjdKndKOLUI
23+
Gp3K9YkPT/fCfesrguUx8BoleO5pC6RQJhRsemkRGlSY8U1ZsQKCAQEA5FepCn1f
24+
A46GsBSQ+/pbaHlbsR2syN3J5RmAFLFozYUrqyHE/cbNUlaYq397Ax7xwQkiN3F2
25+
z/whTxOh4Sk/HdDF4d+I0PZeoxINxgfzyYkx8Xpzn2loxsRO8fb3g+mOxZidjjXv
26+
vxqUBaj3Y01Ig0UXuw7YqCwys+xg3ELtvcGLBW/7NWMo8zqk2nUjhfcwp4e4AwBt
27+
Xcsc2aShUlr/RUrJH4adjha6Yaqc/8xTXHW8gZi5L2lucwB0LA+CBe4ES9BZLZdX
28+
N575/ohXRdjadHKYceYHiamt2326DzaxVJu2EIXU8dgdgOZ/6krITzuePRQHLPHX
29+
6bDfdg/WSpFrtwKCAQEAzpVqBcJ1fAI7bOkt89j2zZb1r5uD2f9sp/lA/Dj65QKV
30+
ShWR7Y6Jr4ShXmFvIenWtjwsl86PflMgtsJefOmLyv8o7PL154XD8SnNbBlds6IM
31+
MyNKkOJFa5NOrsal7TitaTvtYdKq8Zpqtxe+2kg80wi+tPVQNQS/drOpR3rDiLIE
32+
La/ty8XDYZsSowlzBX+uoFq7GuMct1Uh2T0/I4Kf0ZLXwYjkRlRk4LrU0BRPhRMu
33+
MHugOTYFKXShE2a3OEcxqCgvQ/3pn2TV92pPVKBIBGL6uKUwmXQYKaV3G4u10pJ4
34+
axq/avBOErcKZOReb0SNiOjiIsth8o+hnpYPU5COUwKCAQBksVNV0NtpUhyK4Ube
35+
FxTgCUQp4pAjM8qoQIp+lY1FtAgBuy6HSneYa59/YQP56FdrbH+uO1bNeL2nhVzJ
36+
UcsHdt0MMeq/WyV4e6mfPjp/EQT5G6qJDY6quD6n7ORRQ1k2QYqY/6fteeb0aAJP
37+
w/DKElnYnz9jSbpCJWbBOrJkD0ki6LK6ZDPWrnGr9CPqG4tVFUBL8pBH4B2kzDhn
38+
fME86TGvuUkZM2SVVQtOsefAyhqKe7KN+cw+4mBYXa5UtxUl6Yap2CcZ2/0aBT2X
39+
C32qBC69a1a/mheUxuiZdODWEqRCvQGedFLuWLbntnqGlh+9h2tyomM4JkskYO96
40+
io4ZAoIBAFouLW9AOUseKlTb4dx+DRcoXC4BpGhIsWUOUQkJ0rSgEQ2bJu3d+Erv
41+
igYKYJocW0eIMys917Qck75UUS0UQpsmEfaGBUTBRw0C45LZ6+abydmVAVsH+6f/
42+
USzIuOw6frDeoTy/2zHG5+jva7gcKrkxKxcRs6bBYNdvjGkQtUT5+Qr8rsDyntz/
43+
9f3IBTcUSuXjVaRiGkoJ1tHfg617u0qgYKEyofv1oWfdB0Oiaig8fEBb51CyPUSg
44+
jiRLBZaCtbGjgSacNB0JxsHP3buikG2hy7NJIVMLs/SSL9GNhpzapciTj5YeOua+
45+
ksICUxsdgO+QQg9QW3yoqLPy69Pd2dMCggEBANDLoUf3ZE7Dews6cfIa0WC33NCV
46+
FkyECaF2MNOp5Q9y/T35FyeA7UeDsTZ6Dy++XGW4uNStrSI6dCyQARqJw+i7gCst
47+
2m5lIde01ptzDQ9iO1Dv1XasxX/589CyLq6CxLfRgPMJPDeUEg0X7+a0lBT5Hpwk
48+
gNnZmws4l3i7RlVMtACCenmof9VtOcMK/9Qr502WHEoGkQR1r6HZFb25841cehL2
49+
do+oXlr8db++r87a8QQUkizzc6wXD9JffBNo9AO9Ed4HVOukpEA0gqVGBu85N3xW
50+
jW4KB95bGOTa7r7DM1Up0MbAIwWoeLBGhOIXk7inurZGg+FNjZMA5Lzm6qo=
51+
-----END RSA PRIVATE KEY-----

0 commit comments

Comments
 (0)