From 3285729b7ddaa5e925c8875ed576578872f575f9 Mon Sep 17 00:00:00 2001 From: Isabella Basso Date: Tue, 26 Nov 2024 07:55:52 -0300 Subject: [PATCH 1/4] py: client: add logging (#563) * py: client: add logging Co-authored-by: Luca Giorgi Signed-off-by: Isabella do Amaral * minor fixes Co-authored-by: Matteo Mortari Signed-off-by: Isabella do Amaral --------- Signed-off-by: Isabella do Amaral Co-authored-by: Luca Giorgi Co-authored-by: Matteo Mortari --- clients/python/src/model_registry/_client.py | 72 +++++++++++++++----- 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/clients/python/src/model_registry/_client.py b/clients/python/src/model_registry/_client.py index 6cff5092..a6aa7347 100644 --- a/clients/python/src/model_registry/_client.py +++ b/clients/python/src/model_registry/_client.py @@ -2,6 +2,7 @@ from __future__ import annotations +import logging import os from collections.abc import Mapping from pathlib import Path @@ -22,6 +23,30 @@ ModelTypes = Union[RegisteredModel, ModelVersion, ModelArtifact] TModel = TypeVar("TModel", bound=ModelTypes) +logging.basicConfig( + format="%(asctime)s.%(msecs)03d - %(name)s:%(levelname)s: %(message)s", + datefmt="%H:%M:%S", + level=logging.WARNING, # the default loglevel + handlers=[ + # logging.FileHandler( + # LOGS + # / "log-{}-{}.log".format( + # datetime.now(tz=datetime.now().astimezone().tzinfo).strftime( + # "%Y-%m-%d-%H-%M-%S" + # ), + # os.getpid(), + # ), + # encoding="utf-8", + # delay=False, + # ), + logging.StreamHandler(), + ], +) + +logger = logging.getLogger("model-registry") + +DEFAULT_USER_TOKEN_ENVVAR = "KF_PIPELINES_SA_TOKEN_PATH" # noqa: S105 + class ModelRegistry: """Model registry client.""" @@ -34,7 +59,10 @@ def __init__( author: str, is_secure: bool = True, user_token: str | None = None, + user_token_envvar: str = DEFAULT_USER_TOKEN_ENVVAR, custom_ca: str | None = None, + custom_ca_envvar: str | None = None, + log_level: int = logging.WARNING, ): """Constructor. @@ -45,47 +73,59 @@ def __init__( Keyword Args: author: Name of the author. is_secure: Whether to use a secure connection. Defaults to True. - user_token: The PEM-encoded user token as a string. Defaults to content of path on envvar KF_PIPELINES_SA_TOKEN_PATH. - custom_ca: Path to the PEM-encoded root certificates as a string. Defaults to path on envvar CERT. + user_token: The PEM-encoded user token as a string. + user_token_envvar: Environment variable to read the user token from if it's not passed as an arg. Defaults to KF_PIPELINES_SA_TOKEN_PATH. + custom_ca: Path to the PEM-encoded root certificates as a string. + custom_ca_envvar: Environment variable to read the custom CA from if it's not passed as an arg. + log_level: Log level. Defaults to logging.WARNING. """ + logger.setLevel(log_level) + import nest_asyncio + logger.debug("Setting up reentrant async event loop") nest_asyncio.apply() # TODO: get remaining args from env self._author = author - if not user_token: + if not user_token and user_token_envvar: + logger.info("Reading user token from %s", user_token_envvar) # /var/run/secrets/kubernetes.io/serviceaccount/token - sa_token = os.environ.get("KF_PIPELINES_SA_TOKEN_PATH") - if sa_token: + if sa_token := os.environ.get(user_token_envvar): + if user_token_envvar == DEFAULT_USER_TOKEN_ENVVAR: + logger.warning( + f"Sourcing user token from default envvar: {DEFAULT_USER_TOKEN_ENVVAR}" + ) user_token = Path(sa_token).read_text() else: warn("User access token is missing", stacklevel=2) if is_secure: - root_ca = None - if not custom_ca: - if cert := os.getenv("CERT"): - root_ca = cert - # client might have a default CA setup - else: - root_ca = custom_ca + if ( + not custom_ca + and custom_ca_envvar + and (cert := os.getenv(custom_ca_envvar)) + ): + logger.info( + "Using custom CA envvar %s", + custom_ca_envvar, + ) + custom_ca = cert + # client might have a default CA setup if not user_token: msg = "user token must be provided for secure connection" raise StoreError(msg) self._api = ModelRegistryAPIClient.secure_connection( - server_address, port, user_token=user_token, custom_ca=root_ca + server_address, port, user_token=user_token, custom_ca=custom_ca ) - elif custom_ca: - msg = "Custom CA provided without secure connection, conflicting options" - raise StoreError(msg) else: self._api = ModelRegistryAPIClient.insecure_connection( server_address, port, user_token ) + self.get_registered_models().page_size(1)._next_page() def async_runner(self, coro: Any) -> Any: import asyncio From 257b85bf574701be01c00c606c55df7e66c1151a Mon Sep 17 00:00:00 2001 From: Alessio Pragliola <83355398+Al-Pragliola@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:24:53 +0100 Subject: [PATCH 2/4] feat(inferenceservice): added integration tests to inferenceservice reconcile function (#574) * feat: added integration tests to inferenceservice reconcile func Signed-off-by: Alessio Pragliola * chore(isvc): keep the crds folder and document Signed-off-by: Alessio Pragliola --------- Signed-off-by: Alessio Pragliola --- Makefile | 21 +- go.mod | 9 +- go.sum | 30 ++ pkg/inferenceservice-controller/controller.go | 20 +- .../controller_test.go | 45 +++ pkg/inferenceservice-controller/suite_test.go | 321 ++++++++++++++++++ .../testdata/crd/.gitignore | 3 + .../testdata/deploy/model-registry-svc.yaml | 20 ++ .../inference-service-correct.yaml | 18 + 9 files changed, 469 insertions(+), 18 deletions(-) create mode 100644 pkg/inferenceservice-controller/controller_test.go create mode 100644 pkg/inferenceservice-controller/suite_test.go create mode 100644 pkg/inferenceservice-controller/testdata/crd/.gitignore create mode 100644 pkg/inferenceservice-controller/testdata/deploy/model-registry-svc.yaml create mode 100644 pkg/inferenceservice-controller/testdata/inferenceservices/inference-service-correct.yaml diff --git a/Makefile b/Makefile index b4c906b2..5566a331 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,10 @@ GO ?= "$(shell which go)" BFF_PATH := $(PROJECT_PATH)/clients/ui/bff UI_PATH := $(PROJECT_PATH)/clients/ui/frontend +# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. +ENVTEST_K8S_VERSION = 1.29 +ENVTEST ?= $(PROJECT_BIN)/setup-envtest + # add tools bin directory PATH := $(PROJECT_BIN):$(PATH) @@ -133,6 +137,9 @@ bin/protoc-gen-go: bin/protoc-gen-go-grpc: GOBIN=$(PROJECT_BIN) ${GO} install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 +bin/envtest: + GOBIN=$(PROJECT_BIN) ${GO} install sigs.k8s.io/controller-runtime/tools/setup-envtest@v0.0.0-20240320141353-395cfc7486e6 + GOLANGCI_LINT ?= ${PROJECT_BIN}/golangci-lint bin/golangci-lint: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(PROJECT_BIN) v1.61.0 @@ -164,7 +171,7 @@ clean/deps: rm -Rf bin/* .PHONY: deps -deps: bin/protoc bin/go-enum bin/protoc-gen-go bin/protoc-gen-go-grpc bin/golangci-lint bin/goverter bin/openapi-generator-cli +deps: bin/protoc bin/go-enum bin/protoc-gen-go bin/protoc-gen-go-grpc bin/golangci-lint bin/goverter bin/openapi-generator-cli bin/envtest .PHONY: vendor vendor: @@ -200,16 +207,16 @@ lint: ${GOLANGCI_LINT} run cmd/... internal/... ./pkg/... .PHONY: test -test: gen - ${GO} test ./internal/... ./pkg/... +test: gen bin/envtest + KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" ${GO} test ./internal/... ./pkg/... .PHONY: test-nocache -test-nocache: gen - ${GO} test ./internal/... ./pkg/... -count=1 +test-nocache: gen bin/envtest + KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" ${GO} test ./internal/... ./pkg/... -count=1 .PHONY: test-cover -test-cover: gen - ${GO} test ./internal/... ./pkg/... -coverprofile=coverage.txt +test-cover: gen bin/envtest + KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" ${GO} test ./internal/... ./pkg/... -coverprofile=coverage.txt ${GO} tool cover -html=coverage.txt -o coverage.html .PHONY: run/proxy diff --git a/go.mod b/go.mod index 0efebf2f..062595f0 100644 --- a/go.mod +++ b/go.mod @@ -8,15 +8,19 @@ require ( github.com/go-logr/logr v1.4.1 github.com/golang/glog v1.2.2 github.com/kserve/kserve v0.12.1 + github.com/onsi/ginkgo v1.16.5 + github.com/onsi/gomega v1.30.0 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 github.com/testcontainers/testcontainers-go v0.33.0 + go.uber.org/zap v1.26.0 google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.35.1 k8s.io/api v0.29.0 k8s.io/apimachinery v0.29.0 + k8s.io/client-go v0.29.0 sigs.k8s.io/controller-runtime v0.16.3 ) @@ -36,6 +40,7 @@ require ( github.com/evanphx/json-patch/v5 v5.7.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.20.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.4 // indirect @@ -61,6 +66,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/nxadm/tail v1.4.8 // indirect github.com/prometheus/client_golang v1.17.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.45.0 // indirect @@ -72,7 +78,6 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect - go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.26.0 // indirect golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect @@ -83,9 +88,9 @@ require ( google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/apiextensions-apiserver v0.28.4 // indirect - k8s.io/client-go v0.29.0 // indirect k8s.io/component-base v0.28.4 // indirect k8s.io/klog/v2 v2.110.1 // indirect k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e // indirect diff --git a/go.sum b/go.sum index 6a639a23..f167dd30 100644 --- a/go.sum +++ b/go.sum @@ -79,6 +79,8 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= @@ -107,6 +109,7 @@ github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -129,6 +132,7 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= @@ -181,6 +185,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -238,8 +243,17 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -299,6 +313,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -372,6 +387,7 @@ golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -381,6 +397,7 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= @@ -400,6 +417,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -407,9 +425,14 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -442,6 +465,7 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= @@ -502,11 +526,17 @@ google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojt gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/inferenceservice-controller/controller.go b/pkg/inferenceservice-controller/controller.go index bbefbdc5..a66a8a9d 100644 --- a/pkg/inferenceservice-controller/controller.go +++ b/pkg/inferenceservice-controller/controller.go @@ -3,6 +3,7 @@ package inferenceservicecontroller import ( "context" "fmt" + "net/http" "github.com/go-logr/logr" kservev1beta1 "github.com/kserve/kserve/pkg/apis/serving/v1beta1" @@ -17,6 +18,7 @@ import ( type InferenceServiceController struct { client client.Client + customHTTPClient *http.Client log logr.Logger bearerToken string inferenceServiceIDLabel string @@ -45,6 +47,10 @@ func NewInferenceServiceController(client client.Client, log logr.Logger, bearer } } +func (r *InferenceServiceController) OverrideHTTPClient(client *http.Client) { + r.customHTTPClient = client +} + // Reconcile performs the reconciliation of the model registry based on Kubeflow InferenceService CRs func (r *InferenceServiceController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { mrNamespace := r.defaultModelRegistryNamespace @@ -143,7 +149,7 @@ func (r *InferenceServiceController) Reconcile(ctx context.Context, req ctrl.Req } if isMarkedToBeDeleted { - err := r.onDeletion(ctx, mrApi, log, isvc, mrIs) + err := r.onDeletion(ctx, mrApi, log, mrIs) if err != nil { return ctrl.Result{Requeue: true}, err } @@ -192,9 +198,8 @@ func (r *InferenceServiceController) initModelRegistryService(ctx context.Contex var err error log1 := log.WithValues("mr-namespace", namespace, "mr-name", name) - scheme := "https" - if url != "" { + if url == "" { log1.Info("Retrieving api http port from deployed model registry service") url, err = r.getMRUrlFromService(ctx, name, namespace) @@ -202,13 +207,10 @@ func (r *InferenceServiceController) initModelRegistryService(ctx context.Contex log1.Error(err, "Unable to fetch the Model Registry Service") return nil, err } - - scheme = "http" } cfg := &openapi.Configuration{ - Host: url, - Scheme: scheme, + HTTPClient: r.customHTTPClient, Servers: openapi.ServerConfigurations{ { URL: url, @@ -242,7 +244,7 @@ func (r *InferenceServiceController) getMRUrlFromService(ctx context.Context, na return "", fmt.Errorf("unable to find the http port in the Model Registry Service") } - return fmt.Sprintf("%s.%s.svc.cluster.local:%d", name, namespace, *restApiPort), nil + return fmt.Sprintf("http://%s.%s.svc.cluster.local:%d", name, namespace, *restApiPort), nil } func (r *InferenceServiceController) createMRInferenceService( @@ -296,7 +298,7 @@ func (r *InferenceServiceController) getOrCreateServingEnvironment(ctx context.C } // onDeletion mark model registry inference service to UNDEPLOYED desired state -func (r *InferenceServiceController) onDeletion(ctx context.Context, mr *openapi.APIClient, log logr.Logger, isvc *kservev1beta1.InferenceService, is *openapi.InferenceService) (err error) { +func (r *InferenceServiceController) onDeletion(ctx context.Context, mr *openapi.APIClient, log logr.Logger, is *openapi.InferenceService) (err error) { log.Info("Running onDeletion logic") if is.DesiredState != nil && *is.DesiredState != openapi.INFERENCESERVICESTATE_UNDEPLOYED { log.Info("InferenceService going to be deleted from cluster, setting desired state to UNDEPLOYED in model registry") diff --git a/pkg/inferenceservice-controller/controller_test.go b/pkg/inferenceservice-controller/controller_test.go new file mode 100644 index 00000000..8d3f6335 --- /dev/null +++ b/pkg/inferenceservice-controller/controller_test.go @@ -0,0 +1,45 @@ +package inferenceservicecontroller_test + +import ( + "fmt" + "time" + + kservev1beta1 "github.com/kserve/kserve/pkg/apis/serving/v1beta1" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" +) + +var _ = Describe("InferenceService Controller", func() { + When("Creating a new InferenceService with Model Registry labels", func() { + It("If a label with inference service id is missing, it should add it after creating the required resources on model registry", func() { + const CorrectInferenceServicePath = "./testdata/inferenceservices/inference-service-correct.yaml" + + inferenceService := &kservev1beta1.InferenceService{} + Expect(ConvertFileToStructuredResource(CorrectInferenceServicePath, inferenceService)).To(Succeed()) + + if err := cli.Create(ctx, inferenceService); err != nil && !errors.IsAlreadyExists(err) { + Fail(err.Error()) + } + + Eventually(func() error { + isvc := &kservev1beta1.InferenceService{} + err := cli.Get(ctx, types.NamespacedName{ + Name: inferenceService.Name, + Namespace: inferenceService.Namespace, + }, isvc) + if err != nil { + return err + } + + if isvc.Labels[inferenceServiceIDLabel] != "1" { + return fmt.Errorf("Label for InferenceServiceID is not set, got %s", isvc.Labels[inferenceServiceIDLabel]) + } + + return nil + }, 10*time.Second, 1*time.Second).Should(Succeed()) + }) + }) +}) diff --git a/pkg/inferenceservice-controller/suite_test.go b/pkg/inferenceservice-controller/suite_test.go new file mode 100644 index 00000000..cbfd31bb --- /dev/null +++ b/pkg/inferenceservice-controller/suite_test.go @@ -0,0 +1,321 @@ +package inferenceservicecontroller_test + +import ( + "context" + "fmt" + "io" + "net/http" + "net/http/httptest" + "net/url" + "os" + "path/filepath" + "strings" + "testing" + "time" + + kservev1beta1 "github.com/kserve/kserve/pkg/apis/serving/v1beta1" + inferenceservicecontroller "github.com/kubeflow/model-registry/pkg/inferenceservice-controller" + "go.uber.org/zap/zapcore" + corev1 "k8s.io/api/core/v1" + authv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/metrics/server" + + logf "sigs.k8s.io/controller-runtime/pkg/log" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +const ( + inferenceServiceIDLabel = "modelregistry.kubeflow.org/inference-service-id" + registeredModelIDLabel = "modelregistry.kubeflow.org/registered-model-id" + modelVersionIDLabel = "modelregistry.kubeflow.org/model-version-id" + namespaceLabel = "modelregistry.kubeflow.org/namespace" + nameLabel = "modelregistry.kubeflow.org/name" + urlLabel = "modelregistry.kubeflow.org/url" + finalizerLabel = "modelregistry.kubeflow.org/finalizer" + defaultNamespace = "default" + accessToken = "" + kserveVersion = "v0.12.1" + kserveCRDParamUrl = "https://raw.githubusercontent.com/kserve/kserve/refs/tags/%s/config/crd/serving.kserve.io_inferenceservices.yaml" + testCRDLocalPath = "./testdata/crd" +) + +var ( + cli client.Client + envTest *envtest.Environment + ctx context.Context + cancel context.CancelFunc + mrMockServer *httptest.Server +) + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "InferenceService Controller Suite") +} + +var _ = BeforeSuite(func() { + ctx, cancel = context.WithCancel(context.Background()) + + // Initialize logger + opts := zap.Options{ + Development: true, + TimeEncoder: zapcore.TimeEncoderOfLayout(time.RFC3339), + } + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseFlagOptions(&opts))) + + // Download CRDs + crdUrl := fmt.Sprintf(kserveCRDParamUrl, kserveVersion) + + crdPath := filepath.Join(testCRDLocalPath, "serving.kserve.io_inferenceservices.yaml") + + if err := os.MkdirAll(filepath.Dir(crdPath), 0755); err != nil { + Fail(err.Error()) + } + + if err := DownloadFile(crdUrl, crdPath); err != nil { + Fail(err.Error()) + } + + // Initialize test environment: + By("Bootstrapping test environment") + envTest = &envtest.Environment{ + CRDInstallOptions: envtest.CRDInstallOptions{ + Paths: []string{filepath.Join("testdata", "crd")}, + ErrorIfPathMissing: true, + CleanUpAfterUse: false, + }, + } + + cfg, err := envTest.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + // Register API objects: + testScheme := runtime.NewScheme() + RegisterSchemes(testScheme) + + // Initialize Kubernetes client + cli, err = client.New(cfg, client.Options{Scheme: testScheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(cli).NotTo(BeNil()) + + // Setup controller manager + mgr, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: testScheme, + LeaderElection: false, + Metrics: server.Options{ + BindAddress: "0", + }, + }) + + Expect(err).NotTo(HaveOccurred()) + + const ModelRegistrySVCPath = "./testdata/deploy/model-registry-svc.yaml" + + mrSvc := &corev1.Service{} + Expect(ConvertFileToStructuredResource(ModelRegistrySVCPath, mrSvc)).To(Succeed()) + + mrSvc.SetNamespace(defaultNamespace) + + if err := cli.Create(ctx, mrSvc); err != nil && !errors.IsAlreadyExists(err) { + Fail(err.Error()) + } + + inferenceServiceController := inferenceservicecontroller.NewInferenceServiceController( + cli, + ctrl.Log.WithName("controllers").WithName("ModelRegistry-InferenceService-Controller"), + accessToken, + inferenceServiceIDLabel, + registeredModelIDLabel, + modelVersionIDLabel, + namespaceLabel, + nameLabel, + urlLabel, + finalizerLabel, + defaultNamespace, + ) + + mrMockServer = ModelRegistryDefaultMockServer() + + inferenceServiceController.OverrideHTTPClient(&http.Client{ + Transport: &http.Transport{ + Proxy: func(req *http.Request) (*url.URL, error) { + if strings.Contains(req.URL.String(), "svc.cluster.local") { + url, err := url.Parse(mrMockServer.URL) + if err != nil { + return nil, err + } + + logf.Log.Info("Proxying request", "request", req.URL) + + proxyUrl, err := http.ProxyURL(url)(req) + + logf.Log.Info("Proxying request", "proxyUrl", proxyUrl) + + return proxyUrl, err + } + + return req.URL, nil + }, + }, + }) + + err = inferenceServiceController.SetupWithManager(mgr) + Expect(err).ToNot(HaveOccurred()) + + // Start the manager + go func() { + defer GinkgoRecover() + err = mgr.Start(ctx) + Expect(err).ToNot(HaveOccurred(), "Failed to run manager") + }() +}, 60) + +var _ = AfterSuite(func() { + cancel() + By("Tearing down the test environment") + err := envTest.Stop() + Expect(err).NotTo(HaveOccurred()) + By("Stopping the Model Registry mock server") + mrMockServer.Close() + + // Clean up CRDs + err = os.Remove(filepath.Join(testCRDLocalPath, "serving.kserve.io_inferenceservices.yaml")) + Expect(err).NotTo(HaveOccurred()) + +}) + +func ModelRegistryDefaultMockServer() *httptest.Server { + handler := http.NewServeMux() + + handler.HandleFunc("/api/model_registry/v1alpha3/serving_environments", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + + if r.Method == http.MethodGet { + w.WriteHeader(http.StatusNotFound) + + return + } + + if r.Method == http.MethodPost { + w.WriteHeader(http.StatusCreated) + + res := `{ + "id": "1", + "name": "default" + }` + + _, err := w.Write([]byte(res)) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + } + + return + } + + w.WriteHeader(http.StatusOK) + }) + + handler.HandleFunc("/api/model_registry/v1alpha3/inference_services/1", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + + res := `{ + "id": "1" + }` + + _, err := w.Write([]byte(res)) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + } + }) + + handler.HandleFunc("/api/model_registry/v1alpha3/inference_services", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + + if r.Method == http.MethodGet { + w.WriteHeader(http.StatusNotFound) + + return + } + + if r.Method == http.MethodPost { + w.WriteHeader(http.StatusCreated) + + res := `{ + "id": "1" + }` + + _, err := w.Write([]byte(res)) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + } + + return + } + + w.WriteHeader(http.StatusOK) + }) + + return httptest.NewServer(handler) +} + +func RegisterSchemes(s *runtime.Scheme) { + utilruntime.Must(clientgoscheme.AddToScheme(s)) + utilruntime.Must(kservev1beta1.AddToScheme(s)) + utilruntime.Must(corev1.AddToScheme(s)) + utilruntime.Must(authv1.AddToScheme(s)) +} + +func ConvertFileToStructuredResource(path string, out runtime.Object) error { + data, err := os.ReadFile(path) + if err != nil { + return err + } + + return ConvertYamlToStructuredResource(data, out) +} + +func ConvertYamlToStructuredResource(content []byte, out runtime.Object) error { + s := runtime.NewScheme() + + RegisterSchemes(s) + + decoder := serializer.NewCodecFactory(s).UniversalDeserializer().Decode + _, _, err := decoder(content, nil, out) + + return err +} + +func DownloadFile(url string, path string) error { + resp, err := http.Get(url) + if err != nil { + return err + } + + defer resp.Body.Close() + + file, err := os.Create(path) + if err != nil { + return err + } + + defer file.Close() + + _, err = io.Copy(file, resp.Body) + if err != nil { + return err + } + + return nil +} diff --git a/pkg/inferenceservice-controller/testdata/crd/.gitignore b/pkg/inferenceservice-controller/testdata/crd/.gitignore new file mode 100644 index 00000000..fa377082 --- /dev/null +++ b/pkg/inferenceservice-controller/testdata/crd/.gitignore @@ -0,0 +1,3 @@ +# CRDs files will be fetched from the test suite + +*.yaml diff --git a/pkg/inferenceservice-controller/testdata/deploy/model-registry-svc.yaml b/pkg/inferenceservice-controller/testdata/deploy/model-registry-svc.yaml new file mode 100644 index 00000000..08af702d --- /dev/null +++ b/pkg/inferenceservice-controller/testdata/deploy/model-registry-svc.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: metadata + name: model-registry + namespace: default +spec: + ports: + - appProtocol: http + name: http-api + port: 8080 + protocol: TCP + - appProtocol: grpc + name: grpc-api + port: 9090 + protocol: TCP + selector: + component: model-registry-server + type: ClusterIP diff --git a/pkg/inferenceservice-controller/testdata/inferenceservices/inference-service-correct.yaml b/pkg/inferenceservice-controller/testdata/inferenceservices/inference-service-correct.yaml new file mode 100644 index 00000000..edb6c9f3 --- /dev/null +++ b/pkg/inferenceservice-controller/testdata/inferenceservices/inference-service-correct.yaml @@ -0,0 +1,18 @@ +apiVersion: serving.kserve.io/v1beta1 +kind: InferenceService +metadata: + name: example-onnx-mnist + namespace: default + labels: + modelregistry.kubeflow.org/registered-model-id: "1" + modelregistry.kubeflow.org/name: "model-registry" + modelregistry.kubeflow.org/namespace: "default" +spec: + predictor: + model: + modelFormat: + name: onnx + runtime: kserve-ovms + storage: + key: testkey + path: /testpath/test From c811819c77ea098f16e95974c6f1285d758b26c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Nov 2024 10:45:53 +0000 Subject: [PATCH 3/4] build(deps): bump ubi8/go-toolset from 1.21 to 1.22 (#550) Bumps ubi8/go-toolset from 1.21 to 1.22. --- updated-dependencies: - dependency-name: ubi8/go-toolset dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- Dockerfile.odh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 72290fc6..18dae08b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build the model-registry binary -FROM --platform=$BUILDPLATFORM registry.access.redhat.com/ubi8/go-toolset:1.21 AS builder +FROM --platform=$BUILDPLATFORM registry.access.redhat.com/ubi8/go-toolset:1.22 AS builder ARG TARGETOS ARG TARGETARCH diff --git a/Dockerfile.odh b/Dockerfile.odh index a442a6bb..a9990cdb 100644 --- a/Dockerfile.odh +++ b/Dockerfile.odh @@ -1,5 +1,5 @@ # Build the model-registry binary -FROM registry.access.redhat.com/ubi8/go-toolset:1.21 AS builder +FROM registry.access.redhat.com/ubi8/go-toolset:1.22 AS builder WORKDIR /workspace # Copy the Go Modules manifests From 4099d46f35a8d5a0f5e8c5f357c39545f60f5433 Mon Sep 17 00:00:00 2001 From: Griffin Sullivan <48397354+Griffin-Sullivan@users.noreply.github.com> Date: Wed, 27 Nov 2024 12:46:53 -0500 Subject: [PATCH 4/4] Upgrade nginx proxy http version (#597) Signed-off-by: Griffin-Sullivan --- clients/ui/frontend/nginx.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/clients/ui/frontend/nginx.conf b/clients/ui/frontend/nginx.conf index 5e36e5d9..becbbfd8 100644 --- a/clients/ui/frontend/nginx.conf +++ b/clients/ui/frontend/nginx.conf @@ -16,6 +16,7 @@ server { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass ${API_URL}; + proxy_http_version 1.1; } }