Skip to content

Commit 38e2e71

Browse files
varungup90varungupta
andauthored
Add users CRUD API (#181)
* Add users CRUD API * nit * read userconfig in gateway plugin * nit * address code review comments * revert dockerfile changes --------- Co-authored-by: varungupta <[email protected]>
1 parent d12ff81 commit 38e2e71

File tree

18 files changed

+646
-66
lines changed

18 files changed

+646
-66
lines changed

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ COPY go.sum go.sum
1212
RUN go mod download
1313

1414
# Copy the go source
15-
COPY cmd/controllers/main.go cmd/main.go
15+
COPY cmd/ cmd/
1616
COPY api/ api/
1717
COPY pkg/controller/ pkg/controller/
1818
COPY pkg/utils/ pkg/utils/
@@ -24,7 +24,7 @@ COPY pkg/client/ pkg/client/
2424
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
2525
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
2626
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
27-
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go
27+
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/controllers/main.go
2828

2929
# Use distroless as minimal base image to package the manager binary
3030
# Refer to https://github.com/GoogleContainerTools/distroless for more details
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
## Multistage build
2-
FROM golang:1.22 as builder
1+
# Build the manager binary
2+
FROM golang:1.22 AS builder
33
ARG TARGETOS
44
ARG TARGETARCH
55

@@ -12,7 +12,7 @@ COPY go.sum go.sum
1212
RUN go mod download
1313

1414
# Copy the go source
15-
COPY cmd/plugins/main.go cmd/main.go
15+
COPY cmd/ cmd/
1616
COPY api/ api/
1717
COPY pkg/plugins/ pkg/plugins/
1818
COPY pkg/utils/ pkg/utils/
@@ -24,7 +24,7 @@ COPY pkg/client/ pkg/client/
2424
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
2525
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
2626
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
27-
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o plugins cmd/main.go
27+
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o plugins cmd/plugins/main.go
2828

2929
# Use distroless as minimal base image to package the manager binary
3030
# Refer to https://github.com/GoogleContainerTools/distroless for more details
@@ -33,4 +33,4 @@ WORKDIR /
3333
COPY --from=builder /workspace/plugins .
3434
USER 65532:65532
3535

36-
ENTRYPOINT ["/plugins"]
36+
ENTRYPOINT ["/plugins"]

Dockerfile.users

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Build the manager binary
2+
FROM golang:1.22 AS builder
3+
ARG TARGETOS
4+
ARG TARGETARCH
5+
6+
WORKDIR /workspace
7+
# Copy the Go Modules manifests
8+
COPY go.mod go.mod
9+
COPY go.sum go.sum
10+
# cache deps before building and copying source so that we don't need to re-download as much
11+
# and so that source changes don't invalidate our downloaded layer
12+
RUN go mod download
13+
14+
# Copy the go source
15+
COPY cmd/ cmd/
16+
COPY api/ api/
17+
COPY pkg/users/ pkg/users/
18+
COPY pkg/utils/ pkg/utils/
19+
COPY pkg/cache/ pkg/cache/
20+
COPY pkg/client/ pkg/client/
21+
22+
# Build
23+
# the GOARCH has not a default value to allow the binary be built according to the host where the command
24+
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
25+
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
26+
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
27+
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o users cmd/users/main.go
28+
29+
# Use distroless as minimal base image to package the manager binary
30+
# Refer to https://github.com/GoogleContainerTools/distroless for more details
31+
FROM gcr.io/distroless/static:nonroot
32+
WORKDIR /
33+
COPY --from=builder /workspace/users .
34+
USER 65532:65532
35+
36+
ENTRYPOINT ["/users"]

Makefile

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ AIBRIX_DOCKERHUB_NAMESPACE ?= aibrix
66
IMG ?= ${AIBRIX_DOCKERHUB_NAMESPACE}/controller-manager:${GIT_COMMIT_HASH}
77
PLUGINS_IMG ?= ${AIBRIX_DOCKERHUB_NAMESPACE}/plugins:${GIT_COMMIT_HASH}
88
RUNTIME_IMG ?= ${AIBRIX_DOCKERHUB_NAMESPACE}/runtime:${GIT_COMMIT_HASH}
9+
USERS_IMG ?= ${AIBRIX_DOCKERHUB_NAMESPACE}/users:${GIT_COMMIT_HASH}
910
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
1011
ENVTEST_K8S_VERSION = 1.29.0
1112

@@ -126,14 +127,19 @@ docker-build: ## Build docker image with the manager.
126127

127128
.PHONY: docker-build-plugins
128129
docker-build-plugins: ## Build docker image with the manager.
129-
$(CONTAINER_TOOL) build -t ${PLUGINS_IMG} -f gateway.Dockerfile .
130+
$(CONTAINER_TOOL) build -t ${PLUGINS_IMG} -f Dockerfile.gateway .
130131
$(CONTAINER_TOOL) tag ${PLUGINS_IMG} ${AIBRIX_DOCKERHUB_NAMESPACE}/plugins:nightly
131132

132133
.PHONY: docker-build-runtime
133134
docker-build-runtime: ## Build docker image with the AI Runime.
134135
$(CONTAINER_TOOL) build -t ${RUNTIME_IMG} -f runtime.Dockerfile .
135136
$(CONTAINER_TOOL) tag ${RUNTIME_IMG} ${AIBRIX_DOCKERHUB_NAMESPACE}/runtime:nightly
136137

138+
.PHONY: docker-build-users
139+
docker-build-users: ## Build docker image with the manager.
140+
$(CONTAINER_TOOL) build -t ${USERS_IMG} -f Dockerfile.users .
141+
$(CONTAINER_TOOL) tag ${USERS_IMG} ${AIBRIX_DOCKERHUB_NAMESPACE}/users:nightly
142+
137143
.PHONY: docker-push
138144
docker-push: ## Push docker image with the manager.
139145
$(CONTAINER_TOOL) push ${IMG}
@@ -149,6 +155,11 @@ docker-push-runtime: ## Push docker image with the manager.
149155
$(CONTAINER_TOOL) push ${RUNTIME_IMG}
150156
$(CONTAINER_TOOL) push ${AIBRIX_DOCKERHUB_NAMESPACE}/runtime:nightly
151157

158+
.PHONY: docker-push-users
159+
docker-push-users: ## Push docker image with the manager.
160+
$(CONTAINER_TOOL) push ${USERS_IMG}
161+
$(CONTAINER_TOOL) push ${AIBRIX_DOCKERHUB_NAMESPACE}/users:nightly
162+
152163
# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple
153164
# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
154165
# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/

cmd/plugins/main.go

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ limitations under the License.
1717
package main
1818

1919
import (
20-
"context"
2120
"flag"
2221
"fmt"
2322
"log"
@@ -27,53 +26,34 @@ import (
2726
"syscall"
2827
"time"
2928

30-
redis "github.com/redis/go-redis/v9"
3129
"google.golang.org/grpc"
3230
"k8s.io/client-go/kubernetes"
3331
"k8s.io/client-go/rest"
3432
"k8s.io/client-go/tools/clientcmd"
3533

3634
"github.com/aibrix/aibrix/pkg/cache"
3735
"github.com/aibrix/aibrix/pkg/plugins/gateway"
38-
ratelimiter "github.com/aibrix/aibrix/pkg/plugins/gateway/rate_limiter"
36+
"github.com/aibrix/aibrix/pkg/utils"
3937
extProcPb "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3"
4038
healthPb "google.golang.org/grpc/health/grpc_health_v1"
4139
)
4240

43-
// Create Redis Client
4441
var (
45-
grpc_port int
46-
redis_host = getEnv("REDIS_HOST", "localhost")
47-
redis_port = getEnv("REDIS_PORT", "6379")
42+
grpc_port int
4843
)
4944

50-
func getEnv(key, defaultValue string) string {
51-
value := os.Getenv(key)
52-
if value == "" {
53-
return defaultValue
54-
}
55-
return value
56-
}
57-
5845
func main() {
5946
flag.IntVar(&grpc_port, "port", 50052, "gRPC port")
6047
flag.Parse()
6148

6249
// Connect to Redis
63-
client := redis.NewClient(&redis.Options{
64-
Addr: redis_host + ":" + redis_port,
65-
DB: 0, // Default DB
66-
})
67-
pong, err := client.Ping(context.Background()).Result()
68-
if err != nil {
69-
log.Fatal("Error connecting to Redis:", err)
70-
}
71-
fmt.Println("Connected to Redis:", pong)
50+
redisClient := utils.GetRedisClient()
7251

7352
fmt.Println("Starting cache")
7453
stopCh := make(chan struct{})
7554
defer close(stopCh)
7655
var config *rest.Config
56+
var err error
7757

7858
// ref: https://github.com/kubernetes-sigs/controller-runtime/issues/878#issuecomment-1002204308
7959
kubeConfig := flag.Lookup("kubeconfig").Value.String()
@@ -105,10 +85,7 @@ func main() {
10585

10686
s := grpc.NewServer()
10787

108-
extProcPb.RegisterExternalProcessorServer(s, gateway.NewServer(
109-
ratelimiter.NewRedisAccountRateLimiter("aibrix", client, 1*time.Minute),
110-
k8sClient,
111-
))
88+
extProcPb.RegisterExternalProcessorServer(s, gateway.NewServer(redisClient, k8sClient))
11289
healthPb.RegisterHealthServer(s, &gateway.HealthServer{})
11390

11491
log.Println("Starting gRPC server on port :50052")

cmd/users/main.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
Copyright 2024 The Aibrix Team.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"log"
21+
22+
"github.com/aibrix/aibrix/pkg/users"
23+
"github.com/aibrix/aibrix/pkg/utils"
24+
)
25+
26+
func main() {
27+
redisClient := utils.GetRedisClient()
28+
29+
log.Println("Starting listening on port 8090")
30+
srv := users.NewHTTPServer(":8090", redisClient)
31+
log.Fatal(srv.ListenAndServe())
32+
}

config/gateway/kustomization.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ resources:
22
- gateway.yaml
33
- redis.yaml
44
- gateway-plugin.yaml
5+
- users.yaml
56

config/gateway/users.yaml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: gateway-users
5+
namespace: aibrix-system
6+
spec:
7+
selector:
8+
app: gateway-users
9+
ports:
10+
- protocol: TCP
11+
port: 8090
12+
targetPort: 8090
13+
---
14+
apiVersion: apps/v1
15+
kind: Deployment
16+
metadata:
17+
name: gateway-users
18+
namespace: aibrix-system
19+
spec:
20+
replicas: 1
21+
selector:
22+
matchLabels:
23+
app: gateway-users
24+
template:
25+
metadata:
26+
labels:
27+
app: gateway-users
28+
spec:
29+
initContainers:
30+
- name: init-c
31+
image: busybox
32+
command: ['sh', '-c', "until nslookup aibrix-redis-master.aibrix-system.svc.cluster.local; do echo waiting for service aibrix-redis-master; sleep 2; done"]
33+
containers:
34+
- name: golang-app-container
35+
image: aibrix/users:nightly
36+
imagePullPolicy: Always
37+
ports:
38+
- containerPort: 8090
39+
env:
40+
- name: REDIS_HOST
41+
value: aibrix-redis-master
42+
- name: REDIS_PORT
43+
value: "6379"
44+
- name: POD_NAME
45+
valueFrom:
46+
fieldRef:
47+
fieldPath: metadata.name
48+
- name: POD_NAMESPACE
49+
valueFrom:
50+
fieldRef:
51+
fieldPath: metadata.namespace
52+
serviceAccountName: aibrix-gateway-plugin

docs/development/app/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ OR
4646

4747
- if only want to test gateway plugins
4848

49-
docker build -t aibrix/plugins:v0.1.0 -f gateway.Dockerfile .
49+
docker build -t aibrix/plugins:v0.1.0 -f Dockerfile.gateway .
5050
kind load docker-image aibrix/plugins:v0.1.0
5151

5252
kubectl -n aibrix-system apply -f docs/development/app/redis.yaml

docs/development/app/users.yaml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: aibrix-gateway-users
5+
namespace: aibrix-system
6+
spec:
7+
selector:
8+
app: gateway-users
9+
ports:
10+
- protocol: TCP
11+
port: 8090
12+
targetPort: 8090
13+
---
14+
apiVersion: apps/v1
15+
kind: Deployment
16+
metadata:
17+
name: aibrix-gateway-users
18+
namespace: aibrix-system
19+
spec:
20+
replicas: 1
21+
selector:
22+
matchLabels:
23+
app: gateway-users
24+
template:
25+
metadata:
26+
labels:
27+
app: gateway-users
28+
spec:
29+
initContainers:
30+
- name: init-c
31+
image: busybox
32+
command: ['sh', '-c', "until nslookup aibrix-redis-master.aibrix-system.svc.cluster.local; do echo waiting for service aibrix-redis-master; sleep 2; done"]
33+
containers:
34+
- name: golang-app-container
35+
image: aibrix/users:nightly
36+
imagePullPolicy: Always
37+
ports:
38+
- containerPort: 8090
39+
env:
40+
- name: REDIS_HOST
41+
value: aibrix-redis-master
42+
- name: REDIS_PORT
43+
value: "6379"
44+
- name: POD_NAME
45+
valueFrom:
46+
fieldRef:
47+
fieldPath: metadata.name
48+
- name: POD_NAMESPACE
49+
valueFrom:
50+
fieldRef:
51+
fieldPath: metadata.namespace
52+
serviceAccountName: aibrix-gateway-plugin

0 commit comments

Comments
 (0)