From bf7b561b23fc992b6eca799bf3f5d520c0300679 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Fri, 1 Apr 2022 23:29:22 +0000 Subject: [PATCH 01/24] Initial merge --- .gitignore | 1 + .vscode/launch.json | 15 ++ Dockerfile | 18 +++ LICENSE | 201 ++++++++++++++++++++++++++ Makefile | 32 ++++ README.md | 4 +- cmd/root.go | 62 ++++++++ cmd/version.go | 44 ++++++ docs/design.md | 3 + go.mod | 34 +++++ go.sum | 257 +++++++++++++++++++++++++++++++++ main.go | 23 +++ pkg/client/run.go | 40 +++++ pkg/controller/controller.go | 273 +++++++++++++++++++++++++++++++++++ pkg/event/event.go | 95 ++++++++++++ pkg/handlers/handler.go | 49 +++++++ pkg/utils/k8sutil.go | 64 ++++++++ quarkcm-in-cluster.yaml | 19 +++ quarkcm-service-account.yaml | 28 ++++ quarkcm.yaml | 19 +++ 20 files changed, 1280 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 cmd/root.go create mode 100644 cmd/version.go create mode 100644 docs/design.md create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 pkg/client/run.go create mode 100644 pkg/controller/controller.go create mode 100644 pkg/event/event.go create mode 100644 pkg/handlers/handler.go create mode 100644 pkg/utils/k8sutil.go create mode 100644 quarkcm-in-cluster.yaml create mode 100644 quarkcm-service-account.yaml create mode 100644 quarkcm.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..318b509 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +quarkcm diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6deb9a6 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "main.go" + } + ] +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a2832e1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM golang AS builder + +RUN apt-get update && \ + apt-get install -y --no-install-recommends build-essential && \ + apt-get clean && \ + mkdir -p "$GOPATH/src/github.com/CentaurusInfra/quarkcm" + +ADD . "$GOPATH/src/github.com/CentaurusInfra/quarkcm" + +RUN cd "$GOPATH/src/github.com/CentaurusInfra/quarkcm" && \ + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a --installsuffix cgo --ldflags="-s" -o /quarkcm + +FROM bitnami/minideb:stretch +RUN install_packages ca-certificates + +COPY --from=builder /quarkcm /bin/quarkcm + +ENTRYPOINT ["/bin/quarkcm"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..56d882d --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2022 quarkcm Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3d5d8c5 --- /dev/null +++ b/Makefile @@ -0,0 +1,32 @@ +.PHONY: default build docker-image test stop clean-images clean + +BINARY = quarkcm + +VERSION= +BUILD= + +PKG = github.com/CentaurusInfra/quarkcm +GOCMD = go +BUILD_DATE = `date +%FT%T%z` +GOFLAGS ?= $(GOFLAGS:) +LDFLAGS := "-X '$(PKG)/cmd.buildDate=$(BUILD_DATE)'" + +default: build test + +build: + "$(GOCMD)" build ${GOFLAGS} -ldflags ${LDFLAGS} -o "${BINARY}" + +docker-image: + @docker build -t "${BINARY}" . + +test: + "$(GOCMD)" test -race -v ./... + +stop: + @docker stop "${BINARY}" + +clean-images: stop + @docker rmi "${BUILDER}" "${BINARY}" + +clean: + "$(GOCMD)" clean -i diff --git a/README.md b/README.md index 278929a..67b220f 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ -# rdma-cm \ No newline at end of file +# quarkcm + +quarkcm is Connection Manager for Quark CDMA Networking Solution. \ No newline at end of file diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..2806148 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cmd + +import ( + "fmt" + "os" + + c "github.com/CentaurusInfra/quarkcm/pkg/client" + "github.com/spf13/cobra" +) + +// RootCmd represents the base command when called without any subcommands +var RootCmd = &cobra.Command{ + Use: "quarkcm", + Short: "Quark Connection Manager", + Long: ` + quarkcm: Quark Connection Manager + +quarkcm is Quark's Connection Manager +that watching the cluster for changes +and syncing to RDMASvc. + +`, + + Run: func(cmd *cobra.Command, args []string) { + c.Run() + }, +} + +// Execute adds all child commands to the root command sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + if err := RootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(-1) + } +} + +func init() { + cobra.OnInitialize() + + // Disable Help subcommand + RootCmd.SetHelpCommand(&cobra.Command{ + Use: "no-help", + Hidden: true, + }) +} diff --git a/cmd/version.go b/cmd/version.go new file mode 100644 index 0000000..128bcbb --- /dev/null +++ b/cmd/version.go @@ -0,0 +1,44 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cmd + +import ( + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var ( + buildDate, gitCommit string +) + +var versionCmd = &cobra.Command{ + Use: "version", + Short: "print version", + Long: `print version`, + Run: func(cmd *cobra.Command, args []string) { + versionPrettyString() + }, +} + +func versionPrettyString() { + logrus.Info("gitCommit: ", gitCommit) + logrus.Info("buildDate: ", buildDate) +} + +func init() { + RootCmd.AddCommand(versionCmd) +} diff --git a/docs/design.md b/docs/design.md new file mode 100644 index 0000000..17a7298 --- /dev/null +++ b/docs/design.md @@ -0,0 +1,3 @@ +# quarkcm + +quarkcm is Connection Manager for Quark CDMA Networking Solution. diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d8d3ced --- /dev/null +++ b/go.mod @@ -0,0 +1,34 @@ +module github.com/CentaurusInfra/quarkcm + +go 1.14 + +require ( + github.com/fatih/structtag v1.2.0 + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect + github.com/golang/protobuf v1.4.2 // indirect + github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 // indirect + github.com/googleapis/gnostic v0.1.0 // indirect + github.com/hashicorp/hcl v0.0.0-20171017181929-23c074d0eceb // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/magiconair/properties v1.7.4 // indirect + github.com/mitchellh/mapstructure v0.0.0-20180111000720-b4575eea38cc // indirect + github.com/mkmik/multierror v0.3.0 + github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect + github.com/pelletier/go-toml v1.0.1 // indirect + github.com/segmentio/textio v1.2.0 + github.com/sirupsen/logrus v1.6.0 + github.com/spf13/cast v1.1.0 // indirect + github.com/spf13/cobra v0.0.1 + github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec // indirect + github.com/spf13/viper v1.0.0 + github.com/stretchr/testify v1.6.1 // indirect + golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 // indirect + golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 // indirect + gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect + gopkg.in/yaml.v2 v2.3.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c + k8s.io/api v0.16.8 + k8s.io/apimachinery v0.16.8 + k8s.io/client-go v0.16.8 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..aee4602 --- /dev/null +++ b/go.sum @@ -0,0 +1,257 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= +github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +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.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 h1:zLTLjkaOFEFIOxY5BWLFLwh+cL8vOBW4XJ2aqLE/Tf0= +github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v0.0.0-20171017181929-23c074d0eceb h1:1OvvPvZkn/yCQ3xBcM8y4020wdkMXPHLB4+NfoGWh4U= +github.com/hashicorp/hcl v0.0.0-20171017181929-23c074d0eceb/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.7.4 h1:UVo0TkHGd4lQSN1dVDzs9URCIgReuSIcCXpAVB9nZ80= +github.com/magiconair/properties v1.7.4/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mitchellh/mapstructure v0.0.0-20180111000720-b4575eea38cc h1:5T6hzGUO5OrL6MdYXYoLQtRWJDDgjdlOVBn9mIqGY1g= +github.com/mitchellh/mapstructure v0.0.0-20180111000720-b4575eea38cc/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mkmik/multierror v0.3.0 h1:FHr3n5BEVlzlTz8GRbuwimkL2zbdD2gTPcSh0wpRpUg= +github.com/mkmik/multierror v0.3.0/go.mod h1:wjBYXRpDhh+8mIp+iLBOq0kZ3Y4ICTncojwvP8LUYLQ= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pelletier/go-toml v1.0.1 h1:0nx4vKBl23+hEaCOV1mFhKS9vhhBtFYWC7rQY0vJAyE= +github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/segmentio/textio v1.2.0 h1:Ug4IkV3kh72juJbG8azoSBlgebIbUUxVNrfFcKHfTSQ= +github.com/segmentio/textio v1.2.0/go.mod h1:+Rb7v0YVODP+tK5F7FD9TCkV7gOYx9IgLHWiqtvY8ag= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.1.0 h1:0Rhw4d6C8J9VPu6cjZLIhZ8+aAOHcDvGeKn+cq5Aq3k= +github.com/spf13/cast v1.1.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/cobra v0.0.1 h1:zZh3X5aZbdnoj+4XkaBxKfhO4ot82icYdhhREIAXIj8= +github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec h1:2ZXvIUGghLpdTVHR1UfvfrzoVlZaE/yOWC5LueIHZig= +github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.0.0 h1:RUA/ghS2i64rlnn4ydTfblY8Og8QzcPtCcHvgMn+w/I= +github.com/spf13/viper v1.0.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +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= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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-20190209173611-3b5209105503/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +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/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/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 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/api v0.16.8 h1:T72itM0CUT8KHqPAqbjTeSY0n24RyVM71nLiMlq/cAw= +k8s.io/api v0.16.8/go.mod h1:a8EOdYHO8en+YHhPBLiW5q+3RfHTr7wxTqqp7emJ7PM= +k8s.io/apimachinery v0.16.8 h1:wgFRqtel3w3rcclpba+iBkVlKeBlh42OzNp7FalXVCg= +k8s.io/apimachinery v0.16.8/go.mod h1:Xk2vD2TRRpuWYLQNM6lT9R7DSFZUYG03SarNkbGrnKE= +k8s.io/client-go v0.16.8 h1:CmsQXJpSWq1aUyQ5Lp/rRPiMK2OYfJv32Ftl0D1D42U= +k8s.io/client-go v0.16.8/go.mod h1:WmPuN0yJTKHXoklExKxzo3jSXmr3EnN+65uaTb5VuNs= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= +k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE= +k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/main.go b/main.go new file mode 100644 index 0000000..0329c86 --- /dev/null +++ b/main.go @@ -0,0 +1,23 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import "github.com/CentaurusInfra/quarkcm/cmd" + +func main() { + cmd.Execute() +} diff --git a/pkg/client/run.go b/pkg/client/run.go new file mode 100644 index 0000000..108bf8d --- /dev/null +++ b/pkg/client/run.go @@ -0,0 +1,40 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "log" + + "github.com/CentaurusInfra/quarkcm/pkg/controller" + "github.com/CentaurusInfra/quarkcm/pkg/handlers" +) + +// Run runs the event loop processing with given handler +func Run() { + + var eventHandler = NewEventHandler() + controller.Start(eventHandler) +} + +func NewEventHandler() handlers.Handler { + + eventHandler := new(handlers.Default) + if err := eventHandler.Init(); err != nil { + log.Fatal(err) + } + return eventHandler +} diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go new file mode 100644 index 0000000..9be1121 --- /dev/null +++ b/pkg/controller/controller.go @@ -0,0 +1,273 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "fmt" + "os" + "os/signal" + "strings" + "syscall" + "time" + + "github.com/CentaurusInfra/quarkcm/pkg/event" + "github.com/CentaurusInfra/quarkcm/pkg/handlers" + "github.com/CentaurusInfra/quarkcm/pkg/utils" + "github.com/sirupsen/logrus" + + api_v1 "k8s.io/api/core/v1" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" +) + +const maxRetries = 5 + +var serverStartTime time.Time + +// Event indicate the informerEvent +type Event struct { + key string + eventType string + namespace string + resourceType string +} + +// Controller object +type Controller struct { + logger *logrus.Entry + clientset kubernetes.Interface + queue workqueue.RateLimitingInterface + informer cache.SharedIndexInformer + eventHandler handlers.Handler +} + +// Start prepares watchers and run their controllers, then waits for process termination signals +func Start(eventHandler handlers.Handler) { + var kubeClient kubernetes.Interface + + if _, err := rest.InClusterConfig(); err != nil { + kubeClient = utils.GetClientOutOfCluster() + } else { + kubeClient = utils.GetClient() + } + + podInformer := cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) { + return kubeClient.CoreV1().Pods("").List(options) + }, + WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) { + return kubeClient.CoreV1().Pods("").Watch(options) + }, + }, + &api_v1.Pod{}, + 0, //Skip resync + cache.Indexers{}, + ) + + podController := newResourceController(kubeClient, eventHandler, podInformer, "pod") + podStopCh := make(chan struct{}) + defer close(podStopCh) + + go podController.Run(podStopCh) + + nodeInformer := cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) { + return kubeClient.CoreV1().Nodes().List(options) + }, + WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) { + return kubeClient.CoreV1().Nodes().Watch(options) + }, + }, + &api_v1.Node{}, + 0, //Skip resync + cache.Indexers{}, + ) + + nodeController := newResourceController(kubeClient, eventHandler, nodeInformer, "node") + nodeStopCh := make(chan struct{}) + defer close(nodeStopCh) + + go nodeController.Run(nodeStopCh) + + sigterm := make(chan os.Signal, 1) + signal.Notify(sigterm, syscall.SIGTERM) + signal.Notify(sigterm, syscall.SIGINT) + <-sigterm +} + +func newResourceController(client kubernetes.Interface, eventHandler handlers.Handler, informer cache.SharedIndexInformer, resourceType string) *Controller { + queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) + var newEvent Event + var err error + informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + newEvent.key, err = cache.MetaNamespaceKeyFunc(obj) + newEvent.eventType = "create" + newEvent.resourceType = resourceType + logrus.WithField("pkg", "quarkcm-"+resourceType).Infof("Processing add to %v: %s", resourceType, newEvent.key) + if err == nil { + queue.Add(newEvent) + } + }, + UpdateFunc: func(old, new interface{}) { + newEvent.key, err = cache.MetaNamespaceKeyFunc(old) + newEvent.eventType = "update" + newEvent.resourceType = resourceType + logrus.WithField("pkg", "quarkcm-"+resourceType).Infof("Processing update to %v: %s", resourceType, newEvent.key) + if err == nil { + queue.Add(newEvent) + } + }, + DeleteFunc: func(obj interface{}) { + newEvent.key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj) + newEvent.eventType = "delete" + newEvent.resourceType = resourceType + newEvent.namespace = utils.GetObjectMetaData(obj).Namespace + logrus.WithField("pkg", "quarkcm-"+resourceType).Infof("Processing delete to %v: %s", resourceType, newEvent.key) + if err == nil { + queue.Add(newEvent) + } + }, + }) + + return &Controller{ + logger: logrus.WithField("pkg", "quarkcm-"+resourceType), + clientset: client, + informer: informer, + queue: queue, + eventHandler: eventHandler, + } +} + +// Run starts the quarkcm controller +func (c *Controller) Run(stopCh <-chan struct{}) { + defer utilruntime.HandleCrash() + defer c.queue.ShutDown() + + c.logger.Info("Starting quarkcm controller") + serverStartTime = time.Now().Local() + + go c.informer.Run(stopCh) + + if !cache.WaitForCacheSync(stopCh, c.HasSynced) { + utilruntime.HandleError(fmt.Errorf("Timed out waiting for caches to sync")) + return + } + + c.logger.Info("quarkcm controller synced and ready") + + wait.Until(c.runWorker, time.Second, stopCh) +} + +// HasSynced is required for the cache.Controller interface. +func (c *Controller) HasSynced() bool { + return c.informer.HasSynced() +} + +// LastSyncResourceVersion is required for the cache.Controller interface. +func (c *Controller) LastSyncResourceVersion() string { + return c.informer.LastSyncResourceVersion() +} + +func (c *Controller) runWorker() { + for c.processNextItem() { + // continue looping + } +} + +func (c *Controller) processNextItem() bool { + newEvent, quit := c.queue.Get() + + if quit { + return false + } + defer c.queue.Done(newEvent) + err := c.processItem(newEvent.(Event)) + if err == nil { + // No error, reset the ratelimit counters + c.queue.Forget(newEvent) + } else if c.queue.NumRequeues(newEvent) < maxRetries { + c.logger.Errorf("Error processing %s (will retry): %v", newEvent.(Event).key, err) + c.queue.AddRateLimited(newEvent) + } else { + // err != nil and too many retries + c.logger.Errorf("Error processing %s (giving up): %v", newEvent.(Event).key, err) + c.queue.Forget(newEvent) + utilruntime.HandleError(err) + } + + return true +} + +func (c *Controller) processItem(newEvent Event) error { + obj, _, err := c.informer.GetIndexer().GetByKey(newEvent.key) + if err != nil { + return fmt.Errorf("Error fetching object with key %s from store: %v", newEvent.key, err) + } + // get object's metedata + objectMeta := utils.GetObjectMetaData(obj) + + // namespace retrived from event key incase namespace value is empty + if newEvent.namespace == "" && strings.Contains(newEvent.key, "/") { + substring := strings.Split(newEvent.key, "/") + newEvent.namespace = substring[0] + newEvent.key = substring[1] + } + + // process events based on its type + switch newEvent.eventType { + case "create": + if objectMeta.CreationTimestamp.Sub(serverStartTime).Seconds() > 0 { + kbEvent := event.Event{ + Name: objectMeta.Name, + Namespace: newEvent.namespace, + Kind: newEvent.resourceType, + Reason: "Created", + } + c.eventHandler.Handle(kbEvent) + return nil + } + case "update": + kbEvent := event.Event{ + Name: newEvent.key, + Namespace: newEvent.namespace, + Kind: newEvent.resourceType, + Reason: "Updated", + } + c.eventHandler.Handle(kbEvent) + return nil + case "delete": + kbEvent := event.Event{ + Name: newEvent.key, + Namespace: newEvent.namespace, + Kind: newEvent.resourceType, + Reason: "Deleted", + } + c.eventHandler.Handle(kbEvent) + return nil + } + return nil +} diff --git a/pkg/event/event.go b/pkg/event/event.go new file mode 100644 index 0000000..3c5b842 --- /dev/null +++ b/pkg/event/event.go @@ -0,0 +1,95 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package event + +import ( + "fmt" + + "github.com/CentaurusInfra/quarkcm/pkg/utils" + api_v1 "k8s.io/api/core/v1" +) + +// Event represent an event got from k8s api server +type Event struct { + Namespace string + Kind string + Component string + Host string + Reason string + Name string +} + +// New create new Event +func New(obj interface{}, action string) Event { + var namespace, kind, component, host, reason, name string + + objectMeta := utils.GetObjectMetaData(obj) + namespace = objectMeta.Namespace + name = objectMeta.Name + reason = action + + switch object := obj.(type) { + case *api_v1.Pod: + kind = "pod" + host = object.Spec.NodeName + case *api_v1.Node: + kind = "node" + case Event: + name = object.Name + kind = object.Kind + namespace = object.Namespace + } + + kbEvent := Event{ + Namespace: namespace, + Kind: kind, + Component: component, + Host: host, + Reason: reason, + Name: name, + } + return kbEvent +} + +// Message returns event message in standard format. +// included as a part of event packege to enhance code resuablity across handlers. +func (e *Event) Message() (msg string) { + // using switch over if..else, since the format could vary based on the kind of the object in future. + switch e.Kind { + case "pod": + msg = fmt.Sprintf( + "A pod `%s` has been `%s`", + e.Name, + e.Reason, + ) + case "node": + msg = fmt.Sprintf( + "A node `%s` has been `%s`", + e.Name, + e.Reason, + ) + default: + msg = fmt.Sprintf( + "A `%s` in namespace `%s` has been `%s`:\n`%s`", + e.Kind, + e.Namespace, + e.Reason, + e.Name, + ) + } + return msg +} diff --git a/pkg/handlers/handler.go b/pkg/handlers/handler.go new file mode 100644 index 0000000..1c0def1 --- /dev/null +++ b/pkg/handlers/handler.go @@ -0,0 +1,49 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package handlers + +import ( + "log" + + "github.com/CentaurusInfra/quarkcm/pkg/event" +) + +// Handler is implemented by any handler. +// The Handle method is used to process event +type Handler interface { + Init() error + Handle(e event.Event) +} + +// Map maps each event handler function to a name for easily lookup +var Map = map[string]interface{}{ + "default": &Default{}, +} + +// Default handler implements Handler interface, +// print each event with JSON format +type Default struct { +} + +func (d *Default) Init() error { + return nil +} + +// Handle handles an event. +func (d *Default) Handle(e event.Event) { + log.Printf("Handle event %s", e) +} diff --git a/pkg/utils/k8sutil.go b/pkg/utils/k8sutil.go new file mode 100644 index 0000000..99678ed --- /dev/null +++ b/pkg/utils/k8sutil.go @@ -0,0 +1,64 @@ +package utils + +import ( + "os" + + "github.com/sirupsen/logrus" + api_v1 "k8s.io/api/core/v1" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" +) + +// GetClient returns a k8s clientset to the request from inside of cluster +func GetClient() kubernetes.Interface { + config, err := rest.InClusterConfig() + if err != nil { + logrus.Fatalf("Can not get kubernetes config: %v", err) + } + + clientset, err := kubernetes.NewForConfig(config) + if err != nil { + logrus.Fatalf("Can not create kubernetes client: %v", err) + } + + return clientset +} + +func buildOutOfClusterConfig() (*rest.Config, error) { + kubeconfigPath := os.Getenv("KUBECONFIG") + if kubeconfigPath == "" { + kubeconfigPath = os.Getenv("HOME") + "/.kube/config" + } + return clientcmd.BuildConfigFromFlags("", kubeconfigPath) +} + +// GetClientOutOfCluster returns a k8s clientset to the request from outside of cluster +func GetClientOutOfCluster() kubernetes.Interface { + config, err := buildOutOfClusterConfig() + if err != nil { + logrus.Fatalf("Can not get kubernetes config: %v", err) + } + + clientset, err := kubernetes.NewForConfig(config) + if err != nil { + logrus.Fatalf("Can not get kubernetes config: %v", err) + } + + return clientset +} + +// GetObjectMetaData returns metadata of a given k8s object +func GetObjectMetaData(obj interface{}) (objectMeta meta_v1.ObjectMeta) { + + switch object := obj.(type) { + case *api_v1.Pod: + objectMeta = object.ObjectMeta + case *api_v1.Node: + objectMeta = object.ObjectMeta + case *api_v1.Event: + objectMeta = object.ObjectMeta + } + return objectMeta +} diff --git a/quarkcm-in-cluster.yaml b/quarkcm-in-cluster.yaml new file mode 100644 index 0000000..32bb466 --- /dev/null +++ b/quarkcm-in-cluster.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Pod +metadata: + name: quarkcm + namespace: default +spec: + containers: + - image: quarkcm:latest + imagePullPolicy: Always + name: quarkcm + volumeMounts: + - name: quarkcm-volume + mountPath: /root + restartPolicy: Always + volumes: + - name: quarkcm-volume + hostPath: + path: /var + type: Directory diff --git a/quarkcm-service-account.yaml b/quarkcm-service-account.yaml new file mode 100644 index 0000000..f09d037 --- /dev/null +++ b/quarkcm-service-account.yaml @@ -0,0 +1,28 @@ +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: quarkcm +rules: +- apiGroups: [""] + resources: ["pods", "replicationcontrollers"] + verbs: ["get", "watch", "list"] +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: quarkcm + namespace: default +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: quarkcm +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: quarkcm +subjects: + - kind: ServiceAccount + name: quarkcm + namespace: default diff --git a/quarkcm.yaml b/quarkcm.yaml new file mode 100644 index 0000000..8e90a55 --- /dev/null +++ b/quarkcm.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Pod +metadata: + name: quarkcm + namespace: default +spec: + containers: + - image: quarkcm # After upload to docker hub, change the value here + imagePullPolicy: Always + name: quarkcm + volumeMounts: + - name: quarkcm-volume + mountPath: /root + restartPolicy: Always + volumes: + - name: quarkcm-volume + hostPath: + path: /var + type: Directory \ No newline at end of file From ffe4a2a0479be030288176c20b9fa05367da9cfb Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Sat, 2 Apr 2022 00:08:25 +0000 Subject: [PATCH 02/24] Change log provider to klog --- cmd/version.go | 10 +++------- go.mod | 2 +- go.sum | 2 -- main.go | 8 +++++++- pkg/controller/controller.go | 22 +++++++++++----------- pkg/utils/k8sutil.go | 10 +++++----- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/cmd/version.go b/cmd/version.go index 128bcbb..d9ac19a 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -17,12 +17,9 @@ limitations under the License. package cmd import ( - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" -) + "fmt" -var ( - buildDate, gitCommit string + "github.com/spf13/cobra" ) var versionCmd = &cobra.Command{ @@ -35,8 +32,7 @@ var versionCmd = &cobra.Command{ } func versionPrettyString() { - logrus.Info("gitCommit: ", gitCommit) - logrus.Info("buildDate: ", buildDate) + fmt.Println("v0.1") } func init() { diff --git a/go.mod b/go.mod index d8d3ced..3fff1f5 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,6 @@ require ( github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/pelletier/go-toml v1.0.1 // indirect github.com/segmentio/textio v1.2.0 - github.com/sirupsen/logrus v1.6.0 github.com/spf13/cast v1.1.0 // indirect github.com/spf13/cobra v0.0.1 github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec // indirect @@ -31,4 +30,5 @@ require ( k8s.io/api v0.16.8 k8s.io/apimachinery v0.16.8 k8s.io/client-go v0.16.8 + k8s.io/klog v1.0.0 // indirect ) diff --git a/go.sum b/go.sum index aee4602..9b03a38 100644 --- a/go.sum +++ b/go.sum @@ -128,8 +128,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/segmentio/textio v1.2.0 h1:Ug4IkV3kh72juJbG8azoSBlgebIbUUxVNrfFcKHfTSQ= github.com/segmentio/textio v1.2.0/go.mod h1:+Rb7v0YVODP+tK5F7FD9TCkV7gOYx9IgLHWiqtvY8ag= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.1.0 h1:0Rhw4d6C8J9VPu6cjZLIhZ8+aAOHcDvGeKn+cq5Aq3k= diff --git a/main.go b/main.go index 0329c86..f7726d0 100644 --- a/main.go +++ b/main.go @@ -16,8 +16,14 @@ limitations under the License. package main -import "github.com/CentaurusInfra/quarkcm/cmd" +import ( + "github.com/CentaurusInfra/quarkcm/cmd" + "k8s.io/klog" +) func main() { + klog.InitFlags(nil) + defer klog.Flush() + cmd.Execute() } diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 9be1121..0277c51 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -27,7 +27,7 @@ import ( "github.com/CentaurusInfra/quarkcm/pkg/event" "github.com/CentaurusInfra/quarkcm/pkg/handlers" "github.com/CentaurusInfra/quarkcm/pkg/utils" - "github.com/sirupsen/logrus" + "k8s.io/klog" api_v1 "k8s.io/api/core/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -55,7 +55,7 @@ type Event struct { // Controller object type Controller struct { - logger *logrus.Entry + resourceType string clientset kubernetes.Interface queue workqueue.RateLimitingInterface informer cache.SharedIndexInformer @@ -127,7 +127,7 @@ func newResourceController(client kubernetes.Interface, eventHandler handlers.Ha newEvent.key, err = cache.MetaNamespaceKeyFunc(obj) newEvent.eventType = "create" newEvent.resourceType = resourceType - logrus.WithField("pkg", "quarkcm-"+resourceType).Infof("Processing add to %v: %s", resourceType, newEvent.key) + klog.Infof("Processing add to %v: %s", resourceType, newEvent.key) if err == nil { queue.Add(newEvent) } @@ -136,7 +136,7 @@ func newResourceController(client kubernetes.Interface, eventHandler handlers.Ha newEvent.key, err = cache.MetaNamespaceKeyFunc(old) newEvent.eventType = "update" newEvent.resourceType = resourceType - logrus.WithField("pkg", "quarkcm-"+resourceType).Infof("Processing update to %v: %s", resourceType, newEvent.key) + klog.Infof("Processing update to %v: %s", resourceType, newEvent.key) if err == nil { queue.Add(newEvent) } @@ -146,7 +146,7 @@ func newResourceController(client kubernetes.Interface, eventHandler handlers.Ha newEvent.eventType = "delete" newEvent.resourceType = resourceType newEvent.namespace = utils.GetObjectMetaData(obj).Namespace - logrus.WithField("pkg", "quarkcm-"+resourceType).Infof("Processing delete to %v: %s", resourceType, newEvent.key) + klog.Infof("Processing delete to %v: %s", resourceType, newEvent.key) if err == nil { queue.Add(newEvent) } @@ -154,7 +154,7 @@ func newResourceController(client kubernetes.Interface, eventHandler handlers.Ha }) return &Controller{ - logger: logrus.WithField("pkg", "quarkcm-"+resourceType), + resourceType: resourceType, clientset: client, informer: informer, queue: queue, @@ -167,17 +167,17 @@ func (c *Controller) Run(stopCh <-chan struct{}) { defer utilruntime.HandleCrash() defer c.queue.ShutDown() - c.logger.Info("Starting quarkcm controller") + klog.Infof("Starting quarkcm %s controller", c.resourceType) serverStartTime = time.Now().Local() go c.informer.Run(stopCh) if !cache.WaitForCacheSync(stopCh, c.HasSynced) { - utilruntime.HandleError(fmt.Errorf("Timed out waiting for caches to sync")) + utilruntime.HandleError(fmt.Errorf("%s controller timed out waiting for caches to sync", c.resourceType)) return } - c.logger.Info("quarkcm controller synced and ready") + klog.Infof("quarkcm %s controller synced and ready", c.resourceType) wait.Until(c.runWorker, time.Second, stopCh) } @@ -210,11 +210,11 @@ func (c *Controller) processNextItem() bool { // No error, reset the ratelimit counters c.queue.Forget(newEvent) } else if c.queue.NumRequeues(newEvent) < maxRetries { - c.logger.Errorf("Error processing %s (will retry): %v", newEvent.(Event).key, err) + klog.Errorf("Error processing %s (will retry): %v", newEvent.(Event).key, err) c.queue.AddRateLimited(newEvent) } else { // err != nil and too many retries - c.logger.Errorf("Error processing %s (giving up): %v", newEvent.(Event).key, err) + klog.Errorf("Error processing %s (giving up): %v", newEvent.(Event).key, err) c.queue.Forget(newEvent) utilruntime.HandleError(err) } diff --git a/pkg/utils/k8sutil.go b/pkg/utils/k8sutil.go index 99678ed..237f811 100644 --- a/pkg/utils/k8sutil.go +++ b/pkg/utils/k8sutil.go @@ -3,24 +3,24 @@ package utils import ( "os" - "github.com/sirupsen/logrus" api_v1 "k8s.io/api/core/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + "k8s.io/klog" ) // GetClient returns a k8s clientset to the request from inside of cluster func GetClient() kubernetes.Interface { config, err := rest.InClusterConfig() if err != nil { - logrus.Fatalf("Can not get kubernetes config: %v", err) + klog.Fatalf("Can not get kubernetes config: %v", err) } clientset, err := kubernetes.NewForConfig(config) if err != nil { - logrus.Fatalf("Can not create kubernetes client: %v", err) + klog.Fatalf("Can not create kubernetes client: %v", err) } return clientset @@ -38,12 +38,12 @@ func buildOutOfClusterConfig() (*rest.Config, error) { func GetClientOutOfCluster() kubernetes.Interface { config, err := buildOutOfClusterConfig() if err != nil { - logrus.Fatalf("Can not get kubernetes config: %v", err) + klog.Fatalf("Can not get kubernetes config: %v", err) } clientset, err := kubernetes.NewForConfig(config) if err != nil { - logrus.Fatalf("Can not get kubernetes config: %v", err) + klog.Fatalf("Can not get kubernetes config: %v", err) } return clientset From 7793cd8c91167b0e266efae1438620d8e2ad9c83 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Sat, 2 Apr 2022 05:13:08 +0000 Subject: [PATCH 03/24] Deploy to cluster --- README.md | 12 ++++++- cmd/version.go | 2 +- deploy-quarkcm.yaml | 61 ++++++++++++++++++++++++++++++++++++ quarkcm-in-cluster.yaml | 19 ----------- quarkcm-service-account.yaml | 28 ----------------- quarkcm.yaml | 19 ----------- 6 files changed, 73 insertions(+), 68 deletions(-) create mode 100644 deploy-quarkcm.yaml delete mode 100644 quarkcm-in-cluster.yaml delete mode 100644 quarkcm-service-account.yaml delete mode 100644 quarkcm.yaml diff --git a/README.md b/README.md index 67b220f..95906b5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,13 @@ # quarkcm -quarkcm is Connection Manager for Quark CDMA Networking Solution. \ No newline at end of file +quarkcm is Connection Manager for Quark CDMA Networking Solution. + +## push to docker hub +sudo docker login -u quarkcm + +sudo docker image build -t quarkcm/quarkcm:v0.1.0 -f Dockerfile . +sudo docker image push quarkcm/quarkcm:v0.1.0 + + +## deploy to cluster +kubectl apply -f deploy-quarkcm.yaml diff --git a/cmd/version.go b/cmd/version.go index d9ac19a..2dd0016 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -32,7 +32,7 @@ var versionCmd = &cobra.Command{ } func versionPrettyString() { - fmt.Println("v0.1") + fmt.Println("v0.1.0") } func init() { diff --git a/deploy-quarkcm.yaml b/deploy-quarkcm.yaml new file mode 100644 index 0000000..6c1fc98 --- /dev/null +++ b/deploy-quarkcm.yaml @@ -0,0 +1,61 @@ +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: quarkcm-operator +rules: +- apiGroups: [""] + resources: ["pods", "nodes"] + verbs: ["get", "watch", "list"] +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: quarkcm-operator + namespace: default +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: quarkcm-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: quarkcm-operator +subjects: + - kind: ServiceAccount + name: quarkcm-operator + namespace: default +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: quarkcm-daemon + namespace: default +spec: + selector: + matchLabels: + job: quarkcm-daemon + template: + metadata: + labels: + job: quarkcm-daemon + spec: + tolerations: + # The daemon shall run on the master node + - effect: NoSchedule + operator: Exists + serviceAccountName: quarkcm-operator + terminationGracePeriodSeconds: 0 + hostNetwork: true + hostPID: true + containers: + - name: quarkcm-daemon + image: quarkcm/quarkcm:v0.1.0 + securityContext: + privileged: true + volumes: + - name: quarkcm-volume + hostPath: + path: /var + type: Directory diff --git a/quarkcm-in-cluster.yaml b/quarkcm-in-cluster.yaml deleted file mode 100644 index 32bb466..0000000 --- a/quarkcm-in-cluster.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: quarkcm - namespace: default -spec: - containers: - - image: quarkcm:latest - imagePullPolicy: Always - name: quarkcm - volumeMounts: - - name: quarkcm-volume - mountPath: /root - restartPolicy: Always - volumes: - - name: quarkcm-volume - hostPath: - path: /var - type: Directory diff --git a/quarkcm-service-account.yaml b/quarkcm-service-account.yaml deleted file mode 100644 index f09d037..0000000 --- a/quarkcm-service-account.yaml +++ /dev/null @@ -1,28 +0,0 @@ ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: quarkcm -rules: -- apiGroups: [""] - resources: ["pods", "replicationcontrollers"] - verbs: ["get", "watch", "list"] ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: quarkcm - namespace: default ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRoleBinding -metadata: - name: quarkcm -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: quarkcm -subjects: - - kind: ServiceAccount - name: quarkcm - namespace: default diff --git a/quarkcm.yaml b/quarkcm.yaml deleted file mode 100644 index 8e90a55..0000000 --- a/quarkcm.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: quarkcm - namespace: default -spec: - containers: - - image: quarkcm # After upload to docker hub, change the value here - imagePullPolicy: Always - name: quarkcm - volumeMounts: - - name: quarkcm-volume - mountPath: /root - restartPolicy: Always - volumes: - - name: quarkcm-volume - hostPath: - path: /var - type: Directory \ No newline at end of file From 437bdc270bf5eb8a17be3b99358666b6024df775 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Mon, 4 Apr 2022 18:08:25 +0000 Subject: [PATCH 04/24] Rename event to eventItem --- pkg/controller/controller.go | 88 ++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 0277c51..93412dd 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -45,8 +45,7 @@ const maxRetries = 5 var serverStartTime time.Time -// Event indicate the informerEvent -type Event struct { +type EventItem struct { key string eventType string namespace string @@ -120,35 +119,35 @@ func Start(eventHandler handlers.Handler) { func newResourceController(client kubernetes.Interface, eventHandler handlers.Handler, informer cache.SharedIndexInformer, resourceType string) *Controller { queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) - var newEvent Event + var eventItem EventItem var err error informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { - newEvent.key, err = cache.MetaNamespaceKeyFunc(obj) - newEvent.eventType = "create" - newEvent.resourceType = resourceType - klog.Infof("Processing add to %v: %s", resourceType, newEvent.key) + eventItem.key, err = cache.MetaNamespaceKeyFunc(obj) + eventItem.eventType = "create" + eventItem.resourceType = resourceType + klog.Infof("Processing add to %v: %s", resourceType, eventItem.key) if err == nil { - queue.Add(newEvent) + queue.Add(eventItem) } }, UpdateFunc: func(old, new interface{}) { - newEvent.key, err = cache.MetaNamespaceKeyFunc(old) - newEvent.eventType = "update" - newEvent.resourceType = resourceType - klog.Infof("Processing update to %v: %s", resourceType, newEvent.key) + eventItem.key, err = cache.MetaNamespaceKeyFunc(old) + eventItem.eventType = "update" + eventItem.resourceType = resourceType + klog.Infof("Processing update to %v: %s", resourceType, eventItem.key) if err == nil { - queue.Add(newEvent) + queue.Add(eventItem) } }, DeleteFunc: func(obj interface{}) { - newEvent.key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj) - newEvent.eventType = "delete" - newEvent.resourceType = resourceType - newEvent.namespace = utils.GetObjectMetaData(obj).Namespace - klog.Infof("Processing delete to %v: %s", resourceType, newEvent.key) + eventItem.key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj) + eventItem.eventType = "delete" + eventItem.resourceType = resourceType + eventItem.namespace = utils.GetObjectMetaData(obj).Namespace + klog.Infof("Processing delete to %v: %s", resourceType, eventItem.key) if err == nil { - queue.Add(newEvent) + queue.Add(eventItem) } }, }) @@ -199,52 +198,53 @@ func (c *Controller) runWorker() { } func (c *Controller) processNextItem() bool { - newEvent, quit := c.queue.Get() + queueItem, quit := c.queue.Get() + eventItem := queueItem.(EventItem) if quit { return false } - defer c.queue.Done(newEvent) - err := c.processItem(newEvent.(Event)) + defer c.queue.Done(queueItem) + err := c.processItem(eventItem) if err == nil { // No error, reset the ratelimit counters - c.queue.Forget(newEvent) - } else if c.queue.NumRequeues(newEvent) < maxRetries { - klog.Errorf("Error processing %s (will retry): %v", newEvent.(Event).key, err) - c.queue.AddRateLimited(newEvent) + c.queue.Forget(queueItem) + } else if c.queue.NumRequeues(queueItem) < maxRetries { + klog.Errorf("error processing %s (will retry): %v", eventItem.key, err) + c.queue.AddRateLimited(queueItem) } else { // err != nil and too many retries - klog.Errorf("Error processing %s (giving up): %v", newEvent.(Event).key, err) - c.queue.Forget(newEvent) + klog.Errorf("error processing %s (giving up): %v", eventItem.key, err) + c.queue.Forget(queueItem) utilruntime.HandleError(err) } return true } -func (c *Controller) processItem(newEvent Event) error { - obj, _, err := c.informer.GetIndexer().GetByKey(newEvent.key) +func (c *Controller) processItem(eventItem EventItem) error { + obj, _, err := c.informer.GetIndexer().GetByKey(eventItem.key) if err != nil { - return fmt.Errorf("Error fetching object with key %s from store: %v", newEvent.key, err) + return fmt.Errorf("error fetching object with key %s from store: %v", eventItem.key, err) } // get object's metedata objectMeta := utils.GetObjectMetaData(obj) // namespace retrived from event key incase namespace value is empty - if newEvent.namespace == "" && strings.Contains(newEvent.key, "/") { - substring := strings.Split(newEvent.key, "/") - newEvent.namespace = substring[0] - newEvent.key = substring[1] + if eventItem.namespace == "" && strings.Contains(eventItem.key, "/") { + substring := strings.Split(eventItem.key, "/") + eventItem.namespace = substring[0] + eventItem.key = substring[1] } // process events based on its type - switch newEvent.eventType { + switch eventItem.eventType { case "create": if objectMeta.CreationTimestamp.Sub(serverStartTime).Seconds() > 0 { kbEvent := event.Event{ Name: objectMeta.Name, - Namespace: newEvent.namespace, - Kind: newEvent.resourceType, + Namespace: eventItem.namespace, + Kind: eventItem.resourceType, Reason: "Created", } c.eventHandler.Handle(kbEvent) @@ -252,18 +252,18 @@ func (c *Controller) processItem(newEvent Event) error { } case "update": kbEvent := event.Event{ - Name: newEvent.key, - Namespace: newEvent.namespace, - Kind: newEvent.resourceType, + Name: eventItem.key, + Namespace: eventItem.namespace, + Kind: eventItem.resourceType, Reason: "Updated", } c.eventHandler.Handle(kbEvent) return nil case "delete": kbEvent := event.Event{ - Name: newEvent.key, - Namespace: newEvent.namespace, - Kind: newEvent.resourceType, + Name: eventItem.key, + Namespace: eventItem.namespace, + Kind: eventItem.resourceType, Reason: "Deleted", } c.eventHandler.Handle(kbEvent) From a6319b00ac2cce874be95a39851308aed2c9c5b0 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Mon, 4 Apr 2022 19:20:03 +0000 Subject: [PATCH 05/24] Add different controller --- pkg/client/run.go | 16 +--- pkg/controller/controller.go | 98 +++--------------------- pkg/controller/controllerbuilder.go | 111 ++++++++++++++++++++++++++++ pkg/handlers/handler.go | 23 ------ pkg/handlers/nodehandler.go | 35 +++++++++ pkg/handlers/podhandler.go | 35 +++++++++ 6 files changed, 192 insertions(+), 126 deletions(-) create mode 100644 pkg/controller/controllerbuilder.go create mode 100644 pkg/handlers/nodehandler.go create mode 100644 pkg/handlers/podhandler.go diff --git a/pkg/client/run.go b/pkg/client/run.go index 108bf8d..36af9ef 100644 --- a/pkg/client/run.go +++ b/pkg/client/run.go @@ -17,24 +17,10 @@ limitations under the License. package client import ( - "log" - "github.com/CentaurusInfra/quarkcm/pkg/controller" - "github.com/CentaurusInfra/quarkcm/pkg/handlers" ) // Run runs the event loop processing with given handler func Run() { - - var eventHandler = NewEventHandler() - controller.Start(eventHandler) -} - -func NewEventHandler() handlers.Handler { - - eventHandler := new(handlers.Default) - if err := eventHandler.Init(); err != nil { - log.Fatal(err) - } - return eventHandler + controller.Start() } diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 93412dd..3db2489 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -29,12 +29,8 @@ import ( "github.com/CentaurusInfra/quarkcm/pkg/utils" "k8s.io/klog" - api_v1 "k8s.io/api/core/v1" - meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" @@ -62,7 +58,7 @@ type Controller struct { } // Start prepares watchers and run their controllers, then waits for process termination signals -func Start(eventHandler handlers.Handler) { +func Start() { var kubeClient kubernetes.Interface if _, err := rest.InClusterConfig(); err != nil { @@ -71,41 +67,13 @@ func Start(eventHandler handlers.Handler) { kubeClient = utils.GetClient() } - podInformer := cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) { - return kubeClient.CoreV1().Pods("").List(options) - }, - WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) { - return kubeClient.CoreV1().Pods("").Watch(options) - }, - }, - &api_v1.Pod{}, - 0, //Skip resync - cache.Indexers{}, - ) - - podController := newResourceController(kubeClient, eventHandler, podInformer, "pod") + podController := NewPodController(kubeClient) podStopCh := make(chan struct{}) defer close(podStopCh) go podController.Run(podStopCh) - nodeInformer := cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) { - return kubeClient.CoreV1().Nodes().List(options) - }, - WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) { - return kubeClient.CoreV1().Nodes().Watch(options) - }, - }, - &api_v1.Node{}, - 0, //Skip resync - cache.Indexers{}, - ) - - nodeController := newResourceController(kubeClient, eventHandler, nodeInformer, "node") + nodeController := NewNodeController(kubeClient) nodeStopCh := make(chan struct{}) defer close(nodeStopCh) @@ -117,50 +85,6 @@ func Start(eventHandler handlers.Handler) { <-sigterm } -func newResourceController(client kubernetes.Interface, eventHandler handlers.Handler, informer cache.SharedIndexInformer, resourceType string) *Controller { - queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) - var eventItem EventItem - var err error - informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - eventItem.key, err = cache.MetaNamespaceKeyFunc(obj) - eventItem.eventType = "create" - eventItem.resourceType = resourceType - klog.Infof("Processing add to %v: %s", resourceType, eventItem.key) - if err == nil { - queue.Add(eventItem) - } - }, - UpdateFunc: func(old, new interface{}) { - eventItem.key, err = cache.MetaNamespaceKeyFunc(old) - eventItem.eventType = "update" - eventItem.resourceType = resourceType - klog.Infof("Processing update to %v: %s", resourceType, eventItem.key) - if err == nil { - queue.Add(eventItem) - } - }, - DeleteFunc: func(obj interface{}) { - eventItem.key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj) - eventItem.eventType = "delete" - eventItem.resourceType = resourceType - eventItem.namespace = utils.GetObjectMetaData(obj).Namespace - klog.Infof("Processing delete to %v: %s", resourceType, eventItem.key) - if err == nil { - queue.Add(eventItem) - } - }, - }) - - return &Controller{ - resourceType: resourceType, - clientset: client, - informer: informer, - queue: queue, - eventHandler: eventHandler, - } -} - // Run starts the quarkcm controller func (c *Controller) Run(stopCh <-chan struct{}) { defer utilruntime.HandleCrash() @@ -240,16 +164,14 @@ func (c *Controller) processItem(eventItem EventItem) error { // process events based on its type switch eventItem.eventType { case "create": - if objectMeta.CreationTimestamp.Sub(serverStartTime).Seconds() > 0 { - kbEvent := event.Event{ - Name: objectMeta.Name, - Namespace: eventItem.namespace, - Kind: eventItem.resourceType, - Reason: "Created", - } - c.eventHandler.Handle(kbEvent) - return nil + kbEvent := event.Event{ + Name: objectMeta.Name, + Namespace: eventItem.namespace, + Kind: eventItem.resourceType, + Reason: "Created", } + c.eventHandler.Handle(kbEvent) + return nil case "update": kbEvent := event.Event{ Name: eventItem.key, diff --git a/pkg/controller/controllerbuilder.go b/pkg/controller/controllerbuilder.go new file mode 100644 index 0000000..b8b7a7e --- /dev/null +++ b/pkg/controller/controllerbuilder.go @@ -0,0 +1,111 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "github.com/CentaurusInfra/quarkcm/pkg/handlers" + "github.com/CentaurusInfra/quarkcm/pkg/utils" + api_v1 "k8s.io/api/core/v1" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/klog" + + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" +) + +func NewPodController(client kubernetes.Interface) *Controller { + var eventHandler handlers.Handler = new(handlers.PodHandler) + informer := cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) { + return client.CoreV1().Pods("").List(options) + }, + WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) { + return client.CoreV1().Pods("").Watch(options) + }, + }, + &api_v1.Pod{}, + 0, + cache.Indexers{}, + ) + return newResourceController(client, eventHandler, informer, "pod") +} + +func NewNodeController(client kubernetes.Interface) *Controller { + var eventHandler handlers.Handler = new(handlers.NodeHandler) + informer := cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) { + return client.CoreV1().Nodes().List(options) + }, + WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) { + return client.CoreV1().Nodes().Watch(options) + }, + }, + &api_v1.Node{}, + 0, + cache.Indexers{}, + ) + return newResourceController(client, eventHandler, informer, "node") +} + +func newResourceController(client kubernetes.Interface, eventHandler handlers.Handler, informer cache.SharedIndexInformer, resourceType string) *Controller { + queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) + var eventItem EventItem + var err error + informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + eventItem.key, err = cache.MetaNamespaceKeyFunc(obj) + eventItem.eventType = "create" + eventItem.resourceType = resourceType + klog.Infof("Processing add to %v: %s", resourceType, eventItem.key) + if err == nil { + queue.Add(eventItem) + } + }, + UpdateFunc: func(old, new interface{}) { + eventItem.key, err = cache.MetaNamespaceKeyFunc(old) + eventItem.eventType = "update" + eventItem.resourceType = resourceType + klog.Infof("Processing update to %v: %s", resourceType, eventItem.key) + if err == nil { + queue.Add(eventItem) + } + }, + DeleteFunc: func(obj interface{}) { + eventItem.key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj) + eventItem.eventType = "delete" + eventItem.resourceType = resourceType + eventItem.namespace = utils.GetObjectMetaData(obj).Namespace + klog.Infof("Processing delete to %v: %s", resourceType, eventItem.key) + if err == nil { + queue.Add(eventItem) + } + }, + }) + + return &Controller{ + resourceType: resourceType, + clientset: client, + informer: informer, + queue: queue, + eventHandler: eventHandler, + } +} diff --git a/pkg/handlers/handler.go b/pkg/handlers/handler.go index 1c0def1..7ba7a7b 100644 --- a/pkg/handlers/handler.go +++ b/pkg/handlers/handler.go @@ -17,33 +17,10 @@ limitations under the License. package handlers import ( - "log" - "github.com/CentaurusInfra/quarkcm/pkg/event" ) -// Handler is implemented by any handler. -// The Handle method is used to process event type Handler interface { Init() error Handle(e event.Event) } - -// Map maps each event handler function to a name for easily lookup -var Map = map[string]interface{}{ - "default": &Default{}, -} - -// Default handler implements Handler interface, -// print each event with JSON format -type Default struct { -} - -func (d *Default) Init() error { - return nil -} - -// Handle handles an event. -func (d *Default) Handle(e event.Event) { - log.Printf("Handle event %s", e) -} diff --git a/pkg/handlers/nodehandler.go b/pkg/handlers/nodehandler.go new file mode 100644 index 0000000..102077e --- /dev/null +++ b/pkg/handlers/nodehandler.go @@ -0,0 +1,35 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package handlers + +import ( + "k8s.io/klog" + + "github.com/CentaurusInfra/quarkcm/pkg/event" +) + +type NodeHandler struct { +} + +func (d *NodeHandler) Init() error { + return nil +} + +// Handle handles an event. +func (d *NodeHandler) Handle(e event.Event) { + klog.Infof("Handle node event %s", e) +} diff --git a/pkg/handlers/podhandler.go b/pkg/handlers/podhandler.go new file mode 100644 index 0000000..b933943 --- /dev/null +++ b/pkg/handlers/podhandler.go @@ -0,0 +1,35 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package handlers + +import ( + "k8s.io/klog" + + "github.com/CentaurusInfra/quarkcm/pkg/event" +) + +type PodHandler struct { +} + +func (d *PodHandler) Init() error { + return nil +} + +// Handle handles an event. +func (d *PodHandler) Handle(e event.Event) { + klog.Infof("Handle pod event %s", e) +} From df8724018966540f1dfecc164475b2132c4f9bbd Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Mon, 4 Apr 2022 21:33:47 +0000 Subject: [PATCH 06/24] Simplify controller --- pkg/constants/constants.go | 25 ++++++++++ pkg/controller/controller.go | 46 ++++-------------- pkg/controller/controllerbuilder.go | 14 +++--- pkg/event/event.go | 74 +---------------------------- pkg/handlers/nodehandler.go | 7 ++- pkg/handlers/podhandler.go | 8 +++- pkg/utils/k8sutil.go | 2 - 7 files changed, 54 insertions(+), 122 deletions(-) create mode 100644 pkg/constants/constants.go diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go new file mode 100644 index 0000000..69ceb84 --- /dev/null +++ b/pkg/constants/constants.go @@ -0,0 +1,25 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package constants + +const ( + ResourceType_Pod string = "pod" + ResourceType_Node string = "node" + + EventType_Set string = "set" + EventType_Delete string = "delete" +) diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 3db2489..2013986 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -39,13 +39,10 @@ import ( const maxRetries = 5 -var serverStartTime time.Time - type EventItem struct { - key string - eventType string - namespace string - resourceType string + key string + eventType string + namespace string } // Controller object @@ -91,8 +88,6 @@ func (c *Controller) Run(stopCh <-chan struct{}) { defer c.queue.ShutDown() klog.Infof("Starting quarkcm %s controller", c.resourceType) - serverStartTime = time.Now().Local() - go c.informer.Run(stopCh) if !cache.WaitForCacheSync(stopCh, c.HasSynced) { @@ -161,35 +156,12 @@ func (c *Controller) processItem(eventItem EventItem) error { eventItem.key = substring[1] } - // process events based on its type - switch eventItem.eventType { - case "create": - kbEvent := event.Event{ - Name: objectMeta.Name, - Namespace: eventItem.namespace, - Kind: eventItem.resourceType, - Reason: "Created", - } - c.eventHandler.Handle(kbEvent) - return nil - case "update": - kbEvent := event.Event{ - Name: eventItem.key, - Namespace: eventItem.namespace, - Kind: eventItem.resourceType, - Reason: "Updated", - } - c.eventHandler.Handle(kbEvent) - return nil - case "delete": - kbEvent := event.Event{ - Name: eventItem.key, - Namespace: eventItem.namespace, - Kind: eventItem.resourceType, - Reason: "Deleted", - } - c.eventHandler.Handle(kbEvent) - return nil + kbEvent := event.Event{ + Name: objectMeta.Name, + Namespace: eventItem.namespace, + EventType: eventItem.eventType, + Obj: obj, } + c.eventHandler.Handle(kbEvent) return nil } diff --git a/pkg/controller/controllerbuilder.go b/pkg/controller/controllerbuilder.go index b8b7a7e..cd0fc77 100644 --- a/pkg/controller/controllerbuilder.go +++ b/pkg/controller/controllerbuilder.go @@ -17,6 +17,7 @@ limitations under the License. package controller import ( + "github.com/CentaurusInfra/quarkcm/pkg/constants" "github.com/CentaurusInfra/quarkcm/pkg/handlers" "github.com/CentaurusInfra/quarkcm/pkg/utils" api_v1 "k8s.io/api/core/v1" @@ -45,7 +46,7 @@ func NewPodController(client kubernetes.Interface) *Controller { 0, cache.Indexers{}, ) - return newResourceController(client, eventHandler, informer, "pod") + return newResourceController(client, eventHandler, informer, constants.ResourceType_Pod) } func NewNodeController(client kubernetes.Interface) *Controller { @@ -63,7 +64,7 @@ func NewNodeController(client kubernetes.Interface) *Controller { 0, cache.Indexers{}, ) - return newResourceController(client, eventHandler, informer, "node") + return newResourceController(client, eventHandler, informer, constants.ResourceType_Node) } func newResourceController(client kubernetes.Interface, eventHandler handlers.Handler, informer cache.SharedIndexInformer, resourceType string) *Controller { @@ -73,8 +74,7 @@ func newResourceController(client kubernetes.Interface, eventHandler handlers.Ha informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { eventItem.key, err = cache.MetaNamespaceKeyFunc(obj) - eventItem.eventType = "create" - eventItem.resourceType = resourceType + eventItem.eventType = constants.EventType_Set klog.Infof("Processing add to %v: %s", resourceType, eventItem.key) if err == nil { queue.Add(eventItem) @@ -82,8 +82,7 @@ func newResourceController(client kubernetes.Interface, eventHandler handlers.Ha }, UpdateFunc: func(old, new interface{}) { eventItem.key, err = cache.MetaNamespaceKeyFunc(old) - eventItem.eventType = "update" - eventItem.resourceType = resourceType + eventItem.eventType = constants.EventType_Set klog.Infof("Processing update to %v: %s", resourceType, eventItem.key) if err == nil { queue.Add(eventItem) @@ -91,8 +90,7 @@ func newResourceController(client kubernetes.Interface, eventHandler handlers.Ha }, DeleteFunc: func(obj interface{}) { eventItem.key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj) - eventItem.eventType = "delete" - eventItem.resourceType = resourceType + eventItem.eventType = constants.EventType_Delete eventItem.namespace = utils.GetObjectMetaData(obj).Namespace klog.Infof("Processing delete to %v: %s", resourceType, eventItem.key) if err == nil { diff --git a/pkg/event/event.go b/pkg/event/event.go index 3c5b842..2146c28 100644 --- a/pkg/event/event.go +++ b/pkg/event/event.go @@ -16,80 +16,10 @@ limitations under the License. package event -import ( - "fmt" - - "github.com/CentaurusInfra/quarkcm/pkg/utils" - api_v1 "k8s.io/api/core/v1" -) - // Event represent an event got from k8s api server type Event struct { Namespace string - Kind string - Component string - Host string - Reason string + EventType string Name string -} - -// New create new Event -func New(obj interface{}, action string) Event { - var namespace, kind, component, host, reason, name string - - objectMeta := utils.GetObjectMetaData(obj) - namespace = objectMeta.Namespace - name = objectMeta.Name - reason = action - - switch object := obj.(type) { - case *api_v1.Pod: - kind = "pod" - host = object.Spec.NodeName - case *api_v1.Node: - kind = "node" - case Event: - name = object.Name - kind = object.Kind - namespace = object.Namespace - } - - kbEvent := Event{ - Namespace: namespace, - Kind: kind, - Component: component, - Host: host, - Reason: reason, - Name: name, - } - return kbEvent -} - -// Message returns event message in standard format. -// included as a part of event packege to enhance code resuablity across handlers. -func (e *Event) Message() (msg string) { - // using switch over if..else, since the format could vary based on the kind of the object in future. - switch e.Kind { - case "pod": - msg = fmt.Sprintf( - "A pod `%s` has been `%s`", - e.Name, - e.Reason, - ) - case "node": - msg = fmt.Sprintf( - "A node `%s` has been `%s`", - e.Name, - e.Reason, - ) - default: - msg = fmt.Sprintf( - "A `%s` in namespace `%s` has been `%s`:\n`%s`", - e.Kind, - e.Namespace, - e.Reason, - e.Name, - ) - } - return msg + Obj interface{} } diff --git a/pkg/handlers/nodehandler.go b/pkg/handlers/nodehandler.go index 102077e..a9c2bef 100644 --- a/pkg/handlers/nodehandler.go +++ b/pkg/handlers/nodehandler.go @@ -17,6 +17,7 @@ limitations under the License. package handlers import ( + v1 "k8s.io/api/core/v1" "k8s.io/klog" "github.com/CentaurusInfra/quarkcm/pkg/event" @@ -31,5 +32,9 @@ func (d *NodeHandler) Init() error { // Handle handles an event. func (d *NodeHandler) Handle(e event.Event) { - klog.Infof("Handle node event %s", e) + d.handleInternal(e, e.Obj.(*v1.Node)) +} + +func (d *NodeHandler) handleInternal(e event.Event, node *v1.Node) { + klog.Infof("Handle node event %s", node.Name) } diff --git a/pkg/handlers/podhandler.go b/pkg/handlers/podhandler.go index b933943..e89fe44 100644 --- a/pkg/handlers/podhandler.go +++ b/pkg/handlers/podhandler.go @@ -17,6 +17,7 @@ limitations under the License. package handlers import ( + v1 "k8s.io/api/core/v1" "k8s.io/klog" "github.com/CentaurusInfra/quarkcm/pkg/event" @@ -29,7 +30,10 @@ func (d *PodHandler) Init() error { return nil } -// Handle handles an event. func (d *PodHandler) Handle(e event.Event) { - klog.Infof("Handle pod event %s", e) + d.handleInternal(e, e.Obj.(*v1.Pod)) +} + +func (d *PodHandler) handleInternal(e event.Event, pod *v1.Pod) { + klog.Infof("Handle pod event %s", pod.Name) } diff --git a/pkg/utils/k8sutil.go b/pkg/utils/k8sutil.go index 237f811..fc82b33 100644 --- a/pkg/utils/k8sutil.go +++ b/pkg/utils/k8sutil.go @@ -57,8 +57,6 @@ func GetObjectMetaData(obj interface{}) (objectMeta meta_v1.ObjectMeta) { objectMeta = object.ObjectMeta case *api_v1.Node: objectMeta = object.ObjectMeta - case *api_v1.Event: - objectMeta = object.ObjectMeta } return objectMeta } From 2ed8c7360e33841b5573e5e186f867577dbae0ed Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Mon, 4 Apr 2022 22:12:11 +0000 Subject: [PATCH 07/24] Add event Id for tracking --- go.mod | 3 +- go.sum | 1 + pkg/controller/controller.go | 40 +++++++------------- pkg/controller/controllerbuilder.go | 27 +++++++------ pkg/handlers/handler.go | 7 +--- pkg/handlers/nodehandler.go | 16 +++----- pkg/handlers/podhandler.go | 11 +++--- pkg/{event/event.go => objects/eventitem.go} | 10 ++--- pkg/utils/k8sutil.go | 14 ------- 9 files changed, 48 insertions(+), 81 deletions(-) rename pkg/{event/event.go => objects/eventitem.go} (85%) diff --git a/go.mod b/go.mod index 3fff1f5..1261add 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/golang/protobuf v1.4.2 // indirect github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 // indirect + github.com/google/uuid v1.1.1 github.com/googleapis/gnostic v0.1.0 // indirect github.com/hashicorp/hcl v0.0.0-20171017181929-23c074d0eceb // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect @@ -30,5 +31,5 @@ require ( k8s.io/api v0.16.8 k8s.io/apimachinery v0.16.8 k8s.io/client-go v0.16.8 - k8s.io/klog v1.0.0 // indirect + k8s.io/klog v1.0.0 ) diff --git a/go.sum b/go.sum index 9b03a38..57b38a0 100644 --- a/go.sum +++ b/go.sum @@ -66,6 +66,7 @@ github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 2013986..64e0035 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -24,8 +24,8 @@ import ( "syscall" "time" - "github.com/CentaurusInfra/quarkcm/pkg/event" "github.com/CentaurusInfra/quarkcm/pkg/handlers" + "github.com/CentaurusInfra/quarkcm/pkg/objects" "github.com/CentaurusInfra/quarkcm/pkg/utils" "k8s.io/klog" @@ -39,13 +39,6 @@ import ( const maxRetries = 5 -type EventItem struct { - key string - eventType string - namespace string -} - -// Controller object type Controller struct { resourceType string clientset kubernetes.Interface @@ -118,7 +111,7 @@ func (c *Controller) runWorker() { func (c *Controller) processNextItem() bool { queueItem, quit := c.queue.Get() - eventItem := queueItem.(EventItem) + eventItem := queueItem.(objects.EventItem) if quit { return false @@ -129,11 +122,11 @@ func (c *Controller) processNextItem() bool { // No error, reset the ratelimit counters c.queue.Forget(queueItem) } else if c.queue.NumRequeues(queueItem) < maxRetries { - klog.Errorf("error processing %s (will retry): %v", eventItem.key, err) + klog.Errorf("error processing %s (will retry): %v", eventItem.Key, err) c.queue.AddRateLimited(queueItem) } else { // err != nil and too many retries - klog.Errorf("error processing %s (giving up): %v", eventItem.key, err) + klog.Errorf("error processing %s (giving up): %v", eventItem.Key, err) c.queue.Forget(queueItem) utilruntime.HandleError(err) } @@ -141,27 +134,20 @@ func (c *Controller) processNextItem() bool { return true } -func (c *Controller) processItem(eventItem EventItem) error { - obj, _, err := c.informer.GetIndexer().GetByKey(eventItem.key) +func (c *Controller) processItem(eventItem objects.EventItem) error { + obj, _, err := c.informer.GetIndexer().GetByKey(eventItem.Key) if err != nil { - return fmt.Errorf("error fetching object with key %s from store: %v", eventItem.key, err) + return fmt.Errorf("error fetching object with key %s from store: %v", eventItem.Key, err) } - // get object's metedata - objectMeta := utils.GetObjectMetaData(obj) + eventItem.Obj = obj // namespace retrived from event key incase namespace value is empty - if eventItem.namespace == "" && strings.Contains(eventItem.key, "/") { - substring := strings.Split(eventItem.key, "/") - eventItem.namespace = substring[0] - eventItem.key = substring[1] + if eventItem.Namespace == "" && strings.Contains(eventItem.Key, "/") { + substring := strings.Split(eventItem.Key, "/") + eventItem.Namespace = substring[0] + eventItem.Key = substring[1] } - kbEvent := event.Event{ - Name: objectMeta.Name, - Namespace: eventItem.namespace, - EventType: eventItem.eventType, - Obj: obj, - } - c.eventHandler.Handle(kbEvent) + c.eventHandler.Handle(eventItem) return nil } diff --git a/pkg/controller/controllerbuilder.go b/pkg/controller/controllerbuilder.go index cd0fc77..d7957fc 100644 --- a/pkg/controller/controllerbuilder.go +++ b/pkg/controller/controllerbuilder.go @@ -19,7 +19,8 @@ package controller import ( "github.com/CentaurusInfra/quarkcm/pkg/constants" "github.com/CentaurusInfra/quarkcm/pkg/handlers" - "github.com/CentaurusInfra/quarkcm/pkg/utils" + "github.com/CentaurusInfra/quarkcm/pkg/objects" + "github.com/google/uuid" api_v1 "k8s.io/api/core/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -69,30 +70,32 @@ func NewNodeController(client kubernetes.Interface) *Controller { func newResourceController(client kubernetes.Interface, eventHandler handlers.Handler, informer cache.SharedIndexInformer, resourceType string) *Controller { queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) - var eventItem EventItem + var eventItem objects.EventItem var err error informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { - eventItem.key, err = cache.MetaNamespaceKeyFunc(obj) - eventItem.eventType = constants.EventType_Set - klog.Infof("Processing add to %v: %s", resourceType, eventItem.key) + eventItem.Key, err = cache.MetaNamespaceKeyFunc(obj) + eventItem.EventType = constants.EventType_Set + eventItem.Id = uuid.New().String() + klog.Infof("Processing add to %v: %s tracking: %s", resourceType, eventItem.Key, eventItem.Id) if err == nil { queue.Add(eventItem) } }, UpdateFunc: func(old, new interface{}) { - eventItem.key, err = cache.MetaNamespaceKeyFunc(old) - eventItem.eventType = constants.EventType_Set - klog.Infof("Processing update to %v: %s", resourceType, eventItem.key) + eventItem.Key, err = cache.MetaNamespaceKeyFunc(old) + eventItem.EventType = constants.EventType_Set + eventItem.Id = uuid.New().String() + klog.Infof("Processing update to %v: %s tracking: %s", resourceType, eventItem.Key, eventItem.Id) if err == nil { queue.Add(eventItem) } }, DeleteFunc: func(obj interface{}) { - eventItem.key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj) - eventItem.eventType = constants.EventType_Delete - eventItem.namespace = utils.GetObjectMetaData(obj).Namespace - klog.Infof("Processing delete to %v: %s", resourceType, eventItem.key) + eventItem.Key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj) + eventItem.EventType = constants.EventType_Delete + eventItem.Id = uuid.New().String() + klog.Infof("Processing delete to %v: %s tracking: %s", resourceType, eventItem.Key, eventItem.Id) if err == nil { queue.Add(eventItem) } diff --git a/pkg/handlers/handler.go b/pkg/handlers/handler.go index 7ba7a7b..c54f349 100644 --- a/pkg/handlers/handler.go +++ b/pkg/handlers/handler.go @@ -16,11 +16,8 @@ limitations under the License. package handlers -import ( - "github.com/CentaurusInfra/quarkcm/pkg/event" -) +import "github.com/CentaurusInfra/quarkcm/pkg/objects" type Handler interface { - Init() error - Handle(e event.Event) + Handle(eventItem objects.EventItem) } diff --git a/pkg/handlers/nodehandler.go b/pkg/handlers/nodehandler.go index a9c2bef..ecc6795 100644 --- a/pkg/handlers/nodehandler.go +++ b/pkg/handlers/nodehandler.go @@ -17,24 +17,18 @@ limitations under the License. package handlers import ( + "github.com/CentaurusInfra/quarkcm/pkg/objects" v1 "k8s.io/api/core/v1" "k8s.io/klog" - - "github.com/CentaurusInfra/quarkcm/pkg/event" ) type NodeHandler struct { } -func (d *NodeHandler) Init() error { - return nil -} - -// Handle handles an event. -func (d *NodeHandler) Handle(e event.Event) { - d.handleInternal(e, e.Obj.(*v1.Node)) +func (d *NodeHandler) Handle(eventItem objects.EventItem) { + klog.Infof("Handle node event %s:%s, tracking: %s", eventItem.Key, eventItem.EventType, eventItem.Id) + d.handleInternal(eventItem.EventType, eventItem.Obj.(*v1.Node)) } -func (d *NodeHandler) handleInternal(e event.Event, node *v1.Node) { - klog.Infof("Handle node event %s", node.Name) +func (d *NodeHandler) handleInternal(eventType string, node *v1.Node) { } diff --git a/pkg/handlers/podhandler.go b/pkg/handlers/podhandler.go index e89fe44..46c39d2 100644 --- a/pkg/handlers/podhandler.go +++ b/pkg/handlers/podhandler.go @@ -17,10 +17,9 @@ limitations under the License. package handlers import ( + "github.com/CentaurusInfra/quarkcm/pkg/objects" v1 "k8s.io/api/core/v1" "k8s.io/klog" - - "github.com/CentaurusInfra/quarkcm/pkg/event" ) type PodHandler struct { @@ -30,10 +29,10 @@ func (d *PodHandler) Init() error { return nil } -func (d *PodHandler) Handle(e event.Event) { - d.handleInternal(e, e.Obj.(*v1.Pod)) +func (d *PodHandler) Handle(eventItem objects.EventItem) { + klog.Infof("Handle pod event %s:%s, tracking: %s", eventItem.Key, eventItem.EventType, eventItem.Id) + d.handleInternal(eventItem.EventType, eventItem.Obj.(*v1.Pod)) } -func (d *PodHandler) handleInternal(e event.Event, pod *v1.Pod) { - klog.Infof("Handle pod event %s", pod.Name) +func (d *PodHandler) handleInternal(eventType string, pod *v1.Pod) { } diff --git a/pkg/event/event.go b/pkg/objects/eventitem.go similarity index 85% rename from pkg/event/event.go rename to pkg/objects/eventitem.go index 2146c28..3579eea 100644 --- a/pkg/event/event.go +++ b/pkg/objects/eventitem.go @@ -14,12 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -package event +package objects -// Event represent an event got from k8s api server -type Event struct { - Namespace string +type EventItem struct { + Id string + Key string EventType string - Name string + Namespace string Obj interface{} } diff --git a/pkg/utils/k8sutil.go b/pkg/utils/k8sutil.go index fc82b33..4de75c1 100644 --- a/pkg/utils/k8sutil.go +++ b/pkg/utils/k8sutil.go @@ -3,8 +3,6 @@ package utils import ( "os" - api_v1 "k8s.io/api/core/v1" - meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" @@ -48,15 +46,3 @@ func GetClientOutOfCluster() kubernetes.Interface { return clientset } - -// GetObjectMetaData returns metadata of a given k8s object -func GetObjectMetaData(obj interface{}) (objectMeta meta_v1.ObjectMeta) { - - switch object := obj.(type) { - case *api_v1.Pod: - objectMeta = object.ObjectMeta - case *api_v1.Node: - objectMeta = object.ObjectMeta - } - return objectMeta -} From f1e2062a5af6a986dab3fe6e73722aa36aa4ec5b Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Tue, 5 Apr 2022 18:38:02 +0000 Subject: [PATCH 08/24] Add more logs --- pkg/datastore/datastore.go | 123 ++++++++++++++++++++++++++++++++++++ pkg/handlers/nodehandler.go | 22 ++++++- pkg/handlers/podhandler.go | 20 +++++- pkg/objects/nodeobject.go | 25 ++++++++ pkg/objects/podobject.go | 24 +++++++ pkg/utils/k8sutil.go | 16 +++++ 6 files changed, 224 insertions(+), 6 deletions(-) create mode 100644 pkg/datastore/datastore.go create mode 100644 pkg/objects/nodeobject.go create mode 100644 pkg/objects/podobject.go diff --git a/pkg/datastore/datastore.go b/pkg/datastore/datastore.go new file mode 100644 index 0000000..d602b78 --- /dev/null +++ b/pkg/datastore/datastore.go @@ -0,0 +1,123 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package datastore + +import ( + "encoding/json" + "sync" + + "github.com/CentaurusInfra/quarkcm/pkg/objects" + "k8s.io/klog" +) + +type DataStore struct { + NodeMap map[string]*objects.NodeObject // map[node name] => node object + PodMap map[string]*objects.PodObject // map[key] => pod object +} + +var lock = &sync.Mutex{} +var dataStore *DataStore + +func Instance() *DataStore { + if dataStore == nil { + lock.Lock() + defer lock.Unlock() + if dataStore == nil { + dataStore = &DataStore{ + NodeMap: map[string]*objects.NodeObject{}, + PodMap: map[string]*objects.PodObject{}, + } + } + } + return dataStore +} + +func SetNode(key string, nodeHostname string, nodeIP string, creationTimestamp string, resourceVersion string, trackingId string) { + nodeMap := Instance().NodeMap + node, exists := nodeMap[key] + changed := false + if exists { + if node.Hostname != nodeHostname || node.IP != nodeIP { + node.Hostname = nodeHostname + node.IP = nodeIP + node.CreationTimestamp = creationTimestamp + node.ResourceVersion = resourceVersion + changed = true + } else { + klog.Infof("Handling node completed. Node %s is unchanged. Tracking Id: %s", key, trackingId) + } + } else { + nodeMap[key] = &objects.NodeObject{ + Name: key, + Hostname: nodeHostname, + IP: nodeIP, + CreationTimestamp: creationTimestamp, + ResourceVersion: resourceVersion, + } + changed = true + } + if changed { + nodeStr, _ := json.Marshal(nodeMap[key]) + klog.Infof("Handling node completed. Node set as %s. Tracking Id: %s", nodeStr, trackingId) + } +} + +func DeleteNode(key string, trackingId string) { + nodeMap := Instance().NodeMap + _, exists := nodeMap[key] + if exists { + delete(nodeMap, key) + klog.Infof("Handling node completed. Node %s is deleted. Tracking Id: %s", key, trackingId) + } +} + +func SetPod(key string, podIP string, nodeName string, resourceVersion string, trackingId string) { + podMap := Instance().PodMap + pod, exists := podMap[key] + changed := false + if exists { + if pod.IP != podIP || pod.NodeName != nodeName { + pod.IP = podIP + pod.NodeName = nodeName + pod.ResourceVersion = resourceVersion + changed = true + } else { + klog.Infof("Handling pod completed. Pod %s is unchanged. Tracking Id: %s", key, trackingId) + } + } else { + podMap[key] = &objects.PodObject{ + Key: key, + IP: podIP, + NodeName: nodeName, + ResourceVersion: resourceVersion, + } + changed = true + } + if changed { + podStr, _ := json.Marshal(podMap[key]) + klog.Infof("Handling pod completed. Pod set as %s. Tracking Id: %s", podStr, trackingId) + } +} + +func DeletePod(key string, trackingId string) { + podMap := Instance().PodMap + _, exists := podMap[key] + if exists { + delete(podMap, key) + klog.Infof("Handling pod completed. Pod %s is deleted. Tracking Id: %s", key, trackingId) + } +} diff --git a/pkg/handlers/nodehandler.go b/pkg/handlers/nodehandler.go index ecc6795..a9a86d0 100644 --- a/pkg/handlers/nodehandler.go +++ b/pkg/handlers/nodehandler.go @@ -17,6 +17,8 @@ limitations under the License. package handlers import ( + "github.com/CentaurusInfra/quarkcm/pkg/constants" + "github.com/CentaurusInfra/quarkcm/pkg/datastore" "github.com/CentaurusInfra/quarkcm/pkg/objects" v1 "k8s.io/api/core/v1" "k8s.io/klog" @@ -26,9 +28,23 @@ type NodeHandler struct { } func (d *NodeHandler) Handle(eventItem objects.EventItem) { - klog.Infof("Handle node event %s:%s, tracking: %s", eventItem.Key, eventItem.EventType, eventItem.Id) - d.handleInternal(eventItem.EventType, eventItem.Obj.(*v1.Node)) + klog.Infof("Handle node event %s:%s. Tracking Id: %s", eventItem.Key, eventItem.EventType, eventItem.Id) + if eventItem.EventType == constants.EventType_Delete { + datastore.DeleteNode(eventItem.Key, eventItem.Id) + } else { + handleNodeSet(eventItem, eventItem.Obj.(*v1.Node)) + } } -func (d *NodeHandler) handleInternal(eventType string, node *v1.Node) { +func handleNodeSet(eventItem objects.EventItem, node *v1.Node) { + var hostname string + var nodeIP string + for _, item := range node.Status.Addresses { + if item.Type == "InternalIP" { + nodeIP = item.Address + } else if item.Type == "Hostname" { + hostname = item.Address + } + } + datastore.SetNode(eventItem.Key, hostname, nodeIP, node.ObjectMeta.CreationTimestamp.String(), node.ObjectMeta.ResourceVersion, eventItem.Id) } diff --git a/pkg/handlers/podhandler.go b/pkg/handlers/podhandler.go index 46c39d2..11b4ca9 100644 --- a/pkg/handlers/podhandler.go +++ b/pkg/handlers/podhandler.go @@ -17,6 +17,10 @@ limitations under the License. package handlers import ( + "fmt" + + "github.com/CentaurusInfra/quarkcm/pkg/constants" + "github.com/CentaurusInfra/quarkcm/pkg/datastore" "github.com/CentaurusInfra/quarkcm/pkg/objects" v1 "k8s.io/api/core/v1" "k8s.io/klog" @@ -30,9 +34,19 @@ func (d *PodHandler) Init() error { } func (d *PodHandler) Handle(eventItem objects.EventItem) { - klog.Infof("Handle pod event %s:%s, tracking: %s", eventItem.Key, eventItem.EventType, eventItem.Id) - d.handleInternal(eventItem.EventType, eventItem.Obj.(*v1.Pod)) + klog.Infof("Handle pod event %s:%s. Tracking Id: %s", eventItem.Key, eventItem.EventType, eventItem.Id) + podKey := fmt.Sprintf("%s/%s", eventItem.Namespace, eventItem.Key) + if eventItem.EventType == constants.EventType_Delete { + datastore.DeletePod(podKey, eventItem.Id) + } else { + handlePodSet(eventItem, podKey, eventItem.Obj.(*v1.Pod)) + } } -func (d *PodHandler) handleInternal(eventType string, pod *v1.Pod) { +func handlePodSet(eventItem objects.EventItem, key string, pod *v1.Pod) { + if len(pod.Spec.NodeName) == 0 || len(pod.Status.PodIP) == 0 { + klog.Infof("Handling pod completed. Pod %s is not ready. Tracking Id: %s", eventItem.Key, eventItem.Id) + return + } + datastore.SetPod(key, pod.Status.PodIP, pod.Spec.NodeName, pod.ObjectMeta.ResourceVersion, eventItem.Id) } diff --git a/pkg/objects/nodeobject.go b/pkg/objects/nodeobject.go new file mode 100644 index 0000000..e46443e --- /dev/null +++ b/pkg/objects/nodeobject.go @@ -0,0 +1,25 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package objects + +type NodeObject struct { + Name string + Hostname string + IP string + CreationTimestamp string + ResourceVersion string +} diff --git a/pkg/objects/podobject.go b/pkg/objects/podobject.go new file mode 100644 index 0000000..59e8af3 --- /dev/null +++ b/pkg/objects/podobject.go @@ -0,0 +1,24 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package objects + +type PodObject struct { + Key string + IP string + NodeName string + ResourceVersion string +} diff --git a/pkg/utils/k8sutil.go b/pkg/utils/k8sutil.go index 4de75c1..a513b3c 100644 --- a/pkg/utils/k8sutil.go +++ b/pkg/utils/k8sutil.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package utils import ( From 8e893368519d27f67b8c945c75be5679adf2b86d Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Tue, 5 Apr 2022 18:51:56 +0000 Subject: [PATCH 09/24] Small refine --- .vscode/launch.json | 2 +- pkg/controller/controller.go | 7 +++---- pkg/controller/controllerbuilder.go | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 6deb9a6..d428a1f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,4 +12,4 @@ "program": "main.go" } ] -} \ No newline at end of file +} diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 64e0035..1364a05 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -47,7 +47,6 @@ type Controller struct { eventHandler handlers.Handler } -// Start prepares watchers and run their controllers, then waits for process termination signals func Start() { var kubeClient kubernetes.Interface @@ -122,11 +121,11 @@ func (c *Controller) processNextItem() bool { // No error, reset the ratelimit counters c.queue.Forget(queueItem) } else if c.queue.NumRequeues(queueItem) < maxRetries { - klog.Errorf("error processing %s (will retry): %v", eventItem.Key, err) + klog.Errorf("error processing %s (will retry): %v. Tracking Id: %s", eventItem.Key, err, eventItem.Id) c.queue.AddRateLimited(queueItem) } else { // err != nil and too many retries - klog.Errorf("error processing %s (giving up): %v", eventItem.Key, err) + klog.Errorf("error processing %s (giving up): %v. Tracking Id: %s", eventItem.Key, err, eventItem.Id) c.queue.Forget(queueItem) utilruntime.HandleError(err) } @@ -137,7 +136,7 @@ func (c *Controller) processNextItem() bool { func (c *Controller) processItem(eventItem objects.EventItem) error { obj, _, err := c.informer.GetIndexer().GetByKey(eventItem.Key) if err != nil { - return fmt.Errorf("error fetching object with key %s from store: %v", eventItem.Key, err) + return fmt.Errorf("error fetching object with key %s from store: %v. Tracking Id: %s", eventItem.Key, err, eventItem.Id) } eventItem.Obj = obj diff --git a/pkg/controller/controllerbuilder.go b/pkg/controller/controllerbuilder.go index d7957fc..042d9a8 100644 --- a/pkg/controller/controllerbuilder.go +++ b/pkg/controller/controllerbuilder.go @@ -77,7 +77,7 @@ func newResourceController(client kubernetes.Interface, eventHandler handlers.Ha eventItem.Key, err = cache.MetaNamespaceKeyFunc(obj) eventItem.EventType = constants.EventType_Set eventItem.Id = uuid.New().String() - klog.Infof("Processing add to %v: %s tracking: %s", resourceType, eventItem.Key, eventItem.Id) + klog.Infof("Processing add to %v: %s. Tracking Id: %s", resourceType, eventItem.Key, eventItem.Id) if err == nil { queue.Add(eventItem) } @@ -86,7 +86,7 @@ func newResourceController(client kubernetes.Interface, eventHandler handlers.Ha eventItem.Key, err = cache.MetaNamespaceKeyFunc(old) eventItem.EventType = constants.EventType_Set eventItem.Id = uuid.New().String() - klog.Infof("Processing update to %v: %s tracking: %s", resourceType, eventItem.Key, eventItem.Id) + klog.Infof("Processing update to %v: %s. Tracking Id: %s", resourceType, eventItem.Key, eventItem.Id) if err == nil { queue.Add(eventItem) } @@ -95,7 +95,7 @@ func newResourceController(client kubernetes.Interface, eventHandler handlers.Ha eventItem.Key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj) eventItem.EventType = constants.EventType_Delete eventItem.Id = uuid.New().String() - klog.Infof("Processing delete to %v: %s tracking: %s", resourceType, eventItem.Key, eventItem.Id) + klog.Infof("Processing delete to %v: %s. Tracking Id: %s", resourceType, eventItem.Key, eventItem.Id) if err == nil { queue.Add(eventItem) } From 538e4aa56667ded5476a474f9317da7993b0c40f Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Mon, 11 Apr 2022 17:36:47 +0000 Subject: [PATCH 10/24] Add ResourceVersion to DataStore --- pkg/datastore/datastore.go | 30 ++++++++++++++++++++---------- pkg/handlers/nodehandler.go | 2 +- pkg/handlers/podhandler.go | 2 +- pkg/objects/nodeobject.go | 2 +- pkg/objects/podobject.go | 2 +- 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/pkg/datastore/datastore.go b/pkg/datastore/datastore.go index d602b78..cb2c695 100644 --- a/pkg/datastore/datastore.go +++ b/pkg/datastore/datastore.go @@ -25,8 +25,9 @@ import ( ) type DataStore struct { - NodeMap map[string]*objects.NodeObject // map[node name] => node object - PodMap map[string]*objects.PodObject // map[key] => pod object + ResourceVersion int + NodeMap map[string]*objects.NodeObject // map[node name] => node object + PodMap map[string]*objects.PodObject // map[key] => pod object } var lock = &sync.Mutex{} @@ -38,15 +39,24 @@ func Instance() *DataStore { defer lock.Unlock() if dataStore == nil { dataStore = &DataStore{ - NodeMap: map[string]*objects.NodeObject{}, - PodMap: map[string]*objects.PodObject{}, + ResourceVersion: 0, + NodeMap: map[string]*objects.NodeObject{}, + PodMap: map[string]*objects.PodObject{}, } } } return dataStore } -func SetNode(key string, nodeHostname string, nodeIP string, creationTimestamp string, resourceVersion string, trackingId string) { +func getNextResourceVersion() int { + instance := Instance() + lock.Lock() + defer lock.Unlock() + instance.ResourceVersion += 1 + return instance.ResourceVersion +} + +func SetNode(key string, nodeHostname string, nodeIP string, creationTimestamp string, trackingId string) { nodeMap := Instance().NodeMap node, exists := nodeMap[key] changed := false @@ -55,7 +65,7 @@ func SetNode(key string, nodeHostname string, nodeIP string, creationTimestamp s node.Hostname = nodeHostname node.IP = nodeIP node.CreationTimestamp = creationTimestamp - node.ResourceVersion = resourceVersion + node.ResourceVersion = getNextResourceVersion() changed = true } else { klog.Infof("Handling node completed. Node %s is unchanged. Tracking Id: %s", key, trackingId) @@ -66,7 +76,7 @@ func SetNode(key string, nodeHostname string, nodeIP string, creationTimestamp s Hostname: nodeHostname, IP: nodeIP, CreationTimestamp: creationTimestamp, - ResourceVersion: resourceVersion, + ResourceVersion: getNextResourceVersion(), } changed = true } @@ -85,7 +95,7 @@ func DeleteNode(key string, trackingId string) { } } -func SetPod(key string, podIP string, nodeName string, resourceVersion string, trackingId string) { +func SetPod(key string, podIP string, nodeName string, trackingId string) { podMap := Instance().PodMap pod, exists := podMap[key] changed := false @@ -93,7 +103,7 @@ func SetPod(key string, podIP string, nodeName string, resourceVersion string, t if pod.IP != podIP || pod.NodeName != nodeName { pod.IP = podIP pod.NodeName = nodeName - pod.ResourceVersion = resourceVersion + pod.ResourceVersion = getNextResourceVersion() changed = true } else { klog.Infof("Handling pod completed. Pod %s is unchanged. Tracking Id: %s", key, trackingId) @@ -103,7 +113,7 @@ func SetPod(key string, podIP string, nodeName string, resourceVersion string, t Key: key, IP: podIP, NodeName: nodeName, - ResourceVersion: resourceVersion, + ResourceVersion: getNextResourceVersion(), } changed = true } diff --git a/pkg/handlers/nodehandler.go b/pkg/handlers/nodehandler.go index a9a86d0..3c49f20 100644 --- a/pkg/handlers/nodehandler.go +++ b/pkg/handlers/nodehandler.go @@ -46,5 +46,5 @@ func handleNodeSet(eventItem objects.EventItem, node *v1.Node) { hostname = item.Address } } - datastore.SetNode(eventItem.Key, hostname, nodeIP, node.ObjectMeta.CreationTimestamp.String(), node.ObjectMeta.ResourceVersion, eventItem.Id) + datastore.SetNode(eventItem.Key, hostname, nodeIP, node.ObjectMeta.CreationTimestamp.Time.String(), eventItem.Id) } diff --git a/pkg/handlers/podhandler.go b/pkg/handlers/podhandler.go index 11b4ca9..1532be8 100644 --- a/pkg/handlers/podhandler.go +++ b/pkg/handlers/podhandler.go @@ -48,5 +48,5 @@ func handlePodSet(eventItem objects.EventItem, key string, pod *v1.Pod) { klog.Infof("Handling pod completed. Pod %s is not ready. Tracking Id: %s", eventItem.Key, eventItem.Id) return } - datastore.SetPod(key, pod.Status.PodIP, pod.Spec.NodeName, pod.ObjectMeta.ResourceVersion, eventItem.Id) + datastore.SetPod(key, pod.Status.PodIP, pod.Spec.NodeName, eventItem.Id) } diff --git a/pkg/objects/nodeobject.go b/pkg/objects/nodeobject.go index e46443e..b90e42a 100644 --- a/pkg/objects/nodeobject.go +++ b/pkg/objects/nodeobject.go @@ -21,5 +21,5 @@ type NodeObject struct { Hostname string IP string CreationTimestamp string - ResourceVersion string + ResourceVersion int } diff --git a/pkg/objects/podobject.go b/pkg/objects/podobject.go index 59e8af3..c69a904 100644 --- a/pkg/objects/podobject.go +++ b/pkg/objects/podobject.go @@ -20,5 +20,5 @@ type PodObject struct { Key string IP string NodeName string - ResourceVersion string + ResourceVersion int } From a23483c4d6edfc211136f19c242ad15971e42a57 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Tue, 12 Apr 2022 03:44:22 +0000 Subject: [PATCH 11/24] Add grpc server --- Makefile | 5 +- go.mod | 12 +- go.sum | 84 ++++++++++++ pkg/client/run.go | 2 + pkg/grpc/quarkcmsvc.go | 57 ++++++++ pkg/grpc/quarkcmsvc.pb.go | 230 +++++++++++++++++++++++++++++++++ pkg/grpc/quarkcmsvc.proto | 33 +++++ pkg/grpc/quarkcmsvc_grpc.pb.go | 107 +++++++++++++++ 8 files changed, 524 insertions(+), 6 deletions(-) create mode 100644 pkg/grpc/quarkcmsvc.go create mode 100644 pkg/grpc/quarkcmsvc.pb.go create mode 100644 pkg/grpc/quarkcmsvc.proto create mode 100644 pkg/grpc/quarkcmsvc_grpc.pb.go diff --git a/Makefile b/Makefile index 3d5d8c5..0750ca7 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ LDFLAGS := "-X '$(PKG)/cmd.buildDate=$(BUILD_DATE)'" default: build test -build: +build: proto "$(GOCMD)" build ${GOFLAGS} -ldflags ${LDFLAGS} -o "${BINARY}" docker-image: @@ -30,3 +30,6 @@ clean-images: stop clean: "$(GOCMD)" clean -i + +proto: + protoc --go_out=. --go-grpc_out=. pkg/grpc/quarkcmsvc.proto diff --git a/go.mod b/go.mod index 1261add..89aecd1 100644 --- a/go.mod +++ b/go.mod @@ -6,9 +6,9 @@ require ( github.com/fatih/structtag v1.2.0 github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect - github.com/golang/protobuf v1.4.2 // indirect + github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 // indirect - github.com/google/uuid v1.1.1 + github.com/google/uuid v1.1.2 github.com/googleapis/gnostic v0.1.0 // indirect github.com/hashicorp/hcl v0.0.0-20171017181929-23c074d0eceb // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect @@ -22,9 +22,11 @@ require ( github.com/spf13/cobra v0.0.1 github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec // indirect github.com/spf13/viper v1.0.0 - github.com/stretchr/testify v1.6.1 // indirect - golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 // indirect - golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 // indirect + golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3 // indirect + golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f // indirect + google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac // indirect + google.golang.org/grpc v1.45.0 + google.golang.org/protobuf v1.28.0 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect gopkg.in/yaml.v2 v2.3.0 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c diff --git a/go.sum b/go.sum index 57b38a0..55e1016 100644 --- a/go.sum +++ b/go.sum @@ -12,7 +12,16 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -21,6 +30,12 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= @@ -28,6 +43,7 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= @@ -46,19 +62,29 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 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 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= 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.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 h1:zLTLjkaOFEFIOxY5BWLFLwh+cL8vOBW4XJ2aqLE/Tf0= github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= @@ -68,6 +94,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI= @@ -76,6 +104,7 @@ github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEo github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -127,6 +156,8 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/segmentio/textio v1.2.0 h1:Ug4IkV3kh72juJbG8azoSBlgebIbUUxVNrfFcKHfTSQ= github.com/segmentio/textio v1.2.0/go.mod h1:+Rb7v0YVODP+tK5F7FD9TCkV7gOYx9IgLHWiqtvY8ag= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= @@ -146,18 +177,25 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 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.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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= @@ -169,14 +207,21 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3 h1:EN5+DfgmRMvRUrMGERW2gQl3Vc+Z7ZMnI/xdEpPSf0c= +golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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= @@ -190,11 +235,24 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f h1:8w7RhxzTVgUzw/AH/9mUV5q0vMgy40SQRursCcfmkCw= +golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -203,8 +261,11 @@ golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -212,15 +273,36 @@ google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7 h1:ZUjXAXmrAyrmmCPHgCA/vChHcpsX27MZ3yBonD/z1KE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac h1:qSNTkEN+L2mvWcLgJOR+8bdHX9rN/IdU3A1Ghpfb1Rg= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -230,6 +312,7 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/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 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -237,6 +320,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.16.8 h1:T72itM0CUT8KHqPAqbjTeSY0n24RyVM71nLiMlq/cAw= k8s.io/api v0.16.8/go.mod h1:a8EOdYHO8en+YHhPBLiW5q+3RfHTr7wxTqqp7emJ7PM= k8s.io/apimachinery v0.16.8 h1:wgFRqtel3w3rcclpba+iBkVlKeBlh42OzNp7FalXVCg= diff --git a/pkg/client/run.go b/pkg/client/run.go index 36af9ef..1f0b5ff 100644 --- a/pkg/client/run.go +++ b/pkg/client/run.go @@ -18,9 +18,11 @@ package client import ( "github.com/CentaurusInfra/quarkcm/pkg/controller" + "github.com/CentaurusInfra/quarkcm/pkg/grpc" ) // Run runs the event loop processing with given handler func Run() { + grpc.StartServer() controller.Start() } diff --git a/pkg/grpc/quarkcmsvc.go b/pkg/grpc/quarkcmsvc.go new file mode 100644 index 0000000..ca15bab --- /dev/null +++ b/pkg/grpc/quarkcmsvc.go @@ -0,0 +1,57 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package grpc + +import ( + context "context" + "encoding/json" + "flag" + "fmt" + "net" + "os" + + "google.golang.org/grpc" + "k8s.io/klog" +) + +var ( + port = flag.Int("port", 51051, "The server port") +) + +type server struct { + UnimplementedQuarkCMServiceServer +} + +func StartServer() { + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) + if err != nil { + klog.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + RegisterQuarkCMServiceServer(s, &server{}) + klog.Infof("grpc server listening at %v", lis.Addr()) + go s.Serve(lis) +} + +// To quickly test this function, execute: +// grpcurl -plaintext -import-path pkg/grpc/ -proto quarkcmsvc.proto -d '{"client_name": "a client name"}' [::]:51051 quarkcmsvc.QuarkCMService/TestPing +func (s *server) TestPing(ctx context.Context, in *TestRequestMessage) (*TestResponseMessage, error) { + inStr, _ := json.Marshal(in) + klog.Infof("grpc Service called TestPing %s", inStr) + hostname, _ := os.Hostname() + return &TestResponseMessage{ServerName: hostname}, nil +} diff --git a/pkg/grpc/quarkcmsvc.pb.go b/pkg/grpc/quarkcmsvc.pb.go new file mode 100644 index 0000000..75ff89c --- /dev/null +++ b/pkg/grpc/quarkcmsvc.pb.go @@ -0,0 +1,230 @@ +// +//Copyright 2022 quarkcm Authors. +// +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.0 +// protoc v3.15.8 +// source: pkg/grpc/quarkcmsvc.proto + +package grpc + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type TestRequestMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClientName string `protobuf:"bytes,1,opt,name=client_name,json=clientName,proto3" json:"client_name,omitempty"` +} + +func (x *TestRequestMessage) Reset() { + *x = TestRequestMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TestRequestMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TestRequestMessage) ProtoMessage() {} + +func (x *TestRequestMessage) ProtoReflect() protoreflect.Message { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TestRequestMessage.ProtoReflect.Descriptor instead. +func (*TestRequestMessage) Descriptor() ([]byte, []int) { + return file_pkg_grpc_quarkcmsvc_proto_rawDescGZIP(), []int{0} +} + +func (x *TestRequestMessage) GetClientName() string { + if x != nil { + return x.ClientName + } + return "" +} + +type TestResponseMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServerName string `protobuf:"bytes,1,opt,name=server_name,json=serverName,proto3" json:"server_name,omitempty"` +} + +func (x *TestResponseMessage) Reset() { + *x = TestResponseMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TestResponseMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TestResponseMessage) ProtoMessage() {} + +func (x *TestResponseMessage) ProtoReflect() protoreflect.Message { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TestResponseMessage.ProtoReflect.Descriptor instead. +func (*TestResponseMessage) Descriptor() ([]byte, []int) { + return file_pkg_grpc_quarkcmsvc_proto_rawDescGZIP(), []int{1} +} + +func (x *TestResponseMessage) GetServerName() string { + if x != nil { + return x.ServerName + } + return "" +} + +var File_pkg_grpc_quarkcmsvc_proto protoreflect.FileDescriptor + +var file_pkg_grpc_quarkcmsvc_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x71, 0x75, 0x61, 0x72, 0x6b, + 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x71, 0x75, 0x61, + 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x22, 0x35, 0x0a, 0x12, 0x54, 0x65, 0x73, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, + 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x36, + 0x0a, 0x13, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x32, 0x5f, 0x0a, 0x0e, 0x51, 0x75, 0x61, 0x72, 0x6b, 0x43, + 0x4d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x08, 0x54, 0x65, 0x73, 0x74, + 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, + 0x63, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1f, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, + 0x63, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x70, 0x6b, 0x67, 0x2f, 0x67, + 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pkg_grpc_quarkcmsvc_proto_rawDescOnce sync.Once + file_pkg_grpc_quarkcmsvc_proto_rawDescData = file_pkg_grpc_quarkcmsvc_proto_rawDesc +) + +func file_pkg_grpc_quarkcmsvc_proto_rawDescGZIP() []byte { + file_pkg_grpc_quarkcmsvc_proto_rawDescOnce.Do(func() { + file_pkg_grpc_quarkcmsvc_proto_rawDescData = protoimpl.X.CompressGZIP(file_pkg_grpc_quarkcmsvc_proto_rawDescData) + }) + return file_pkg_grpc_quarkcmsvc_proto_rawDescData +} + +var file_pkg_grpc_quarkcmsvc_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_pkg_grpc_quarkcmsvc_proto_goTypes = []interface{}{ + (*TestRequestMessage)(nil), // 0: quarkcmsvc.TestRequestMessage + (*TestResponseMessage)(nil), // 1: quarkcmsvc.TestResponseMessage +} +var file_pkg_grpc_quarkcmsvc_proto_depIdxs = []int32{ + 0, // 0: quarkcmsvc.QuarkCMService.TestPing:input_type -> quarkcmsvc.TestRequestMessage + 1, // 1: quarkcmsvc.QuarkCMService.TestPing:output_type -> quarkcmsvc.TestResponseMessage + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_pkg_grpc_quarkcmsvc_proto_init() } +func file_pkg_grpc_quarkcmsvc_proto_init() { + if File_pkg_grpc_quarkcmsvc_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_pkg_grpc_quarkcmsvc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TestRequestMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_grpc_quarkcmsvc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TestResponseMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pkg_grpc_quarkcmsvc_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_pkg_grpc_quarkcmsvc_proto_goTypes, + DependencyIndexes: file_pkg_grpc_quarkcmsvc_proto_depIdxs, + MessageInfos: file_pkg_grpc_quarkcmsvc_proto_msgTypes, + }.Build() + File_pkg_grpc_quarkcmsvc_proto = out.File + file_pkg_grpc_quarkcmsvc_proto_rawDesc = nil + file_pkg_grpc_quarkcmsvc_proto_goTypes = nil + file_pkg_grpc_quarkcmsvc_proto_depIdxs = nil +} diff --git a/pkg/grpc/quarkcmsvc.proto b/pkg/grpc/quarkcmsvc.proto new file mode 100644 index 0000000..e1f4f99 --- /dev/null +++ b/pkg/grpc/quarkcmsvc.proto @@ -0,0 +1,33 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +syntax = "proto3"; +package quarkcmsvc; + +option go_package = "pkg/grpc"; + +service QuarkCMService { + // Test + rpc TestPing (TestRequestMessage) returns (TestResponseMessage) {} +} + +message TestRequestMessage { + string client_name = 1; +} + +message TestResponseMessage { + string server_name = 1; +} \ No newline at end of file diff --git a/pkg/grpc/quarkcmsvc_grpc.pb.go b/pkg/grpc/quarkcmsvc_grpc.pb.go new file mode 100644 index 0000000..d3a1b11 --- /dev/null +++ b/pkg/grpc/quarkcmsvc_grpc.pb.go @@ -0,0 +1,107 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.15.8 +// source: pkg/grpc/quarkcmsvc.proto + +package grpc + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// QuarkCMServiceClient is the client API for QuarkCMService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type QuarkCMServiceClient interface { + // Test + TestPing(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResponseMessage, error) +} + +type quarkCMServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewQuarkCMServiceClient(cc grpc.ClientConnInterface) QuarkCMServiceClient { + return &quarkCMServiceClient{cc} +} + +func (c *quarkCMServiceClient) TestPing(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResponseMessage, error) { + out := new(TestResponseMessage) + err := c.cc.Invoke(ctx, "/quarkcmsvc.QuarkCMService/TestPing", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QuarkCMServiceServer is the server API for QuarkCMService service. +// All implementations must embed UnimplementedQuarkCMServiceServer +// for forward compatibility +type QuarkCMServiceServer interface { + // Test + TestPing(context.Context, *TestRequestMessage) (*TestResponseMessage, error) + mustEmbedUnimplementedQuarkCMServiceServer() +} + +// UnimplementedQuarkCMServiceServer must be embedded to have forward compatible implementations. +type UnimplementedQuarkCMServiceServer struct { +} + +func (UnimplementedQuarkCMServiceServer) TestPing(context.Context, *TestRequestMessage) (*TestResponseMessage, error) { + return nil, status.Errorf(codes.Unimplemented, "method TestPing not implemented") +} +func (UnimplementedQuarkCMServiceServer) mustEmbedUnimplementedQuarkCMServiceServer() {} + +// UnsafeQuarkCMServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to QuarkCMServiceServer will +// result in compilation errors. +type UnsafeQuarkCMServiceServer interface { + mustEmbedUnimplementedQuarkCMServiceServer() +} + +func RegisterQuarkCMServiceServer(s grpc.ServiceRegistrar, srv QuarkCMServiceServer) { + s.RegisterService(&QuarkCMService_ServiceDesc, srv) +} + +func _QuarkCMService_TestPing_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TestRequestMessage) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QuarkCMServiceServer).TestPing(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/quarkcmsvc.QuarkCMService/TestPing", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QuarkCMServiceServer).TestPing(ctx, req.(*TestRequestMessage)) + } + return interceptor(ctx, in, info, handler) +} + +// QuarkCMService_ServiceDesc is the grpc.ServiceDesc for QuarkCMService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var QuarkCMService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "quarkcmsvc.QuarkCMService", + HandlerType: (*QuarkCMServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "TestPing", + Handler: _QuarkCMService_TestPing_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "pkg/grpc/quarkcmsvc.proto", +} From 143ac469ed2beb32ba6f0ee7c8bbbe7e935b4adb Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Tue, 12 Apr 2022 18:04:01 +0000 Subject: [PATCH 12/24] Init grpc client --- .gitignore | 1 + quarkcmclient/Cargo.lock | 993 ++++++++++++++++++++++++++++++++++++++ quarkcmclient/Cargo.toml | 15 + quarkcmclient/build.rs | 4 + quarkcmclient/src/main.rs | 24 + 5 files changed, 1037 insertions(+) create mode 100644 quarkcmclient/Cargo.lock create mode 100644 quarkcmclient/Cargo.toml create mode 100644 quarkcmclient/build.rs create mode 100644 quarkcmclient/src/main.rs diff --git a/.gitignore b/.gitignore index 318b509..3004d07 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ quarkcm +quarkcmclient/target/ diff --git a/quarkcmclient/Cargo.lock b/quarkcmclient/Cargo.lock new file mode 100644 index 0000000..949ee7a --- /dev/null +++ b/quarkcmclient/Cargo.lock @@ -0,0 +1,993 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" + +[[package]] +name = "async-stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" +dependencies = [ + "async-stream-impl", + "futures-core", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47594e438a243791dba58124b6669561f5baa14cb12046641d8008bf035e5a25" +dependencies = [ + "async-trait", + "axum-core", + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde", + "sync_wrapper", + "tokio", + "tower", + "tower-http", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a671c9ae99531afdd5d3ee8340b8da547779430689947144c140fc74a740244" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", +] + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cmake" +version = "0.1.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" +dependencies = [ + "cc", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "fastrand" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +dependencies = [ + "instant", +] + +[[package]] +name = "fixedbitset" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures-channel" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "futures-task" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" + +[[package]] +name = "futures-util" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "getrandom" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "h2" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" + +[[package]] +name = "httparse" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6330e8a36bd8c859f3fa6d9382911fbb7147ec39807f63b923933a247240b9ba" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "indexmap" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.123" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd" + +[[package]] +name = "log" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mio" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "wasi 0.11.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "ntapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" +dependencies = [ + "winapi", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "petgraph" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a13a2fa9d0b63e5f22328828741e523766fff0ee9e779316902290dff3f824f" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "pin-project" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "prettyplease" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b83ec2d0af5c5c556257ff52c9f98934e243b9fd39604bfb2a9b75ec2e97f18" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "prost" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd5316aa8f5c82add416dfbc25116b84b748a21153f512917e8143640a71bbd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "328f9f29b82409216decb172d81e936415d21245befa79cd34c3f29d87d1c50b" +dependencies = [ + "bytes", + "cfg-if", + "cmake", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prost", + "prost-types", + "regex", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df35198f0777b75e9ff669737c6da5136b59dba33cf5a010a6d1cc4d56defc6f" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926681c118ae6e512a3ccefd4abbe5521a14f4cc1e207356d4d00c0b7f2006fd" +dependencies = [ + "bytes", + "prost", +] + +[[package]] +name = "quarkcmclient" +version = "0.1.0" +dependencies = [ + "hostname", + "prost", + "tokio", + "tonic", + "tonic-build", +] + +[[package]] +name = "quote" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "serde" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" + +[[package]] +name = "slab" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" + +[[package]] +name = "socket2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "syn" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8" + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "tokio" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" +dependencies = [ + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-stream" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tonic" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30fb54bf1e446f44d870d260d99957e7d11fb9d0a0f5bd1a662ad1411cc103f9" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "prost-derive", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic-build" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d17087af5c80e5d5fc8ba9878e60258065a0a757e35efe7a05b7904bece1943" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn", +] + +[[package]] +name = "tower" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a89fd63ad6adf737582df5db40d286574513c69a11dac5214dc3b5603d6713e" +dependencies = [ + "futures-core", + "futures-util", + "indexmap", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aba3f3efabf7fb41fae8534fc20a817013dd1c12cb45441efb6c82e6556b4cd8" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" + +[[package]] +name = "tower-service" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" + +[[package]] +name = "tracing" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80b9fa4360528139bc96100c160b7ae879f5567f49f1782b0b02035b0358ebf3" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90442985ee2f57c9e1b548ee72ae842f4a9a20e3f417cc38dbc5dc684d9bb4ee" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "which" +version = "4.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +dependencies = [ + "either", + "lazy_static", + "libc", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/quarkcmclient/Cargo.toml b/quarkcmclient/Cargo.toml new file mode 100644 index 0000000..3c81624 --- /dev/null +++ b/quarkcmclient/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "quarkcmclient" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +hostname = "^0.3" +tonic = "0.7" +prost = "0.10" +tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } + +[build-dependencies] +tonic-build = "0.7" \ No newline at end of file diff --git a/quarkcmclient/build.rs b/quarkcmclient/build.rs new file mode 100644 index 0000000..ab44f90 --- /dev/null +++ b/quarkcmclient/build.rs @@ -0,0 +1,4 @@ +fn main() -> Result<(), Box> { + tonic_build::compile_protos("../pkg/grpc/quarkcmsvc.proto")?; + Ok(()) +} \ No newline at end of file diff --git a/quarkcmclient/src/main.rs b/quarkcmclient/src/main.rs new file mode 100644 index 0000000..b24428e --- /dev/null +++ b/quarkcmclient/src/main.rs @@ -0,0 +1,24 @@ +use quarkcmsvc::quark_cm_service_client::QuarkCmServiceClient; +use quarkcmsvc::TestRequestMessage; + +pub mod quarkcmsvc { + tonic::include_proto!("quarkcmsvc"); +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; + + let mut name=String::new(); + match hostname::get()?.into_string(){ + Ok(n)=>{name=n}, + _=>{} + }; + let request=tonic::Request::new(TestRequestMessage{ + client_name: name, + }); + let response = client.test_ping(request).await?; + + println!("{:?}", response); + Ok(()) +} \ No newline at end of file From e62f7e26b24527c39f832f991ad231840bc7bf2c Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Wed, 13 Apr 2022 18:44:49 +0000 Subject: [PATCH 13/24] Add list function --- .gitignore | 1 + pkg/datastore/datastore.go | 62 ++++-- pkg/grpc/quarkcmsvc.go | 42 ++++ pkg/grpc/quarkcmsvc.pb.go | 378 +++++++++++++++++++++++++++++++-- pkg/grpc/quarkcmsvc.proto | 27 +++ pkg/grpc/quarkcmsvc_grpc.pb.go | 73 +++++++ quarkcmclient/src/main.rs | 6 +- 7 files changed, 556 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index 3004d07..7d5a6e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ quarkcm quarkcmclient/target/ +__debug_bin diff --git a/pkg/datastore/datastore.go b/pkg/datastore/datastore.go index cb2c695..f106334 100644 --- a/pkg/datastore/datastore.go +++ b/pkg/datastore/datastore.go @@ -25,9 +25,10 @@ import ( ) type DataStore struct { - ResourceVersion int - NodeMap map[string]*objects.NodeObject // map[node name] => node object - PodMap map[string]*objects.PodObject // map[key] => pod object + NodeResourceVersion int + NodeMap map[string]*objects.NodeObject // map[node name] => node object + PodResourceVersion int + PodMap map[string]*objects.PodObject // map[key] => pod object } var lock = &sync.Mutex{} @@ -39,21 +40,30 @@ func Instance() *DataStore { defer lock.Unlock() if dataStore == nil { dataStore = &DataStore{ - ResourceVersion: 0, - NodeMap: map[string]*objects.NodeObject{}, - PodMap: map[string]*objects.PodObject{}, + NodeResourceVersion: 0, + NodeMap: map[string]*objects.NodeObject{}, + PodResourceVersion: 0, + PodMap: map[string]*objects.PodObject{}, } } } return dataStore } -func getNextResourceVersion() int { +func calculateNextNodeResourceVersion() int { instance := Instance() lock.Lock() defer lock.Unlock() - instance.ResourceVersion += 1 - return instance.ResourceVersion + instance.NodeResourceVersion += 1 + return instance.NodeResourceVersion +} + +func calculateNextPodResourceVersion() int { + instance := Instance() + lock.Lock() + defer lock.Unlock() + instance.PodResourceVersion += 1 + return instance.PodResourceVersion } func SetNode(key string, nodeHostname string, nodeIP string, creationTimestamp string, trackingId string) { @@ -65,7 +75,7 @@ func SetNode(key string, nodeHostname string, nodeIP string, creationTimestamp s node.Hostname = nodeHostname node.IP = nodeIP node.CreationTimestamp = creationTimestamp - node.ResourceVersion = getNextResourceVersion() + node.ResourceVersion = calculateNextNodeResourceVersion() changed = true } else { klog.Infof("Handling node completed. Node %s is unchanged. Tracking Id: %s", key, trackingId) @@ -76,7 +86,7 @@ func SetNode(key string, nodeHostname string, nodeIP string, creationTimestamp s Hostname: nodeHostname, IP: nodeIP, CreationTimestamp: creationTimestamp, - ResourceVersion: getNextResourceVersion(), + ResourceVersion: calculateNextNodeResourceVersion(), } changed = true } @@ -95,6 +105,19 @@ func DeleteNode(key string, trackingId string) { } } +func ListNode() []objects.NodeObject { + maxResourceVersion := Instance().NodeResourceVersion + nodeMap := Instance().NodeMap + + var nodes []objects.NodeObject + for _, node := range nodeMap { + if node.ResourceVersion <= maxResourceVersion { + nodes = append(nodes, *node) + } + } + return nodes +} + func SetPod(key string, podIP string, nodeName string, trackingId string) { podMap := Instance().PodMap pod, exists := podMap[key] @@ -103,7 +126,7 @@ func SetPod(key string, podIP string, nodeName string, trackingId string) { if pod.IP != podIP || pod.NodeName != nodeName { pod.IP = podIP pod.NodeName = nodeName - pod.ResourceVersion = getNextResourceVersion() + pod.ResourceVersion = calculateNextPodResourceVersion() changed = true } else { klog.Infof("Handling pod completed. Pod %s is unchanged. Tracking Id: %s", key, trackingId) @@ -113,7 +136,7 @@ func SetPod(key string, podIP string, nodeName string, trackingId string) { Key: key, IP: podIP, NodeName: nodeName, - ResourceVersion: getNextResourceVersion(), + ResourceVersion: calculateNextPodResourceVersion(), } changed = true } @@ -131,3 +154,16 @@ func DeletePod(key string, trackingId string) { klog.Infof("Handling pod completed. Pod %s is deleted. Tracking Id: %s", key, trackingId) } } + +func ListPod() []objects.PodObject { + maxResourceVersion := Instance().PodResourceVersion + podMap := Instance().PodMap + + var pods []objects.PodObject + for _, pod := range podMap { + if pod.ResourceVersion <= maxResourceVersion { + pods = append(pods, *pod) + } + } + return pods +} diff --git a/pkg/grpc/quarkcmsvc.go b/pkg/grpc/quarkcmsvc.go index ca15bab..2d352dc 100644 --- a/pkg/grpc/quarkcmsvc.go +++ b/pkg/grpc/quarkcmsvc.go @@ -25,7 +25,10 @@ import ( "os" "google.golang.org/grpc" + emptypb "google.golang.org/protobuf/types/known/emptypb" "k8s.io/klog" + + "github.com/CentaurusInfra/quarkcm/pkg/datastore" ) var ( @@ -55,3 +58,42 @@ func (s *server) TestPing(ctx context.Context, in *TestRequestMessage) (*TestRes hostname, _ := os.Hostname() return &TestResponseMessage{ServerName: hostname}, nil } + +func (s *server) ListNode(ctx context.Context, in *emptypb.Empty) (*NodeListMessage, error) { + klog.Info("grpc Service called ListNode") + + nodeObjects := datastore.ListNode() + length := len(nodeObjects) + nodeMessages := make([]*NodeMessage, 0, length) + for i := 0; i < length; i++ { + nodeObject := nodeObjects[i] + nodeMessages = append(nodeMessages, &NodeMessage{ + Name: nodeObject.Name, + Hostname: nodeObject.Hostname, + Ip: nodeObject.IP, + CreationTimestamp: nodeObject.CreationTimestamp, + ResourceVersion: int32(nodeObject.ResourceVersion), + }) + } + + return &NodeListMessage{Nodes: nodeMessages}, nil +} + +func (s *server) ListPod(ctx context.Context, in *emptypb.Empty) (*PodListMessage, error) { + klog.Info("grpc Service called ListPod") + + podObjects := datastore.ListPod() + length := len(podObjects) + podMessages := make([]*PodMessage, 0, length) + for i := 0; i < length; i++ { + podObject := podObjects[i] + podMessages = append(podMessages, &PodMessage{ + Key: podObject.Key, + Ip: podObject.IP, + NodeName: podObject.NodeName, + ResourceVersion: int32(podObject.ResourceVersion), + }) + } + + return &PodListMessage{Pods: podMessages}, nil +} diff --git a/pkg/grpc/quarkcmsvc.pb.go b/pkg/grpc/quarkcmsvc.pb.go index 75ff89c..3a6c77f 100644 --- a/pkg/grpc/quarkcmsvc.pb.go +++ b/pkg/grpc/quarkcmsvc.pb.go @@ -24,6 +24,7 @@ package grpc import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" reflect "reflect" sync "sync" ) @@ -129,26 +130,306 @@ func (x *TestResponseMessage) GetServerName() string { return "" } +type NodeMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` + Ip string `protobuf:"bytes,3,opt,name=ip,proto3" json:"ip,omitempty"` + CreationTimestamp string `protobuf:"bytes,4,opt,name=creation_timestamp,json=creationTimestamp,proto3" json:"creation_timestamp,omitempty"` + ResourceVersion int32 `protobuf:"varint,5,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` +} + +func (x *NodeMessage) Reset() { + *x = NodeMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NodeMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NodeMessage) ProtoMessage() {} + +func (x *NodeMessage) ProtoReflect() protoreflect.Message { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NodeMessage.ProtoReflect.Descriptor instead. +func (*NodeMessage) Descriptor() ([]byte, []int) { + return file_pkg_grpc_quarkcmsvc_proto_rawDescGZIP(), []int{2} +} + +func (x *NodeMessage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NodeMessage) GetHostname() string { + if x != nil { + return x.Hostname + } + return "" +} + +func (x *NodeMessage) GetIp() string { + if x != nil { + return x.Ip + } + return "" +} + +func (x *NodeMessage) GetCreationTimestamp() string { + if x != nil { + return x.CreationTimestamp + } + return "" +} + +func (x *NodeMessage) GetResourceVersion() int32 { + if x != nil { + return x.ResourceVersion + } + return 0 +} + +type NodeListMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nodes []*NodeMessage `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"` +} + +func (x *NodeListMessage) Reset() { + *x = NodeListMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NodeListMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NodeListMessage) ProtoMessage() {} + +func (x *NodeListMessage) ProtoReflect() protoreflect.Message { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NodeListMessage.ProtoReflect.Descriptor instead. +func (*NodeListMessage) Descriptor() ([]byte, []int) { + return file_pkg_grpc_quarkcmsvc_proto_rawDescGZIP(), []int{3} +} + +func (x *NodeListMessage) GetNodes() []*NodeMessage { + if x != nil { + return x.Nodes + } + return nil +} + +type PodMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Ip string `protobuf:"bytes,2,opt,name=ip,proto3" json:"ip,omitempty"` + NodeName string `protobuf:"bytes,3,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"` + ResourceVersion int32 `protobuf:"varint,4,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` +} + +func (x *PodMessage) Reset() { + *x = PodMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PodMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PodMessage) ProtoMessage() {} + +func (x *PodMessage) ProtoReflect() protoreflect.Message { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PodMessage.ProtoReflect.Descriptor instead. +func (*PodMessage) Descriptor() ([]byte, []int) { + return file_pkg_grpc_quarkcmsvc_proto_rawDescGZIP(), []int{4} +} + +func (x *PodMessage) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *PodMessage) GetIp() string { + if x != nil { + return x.Ip + } + return "" +} + +func (x *PodMessage) GetNodeName() string { + if x != nil { + return x.NodeName + } + return "" +} + +func (x *PodMessage) GetResourceVersion() int32 { + if x != nil { + return x.ResourceVersion + } + return 0 +} + +type PodListMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Pods []*PodMessage `protobuf:"bytes,1,rep,name=pods,proto3" json:"pods,omitempty"` +} + +func (x *PodListMessage) Reset() { + *x = PodListMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PodListMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PodListMessage) ProtoMessage() {} + +func (x *PodListMessage) ProtoReflect() protoreflect.Message { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PodListMessage.ProtoReflect.Descriptor instead. +func (*PodListMessage) Descriptor() ([]byte, []int) { + return file_pkg_grpc_quarkcmsvc_proto_rawDescGZIP(), []int{5} +} + +func (x *PodListMessage) GetPods() []*PodMessage { + if x != nil { + return x.Pods + } + return nil +} + var File_pkg_grpc_quarkcmsvc_proto protoreflect.FileDescriptor var file_pkg_grpc_quarkcmsvc_proto_rawDesc = []byte{ 0x0a, 0x19, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x71, 0x75, 0x61, - 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x22, 0x35, 0x0a, 0x12, 0x54, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, - 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x36, - 0x0a, 0x13, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x32, 0x5f, 0x0a, 0x0e, 0x51, 0x75, 0x61, 0x72, 0x6b, 0x43, + 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, 0x12, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x36, 0x0a, 0x13, 0x54, + 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x22, 0xa7, 0x01, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x70, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x40, 0x0a, + 0x0f, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x2d, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4e, 0x6f, 0x64, + 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, + 0x76, 0x0a, 0x0a, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, + 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3c, 0x0a, 0x0e, 0x50, 0x6f, 0x64, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x70, 0x6f, 0x64, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, + 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x04, 0x70, 0x6f, 0x64, 0x73, 0x32, 0xe3, 0x01, 0x0a, 0x0e, 0x51, 0x75, 0x61, 0x72, 0x6b, 0x43, 0x4d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x08, 0x54, 0x65, 0x73, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1f, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x70, 0x6b, 0x67, 0x2f, 0x67, - 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x4e, + 0x6f, 0x64, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x71, 0x75, + 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, + 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x07, 0x4c, 0x69, + 0x73, 0x74, 0x50, 0x6f, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, + 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x50, 0x6f, 0x64, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x70, + 0x6b, 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -163,19 +444,30 @@ func file_pkg_grpc_quarkcmsvc_proto_rawDescGZIP() []byte { return file_pkg_grpc_quarkcmsvc_proto_rawDescData } -var file_pkg_grpc_quarkcmsvc_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_pkg_grpc_quarkcmsvc_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_pkg_grpc_quarkcmsvc_proto_goTypes = []interface{}{ (*TestRequestMessage)(nil), // 0: quarkcmsvc.TestRequestMessage (*TestResponseMessage)(nil), // 1: quarkcmsvc.TestResponseMessage + (*NodeMessage)(nil), // 2: quarkcmsvc.NodeMessage + (*NodeListMessage)(nil), // 3: quarkcmsvc.NodeListMessage + (*PodMessage)(nil), // 4: quarkcmsvc.PodMessage + (*PodListMessage)(nil), // 5: quarkcmsvc.PodListMessage + (*emptypb.Empty)(nil), // 6: google.protobuf.Empty } var file_pkg_grpc_quarkcmsvc_proto_depIdxs = []int32{ - 0, // 0: quarkcmsvc.QuarkCMService.TestPing:input_type -> quarkcmsvc.TestRequestMessage - 1, // 1: quarkcmsvc.QuarkCMService.TestPing:output_type -> quarkcmsvc.TestResponseMessage - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 2, // 0: quarkcmsvc.NodeListMessage.nodes:type_name -> quarkcmsvc.NodeMessage + 4, // 1: quarkcmsvc.PodListMessage.pods:type_name -> quarkcmsvc.PodMessage + 0, // 2: quarkcmsvc.QuarkCMService.TestPing:input_type -> quarkcmsvc.TestRequestMessage + 6, // 3: quarkcmsvc.QuarkCMService.ListNode:input_type -> google.protobuf.Empty + 6, // 4: quarkcmsvc.QuarkCMService.ListPod:input_type -> google.protobuf.Empty + 1, // 5: quarkcmsvc.QuarkCMService.TestPing:output_type -> quarkcmsvc.TestResponseMessage + 3, // 6: quarkcmsvc.QuarkCMService.ListNode:output_type -> quarkcmsvc.NodeListMessage + 5, // 7: quarkcmsvc.QuarkCMService.ListPod:output_type -> quarkcmsvc.PodListMessage + 5, // [5:8] is the sub-list for method output_type + 2, // [2:5] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_pkg_grpc_quarkcmsvc_proto_init() } @@ -208,6 +500,54 @@ func file_pkg_grpc_quarkcmsvc_proto_init() { return nil } } + file_pkg_grpc_quarkcmsvc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NodeMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_grpc_quarkcmsvc_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NodeListMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_grpc_quarkcmsvc_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PodMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_grpc_quarkcmsvc_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PodListMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -215,7 +555,7 @@ func file_pkg_grpc_quarkcmsvc_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_pkg_grpc_quarkcmsvc_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 6, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/grpc/quarkcmsvc.proto b/pkg/grpc/quarkcmsvc.proto index e1f4f99..216adfd 100644 --- a/pkg/grpc/quarkcmsvc.proto +++ b/pkg/grpc/quarkcmsvc.proto @@ -16,12 +16,16 @@ limitations under the License. syntax = "proto3"; package quarkcmsvc; +import "google/protobuf/empty.proto"; option go_package = "pkg/grpc"; service QuarkCMService { // Test rpc TestPing (TestRequestMessage) returns (TestResponseMessage) {} + + rpc ListNode (google.protobuf.Empty) returns (NodeListMessage) {} + rpc ListPod (google.protobuf.Empty) returns (PodListMessage) {} } message TestRequestMessage { @@ -30,4 +34,27 @@ message TestRequestMessage { message TestResponseMessage { string server_name = 1; +} + +message NodeMessage { + string name = 1; + string hostname = 2; + string ip = 3; + string creation_timestamp = 4; + int32 resource_version = 5; +} + +message NodeListMessage { + repeated NodeMessage nodes = 1; +} + +message PodMessage { + string key = 1; + string ip = 2; + string node_name = 3; + int32 resource_version = 4; +} + +message PodListMessage { + repeated PodMessage pods = 1; } \ No newline at end of file diff --git a/pkg/grpc/quarkcmsvc_grpc.pb.go b/pkg/grpc/quarkcmsvc_grpc.pb.go index d3a1b11..3a5f7b0 100644 --- a/pkg/grpc/quarkcmsvc_grpc.pb.go +++ b/pkg/grpc/quarkcmsvc_grpc.pb.go @@ -11,6 +11,7 @@ import ( grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" ) // This is a compile-time assertion to ensure that this generated file @@ -24,6 +25,8 @@ const _ = grpc.SupportPackageIsVersion7 type QuarkCMServiceClient interface { // Test TestPing(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResponseMessage, error) + ListNode(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*NodeListMessage, error) + ListPod(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*PodListMessage, error) } type quarkCMServiceClient struct { @@ -43,12 +46,32 @@ func (c *quarkCMServiceClient) TestPing(ctx context.Context, in *TestRequestMess return out, nil } +func (c *quarkCMServiceClient) ListNode(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*NodeListMessage, error) { + out := new(NodeListMessage) + err := c.cc.Invoke(ctx, "/quarkcmsvc.QuarkCMService/ListNode", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *quarkCMServiceClient) ListPod(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*PodListMessage, error) { + out := new(PodListMessage) + err := c.cc.Invoke(ctx, "/quarkcmsvc.QuarkCMService/ListPod", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QuarkCMServiceServer is the server API for QuarkCMService service. // All implementations must embed UnimplementedQuarkCMServiceServer // for forward compatibility type QuarkCMServiceServer interface { // Test TestPing(context.Context, *TestRequestMessage) (*TestResponseMessage, error) + ListNode(context.Context, *emptypb.Empty) (*NodeListMessage, error) + ListPod(context.Context, *emptypb.Empty) (*PodListMessage, error) mustEmbedUnimplementedQuarkCMServiceServer() } @@ -59,6 +82,12 @@ type UnimplementedQuarkCMServiceServer struct { func (UnimplementedQuarkCMServiceServer) TestPing(context.Context, *TestRequestMessage) (*TestResponseMessage, error) { return nil, status.Errorf(codes.Unimplemented, "method TestPing not implemented") } +func (UnimplementedQuarkCMServiceServer) ListNode(context.Context, *emptypb.Empty) (*NodeListMessage, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListNode not implemented") +} +func (UnimplementedQuarkCMServiceServer) ListPod(context.Context, *emptypb.Empty) (*PodListMessage, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListPod not implemented") +} func (UnimplementedQuarkCMServiceServer) mustEmbedUnimplementedQuarkCMServiceServer() {} // UnsafeQuarkCMServiceServer may be embedded to opt out of forward compatibility for this service. @@ -90,6 +119,42 @@ func _QuarkCMService_TestPing_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _QuarkCMService_ListNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QuarkCMServiceServer).ListNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/quarkcmsvc.QuarkCMService/ListNode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QuarkCMServiceServer).ListNode(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _QuarkCMService_ListPod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QuarkCMServiceServer).ListPod(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/quarkcmsvc.QuarkCMService/ListPod", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QuarkCMServiceServer).ListPod(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + // QuarkCMService_ServiceDesc is the grpc.ServiceDesc for QuarkCMService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -101,6 +166,14 @@ var QuarkCMService_ServiceDesc = grpc.ServiceDesc{ MethodName: "TestPing", Handler: _QuarkCMService_TestPing_Handler, }, + { + MethodName: "ListNode", + Handler: _QuarkCMService_ListNode_Handler, + }, + { + MethodName: "ListPod", + Handler: _QuarkCMService_ListPod_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "pkg/grpc/quarkcmsvc.proto", diff --git a/quarkcmclient/src/main.rs b/quarkcmclient/src/main.rs index b24428e..12a0911 100644 --- a/quarkcmclient/src/main.rs +++ b/quarkcmclient/src/main.rs @@ -18,7 +18,11 @@ async fn main() -> Result<(), Box> { client_name: name, }); let response = client.test_ping(request).await?; + let all_pods = client.list_pod(()).await?; + let all_nodes = client.list_node(()).await?; - println!("{:?}", response); + println!("TestPing: {:?}", response); + println!("All pods: {:?}", all_pods); + println!("All nodes: {:?}", all_nodes); Ok(()) } \ No newline at end of file From 5e7f7b75e3462b1ccfe7e00775b8f9f55907ec81 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Wed, 13 Apr 2022 19:13:10 +0000 Subject: [PATCH 14/24] Change CreationTimestamp to int64 --- pkg/datastore/datastore.go | 2 +- pkg/grpc/quarkcmsvc.pb.go | 8 ++++---- pkg/grpc/quarkcmsvc.proto | 2 +- pkg/handlers/nodehandler.go | 2 +- pkg/objects/nodeobject.go | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/datastore/datastore.go b/pkg/datastore/datastore.go index f106334..b3f7f02 100644 --- a/pkg/datastore/datastore.go +++ b/pkg/datastore/datastore.go @@ -66,7 +66,7 @@ func calculateNextPodResourceVersion() int { return instance.PodResourceVersion } -func SetNode(key string, nodeHostname string, nodeIP string, creationTimestamp string, trackingId string) { +func SetNode(key string, nodeHostname string, nodeIP string, creationTimestamp int64, trackingId string) { nodeMap := Instance().NodeMap node, exists := nodeMap[key] changed := false diff --git a/pkg/grpc/quarkcmsvc.pb.go b/pkg/grpc/quarkcmsvc.pb.go index 3a6c77f..7281fc1 100644 --- a/pkg/grpc/quarkcmsvc.pb.go +++ b/pkg/grpc/quarkcmsvc.pb.go @@ -138,7 +138,7 @@ type NodeMessage struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` Ip string `protobuf:"bytes,3,opt,name=ip,proto3" json:"ip,omitempty"` - CreationTimestamp string `protobuf:"bytes,4,opt,name=creation_timestamp,json=creationTimestamp,proto3" json:"creation_timestamp,omitempty"` + CreationTimestamp int64 `protobuf:"varint,4,opt,name=creation_timestamp,json=creationTimestamp,proto3" json:"creation_timestamp,omitempty"` ResourceVersion int32 `protobuf:"varint,5,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` } @@ -195,11 +195,11 @@ func (x *NodeMessage) GetIp() string { return "" } -func (x *NodeMessage) GetCreationTimestamp() string { +func (x *NodeMessage) GetCreationTimestamp() int64 { if x != nil { return x.CreationTimestamp } - return "" + return 0 } func (x *NodeMessage) GetResourceVersion() int32 { @@ -394,7 +394,7 @@ var file_pkg_grpc_quarkcmsvc_proto_rawDesc = []byte{ 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x72, 0x65, diff --git a/pkg/grpc/quarkcmsvc.proto b/pkg/grpc/quarkcmsvc.proto index 216adfd..fab001a 100644 --- a/pkg/grpc/quarkcmsvc.proto +++ b/pkg/grpc/quarkcmsvc.proto @@ -40,7 +40,7 @@ message NodeMessage { string name = 1; string hostname = 2; string ip = 3; - string creation_timestamp = 4; + int64 creation_timestamp = 4; int32 resource_version = 5; } diff --git a/pkg/handlers/nodehandler.go b/pkg/handlers/nodehandler.go index 3c49f20..36eda66 100644 --- a/pkg/handlers/nodehandler.go +++ b/pkg/handlers/nodehandler.go @@ -46,5 +46,5 @@ func handleNodeSet(eventItem objects.EventItem, node *v1.Node) { hostname = item.Address } } - datastore.SetNode(eventItem.Key, hostname, nodeIP, node.ObjectMeta.CreationTimestamp.Time.String(), eventItem.Id) + datastore.SetNode(eventItem.Key, hostname, nodeIP, node.ObjectMeta.CreationTimestamp.Unix(), eventItem.Id) } diff --git a/pkg/objects/nodeobject.go b/pkg/objects/nodeobject.go index b90e42a..9e58837 100644 --- a/pkg/objects/nodeobject.go +++ b/pkg/objects/nodeobject.go @@ -20,6 +20,6 @@ type NodeObject struct { Name string Hostname string IP string - CreationTimestamp string + CreationTimestamp int64 ResourceVersion int } From 49110580d975ed0d5f4a04ad0c9f920e8505bdb1 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Thu, 14 Apr 2022 19:01:10 +0000 Subject: [PATCH 15/24] Add grpc stream --- pkg/datastore/datastore.go | 8 +- pkg/grpc/quarkcmsvc.go | 37 ++++++++- pkg/grpc/quarkcmsvc.pb.go | 137 +++++++++++++++++++++++++------- pkg/grpc/quarkcmsvc.proto | 8 +- pkg/grpc/quarkcmsvc_grpc.pb.go | 129 +++++++++++++++++++++++++++++- quarkcmclient/Cargo.lock | 1 + quarkcmclient/Cargo.toml | 1 + quarkcmclient/src/main.rs | 54 +++++++++++-- quarkcmclient/src/svc_client.rs | 31 ++++++++ 9 files changed, 362 insertions(+), 44 deletions(-) create mode 100644 quarkcmclient/src/svc_client.rs diff --git a/pkg/datastore/datastore.go b/pkg/datastore/datastore.go index b3f7f02..d9fb541 100644 --- a/pkg/datastore/datastore.go +++ b/pkg/datastore/datastore.go @@ -105,13 +105,13 @@ func DeleteNode(key string, trackingId string) { } } -func ListNode() []objects.NodeObject { +func ListNode(minResourceVersion int) []objects.NodeObject { maxResourceVersion := Instance().NodeResourceVersion nodeMap := Instance().NodeMap var nodes []objects.NodeObject for _, node := range nodeMap { - if node.ResourceVersion <= maxResourceVersion { + if node.ResourceVersion > minResourceVersion && node.ResourceVersion <= maxResourceVersion { nodes = append(nodes, *node) } } @@ -155,13 +155,13 @@ func DeletePod(key string, trackingId string) { } } -func ListPod() []objects.PodObject { +func ListPod(minResourceVersion int) []objects.PodObject { maxResourceVersion := Instance().PodResourceVersion podMap := Instance().PodMap var pods []objects.PodObject for _, pod := range podMap { - if pod.ResourceVersion <= maxResourceVersion { + if pod.ResourceVersion > minResourceVersion && pod.ResourceVersion <= maxResourceVersion { pods = append(pods, *pod) } } diff --git a/pkg/grpc/quarkcmsvc.go b/pkg/grpc/quarkcmsvc.go index 2d352dc..04abf3e 100644 --- a/pkg/grpc/quarkcmsvc.go +++ b/pkg/grpc/quarkcmsvc.go @@ -62,7 +62,7 @@ func (s *server) TestPing(ctx context.Context, in *TestRequestMessage) (*TestRes func (s *server) ListNode(ctx context.Context, in *emptypb.Empty) (*NodeListMessage, error) { klog.Info("grpc Service called ListNode") - nodeObjects := datastore.ListNode() + nodeObjects := datastore.ListNode(0) length := len(nodeObjects) nodeMessages := make([]*NodeMessage, 0, length) for i := 0; i < length; i++ { @@ -79,10 +79,27 @@ func (s *server) ListNode(ctx context.Context, in *emptypb.Empty) (*NodeListMess return &NodeListMessage{Nodes: nodeMessages}, nil } +func (s *server) WatchNode(maxResourceVersionMessage *MaxResourceVersionMessage, stream QuarkCMService_WatchNodeServer) error { + nodeObjects := datastore.ListNode(int(maxResourceVersionMessage.MaxResourceVersion)) + for _, nodeObject := range nodeObjects { + nodeMessage := &NodeMessage{ + Name: nodeObject.Name, + Hostname: nodeObject.Hostname, + Ip: nodeObject.IP, + CreationTimestamp: nodeObject.CreationTimestamp, + ResourceVersion: int32(nodeObject.ResourceVersion), + } + if err := stream.Send(nodeMessage); err != nil { + return err + } + } + return nil +} + func (s *server) ListPod(ctx context.Context, in *emptypb.Empty) (*PodListMessage, error) { klog.Info("grpc Service called ListPod") - podObjects := datastore.ListPod() + podObjects := datastore.ListPod(0) length := len(podObjects) podMessages := make([]*PodMessage, 0, length) for i := 0; i < length; i++ { @@ -97,3 +114,19 @@ func (s *server) ListPod(ctx context.Context, in *emptypb.Empty) (*PodListMessag return &PodListMessage{Pods: podMessages}, nil } + +func (s *server) WatchPod(maxResourceVersionMessage *MaxResourceVersionMessage, stream QuarkCMService_WatchPodServer) error { + podObjects := datastore.ListPod(int(maxResourceVersionMessage.MaxResourceVersion)) + for _, podObject := range podObjects { + podMessage := &PodMessage{ + Key: podObject.Key, + Ip: podObject.IP, + NodeName: podObject.NodeName, + ResourceVersion: int32(podObject.ResourceVersion), + } + if err := stream.Send(podMessage); err != nil { + return err + } + } + return nil +} diff --git a/pkg/grpc/quarkcmsvc.pb.go b/pkg/grpc/quarkcmsvc.pb.go index 7281fc1..601eccf 100644 --- a/pkg/grpc/quarkcmsvc.pb.go +++ b/pkg/grpc/quarkcmsvc.pb.go @@ -374,6 +374,53 @@ func (x *PodListMessage) GetPods() []*PodMessage { return nil } +type MaxResourceVersionMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MaxResourceVersion int32 `protobuf:"varint,1,opt,name=max_resource_version,json=maxResourceVersion,proto3" json:"max_resource_version,omitempty"` +} + +func (x *MaxResourceVersionMessage) Reset() { + *x = MaxResourceVersionMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MaxResourceVersionMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MaxResourceVersionMessage) ProtoMessage() {} + +func (x *MaxResourceVersionMessage) ProtoReflect() protoreflect.Message { + mi := &file_pkg_grpc_quarkcmsvc_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MaxResourceVersionMessage.ProtoReflect.Descriptor instead. +func (*MaxResourceVersionMessage) Descriptor() ([]byte, []int) { + return file_pkg_grpc_quarkcmsvc_proto_rawDescGZIP(), []int{6} +} + +func (x *MaxResourceVersionMessage) GetMaxResourceVersion() int32 { + if x != nil { + return x.MaxResourceVersion + } + return 0 +} + var File_pkg_grpc_quarkcmsvc_proto protoreflect.FileDescriptor var file_pkg_grpc_quarkcmsvc_proto_rawDesc = []byte{ @@ -414,22 +461,37 @@ var file_pkg_grpc_quarkcmsvc_proto_rawDesc = []byte{ 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x70, 0x6f, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, - 0x04, 0x70, 0x6f, 0x64, 0x73, 0x32, 0xe3, 0x01, 0x0a, 0x0e, 0x51, 0x75, 0x61, 0x72, 0x6b, 0x43, - 0x4d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x08, 0x54, 0x65, 0x73, 0x74, - 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, - 0x63, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1f, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, - 0x63, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x4e, - 0x6f, 0x64, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x71, 0x75, - 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x07, 0x4c, 0x69, + 0x04, 0x70, 0x6f, 0x64, 0x73, 0x22, 0x4d, 0x0a, 0x19, 0x4d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x12, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x32, 0x83, 0x03, 0x0a, 0x0e, 0x51, 0x75, 0x61, 0x72, 0x6b, 0x43, 0x4d, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x08, 0x54, 0x65, 0x73, 0x74, 0x50, + 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, + 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x1a, 0x1f, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, + 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, + 0x64, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x71, 0x75, 0x61, + 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x09, 0x57, 0x61, 0x74, + 0x63, 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x25, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, + 0x73, 0x76, 0x63, 0x2e, 0x4d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x17, 0x2e, + 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3f, 0x0a, 0x07, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x50, 0x6f, 0x64, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x70, - 0x6b, 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x08, 0x57, + 0x61, 0x74, 0x63, 0x68, 0x50, 0x6f, 0x64, 0x12, 0x25, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, + 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x16, + 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x50, 0x6f, 0x64, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x42, 0x0a, 0x5a, 0x08, 0x70, 0x6b, + 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -444,27 +506,32 @@ func file_pkg_grpc_quarkcmsvc_proto_rawDescGZIP() []byte { return file_pkg_grpc_quarkcmsvc_proto_rawDescData } -var file_pkg_grpc_quarkcmsvc_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_pkg_grpc_quarkcmsvc_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_pkg_grpc_quarkcmsvc_proto_goTypes = []interface{}{ - (*TestRequestMessage)(nil), // 0: quarkcmsvc.TestRequestMessage - (*TestResponseMessage)(nil), // 1: quarkcmsvc.TestResponseMessage - (*NodeMessage)(nil), // 2: quarkcmsvc.NodeMessage - (*NodeListMessage)(nil), // 3: quarkcmsvc.NodeListMessage - (*PodMessage)(nil), // 4: quarkcmsvc.PodMessage - (*PodListMessage)(nil), // 5: quarkcmsvc.PodListMessage - (*emptypb.Empty)(nil), // 6: google.protobuf.Empty + (*TestRequestMessage)(nil), // 0: quarkcmsvc.TestRequestMessage + (*TestResponseMessage)(nil), // 1: quarkcmsvc.TestResponseMessage + (*NodeMessage)(nil), // 2: quarkcmsvc.NodeMessage + (*NodeListMessage)(nil), // 3: quarkcmsvc.NodeListMessage + (*PodMessage)(nil), // 4: quarkcmsvc.PodMessage + (*PodListMessage)(nil), // 5: quarkcmsvc.PodListMessage + (*MaxResourceVersionMessage)(nil), // 6: quarkcmsvc.MaxResourceVersionMessage + (*emptypb.Empty)(nil), // 7: google.protobuf.Empty } var file_pkg_grpc_quarkcmsvc_proto_depIdxs = []int32{ 2, // 0: quarkcmsvc.NodeListMessage.nodes:type_name -> quarkcmsvc.NodeMessage 4, // 1: quarkcmsvc.PodListMessage.pods:type_name -> quarkcmsvc.PodMessage 0, // 2: quarkcmsvc.QuarkCMService.TestPing:input_type -> quarkcmsvc.TestRequestMessage - 6, // 3: quarkcmsvc.QuarkCMService.ListNode:input_type -> google.protobuf.Empty - 6, // 4: quarkcmsvc.QuarkCMService.ListPod:input_type -> google.protobuf.Empty - 1, // 5: quarkcmsvc.QuarkCMService.TestPing:output_type -> quarkcmsvc.TestResponseMessage - 3, // 6: quarkcmsvc.QuarkCMService.ListNode:output_type -> quarkcmsvc.NodeListMessage - 5, // 7: quarkcmsvc.QuarkCMService.ListPod:output_type -> quarkcmsvc.PodListMessage - 5, // [5:8] is the sub-list for method output_type - 2, // [2:5] is the sub-list for method input_type + 7, // 3: quarkcmsvc.QuarkCMService.ListNode:input_type -> google.protobuf.Empty + 6, // 4: quarkcmsvc.QuarkCMService.WatchNode:input_type -> quarkcmsvc.MaxResourceVersionMessage + 7, // 5: quarkcmsvc.QuarkCMService.ListPod:input_type -> google.protobuf.Empty + 6, // 6: quarkcmsvc.QuarkCMService.WatchPod:input_type -> quarkcmsvc.MaxResourceVersionMessage + 1, // 7: quarkcmsvc.QuarkCMService.TestPing:output_type -> quarkcmsvc.TestResponseMessage + 3, // 8: quarkcmsvc.QuarkCMService.ListNode:output_type -> quarkcmsvc.NodeListMessage + 2, // 9: quarkcmsvc.QuarkCMService.WatchNode:output_type -> quarkcmsvc.NodeMessage + 5, // 10: quarkcmsvc.QuarkCMService.ListPod:output_type -> quarkcmsvc.PodListMessage + 4, // 11: quarkcmsvc.QuarkCMService.WatchPod:output_type -> quarkcmsvc.PodMessage + 7, // [7:12] is the sub-list for method output_type + 2, // [2:7] is the sub-list for method input_type 2, // [2:2] is the sub-list for extension type_name 2, // [2:2] is the sub-list for extension extendee 0, // [0:2] is the sub-list for field type_name @@ -548,6 +615,18 @@ func file_pkg_grpc_quarkcmsvc_proto_init() { return nil } } + file_pkg_grpc_quarkcmsvc_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MaxResourceVersionMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -555,7 +634,7 @@ func file_pkg_grpc_quarkcmsvc_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_pkg_grpc_quarkcmsvc_proto_rawDesc, NumEnums: 0, - NumMessages: 6, + NumMessages: 7, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/grpc/quarkcmsvc.proto b/pkg/grpc/quarkcmsvc.proto index fab001a..1e39bd8 100644 --- a/pkg/grpc/quarkcmsvc.proto +++ b/pkg/grpc/quarkcmsvc.proto @@ -25,7 +25,9 @@ service QuarkCMService { rpc TestPing (TestRequestMessage) returns (TestResponseMessage) {} rpc ListNode (google.protobuf.Empty) returns (NodeListMessage) {} + rpc WatchNode (MaxResourceVersionMessage) returns (stream NodeMessage) {} rpc ListPod (google.protobuf.Empty) returns (PodListMessage) {} + rpc WatchPod (MaxResourceVersionMessage) returns (stream PodMessage) {} } message TestRequestMessage { @@ -57,4 +59,8 @@ message PodMessage { message PodListMessage { repeated PodMessage pods = 1; -} \ No newline at end of file +} + +message MaxResourceVersionMessage { + int32 max_resource_version = 1; +} diff --git a/pkg/grpc/quarkcmsvc_grpc.pb.go b/pkg/grpc/quarkcmsvc_grpc.pb.go index 3a5f7b0..324d310 100644 --- a/pkg/grpc/quarkcmsvc_grpc.pb.go +++ b/pkg/grpc/quarkcmsvc_grpc.pb.go @@ -26,7 +26,9 @@ type QuarkCMServiceClient interface { // Test TestPing(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResponseMessage, error) ListNode(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*NodeListMessage, error) + WatchNode(ctx context.Context, in *MaxResourceVersionMessage, opts ...grpc.CallOption) (QuarkCMService_WatchNodeClient, error) ListPod(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*PodListMessage, error) + WatchPod(ctx context.Context, in *MaxResourceVersionMessage, opts ...grpc.CallOption) (QuarkCMService_WatchPodClient, error) } type quarkCMServiceClient struct { @@ -55,6 +57,38 @@ func (c *quarkCMServiceClient) ListNode(ctx context.Context, in *emptypb.Empty, return out, nil } +func (c *quarkCMServiceClient) WatchNode(ctx context.Context, in *MaxResourceVersionMessage, opts ...grpc.CallOption) (QuarkCMService_WatchNodeClient, error) { + stream, err := c.cc.NewStream(ctx, &QuarkCMService_ServiceDesc.Streams[0], "/quarkcmsvc.QuarkCMService/WatchNode", opts...) + if err != nil { + return nil, err + } + x := &quarkCMServiceWatchNodeClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type QuarkCMService_WatchNodeClient interface { + Recv() (*NodeMessage, error) + grpc.ClientStream +} + +type quarkCMServiceWatchNodeClient struct { + grpc.ClientStream +} + +func (x *quarkCMServiceWatchNodeClient) Recv() (*NodeMessage, error) { + m := new(NodeMessage) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + func (c *quarkCMServiceClient) ListPod(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*PodListMessage, error) { out := new(PodListMessage) err := c.cc.Invoke(ctx, "/quarkcmsvc.QuarkCMService/ListPod", in, out, opts...) @@ -64,6 +98,38 @@ func (c *quarkCMServiceClient) ListPod(ctx context.Context, in *emptypb.Empty, o return out, nil } +func (c *quarkCMServiceClient) WatchPod(ctx context.Context, in *MaxResourceVersionMessage, opts ...grpc.CallOption) (QuarkCMService_WatchPodClient, error) { + stream, err := c.cc.NewStream(ctx, &QuarkCMService_ServiceDesc.Streams[1], "/quarkcmsvc.QuarkCMService/WatchPod", opts...) + if err != nil { + return nil, err + } + x := &quarkCMServiceWatchPodClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type QuarkCMService_WatchPodClient interface { + Recv() (*PodMessage, error) + grpc.ClientStream +} + +type quarkCMServiceWatchPodClient struct { + grpc.ClientStream +} + +func (x *quarkCMServiceWatchPodClient) Recv() (*PodMessage, error) { + m := new(PodMessage) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + // QuarkCMServiceServer is the server API for QuarkCMService service. // All implementations must embed UnimplementedQuarkCMServiceServer // for forward compatibility @@ -71,7 +137,9 @@ type QuarkCMServiceServer interface { // Test TestPing(context.Context, *TestRequestMessage) (*TestResponseMessage, error) ListNode(context.Context, *emptypb.Empty) (*NodeListMessage, error) + WatchNode(*MaxResourceVersionMessage, QuarkCMService_WatchNodeServer) error ListPod(context.Context, *emptypb.Empty) (*PodListMessage, error) + WatchPod(*MaxResourceVersionMessage, QuarkCMService_WatchPodServer) error mustEmbedUnimplementedQuarkCMServiceServer() } @@ -85,9 +153,15 @@ func (UnimplementedQuarkCMServiceServer) TestPing(context.Context, *TestRequestM func (UnimplementedQuarkCMServiceServer) ListNode(context.Context, *emptypb.Empty) (*NodeListMessage, error) { return nil, status.Errorf(codes.Unimplemented, "method ListNode not implemented") } +func (UnimplementedQuarkCMServiceServer) WatchNode(*MaxResourceVersionMessage, QuarkCMService_WatchNodeServer) error { + return status.Errorf(codes.Unimplemented, "method WatchNode not implemented") +} func (UnimplementedQuarkCMServiceServer) ListPod(context.Context, *emptypb.Empty) (*PodListMessage, error) { return nil, status.Errorf(codes.Unimplemented, "method ListPod not implemented") } +func (UnimplementedQuarkCMServiceServer) WatchPod(*MaxResourceVersionMessage, QuarkCMService_WatchPodServer) error { + return status.Errorf(codes.Unimplemented, "method WatchPod not implemented") +} func (UnimplementedQuarkCMServiceServer) mustEmbedUnimplementedQuarkCMServiceServer() {} // UnsafeQuarkCMServiceServer may be embedded to opt out of forward compatibility for this service. @@ -137,6 +211,27 @@ func _QuarkCMService_ListNode_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _QuarkCMService_WatchNode_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(MaxResourceVersionMessage) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(QuarkCMServiceServer).WatchNode(m, &quarkCMServiceWatchNodeServer{stream}) +} + +type QuarkCMService_WatchNodeServer interface { + Send(*NodeMessage) error + grpc.ServerStream +} + +type quarkCMServiceWatchNodeServer struct { + grpc.ServerStream +} + +func (x *quarkCMServiceWatchNodeServer) Send(m *NodeMessage) error { + return x.ServerStream.SendMsg(m) +} + func _QuarkCMService_ListPod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(emptypb.Empty) if err := dec(in); err != nil { @@ -155,6 +250,27 @@ func _QuarkCMService_ListPod_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _QuarkCMService_WatchPod_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(MaxResourceVersionMessage) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(QuarkCMServiceServer).WatchPod(m, &quarkCMServiceWatchPodServer{stream}) +} + +type QuarkCMService_WatchPodServer interface { + Send(*PodMessage) error + grpc.ServerStream +} + +type quarkCMServiceWatchPodServer struct { + grpc.ServerStream +} + +func (x *quarkCMServiceWatchPodServer) Send(m *PodMessage) error { + return x.ServerStream.SendMsg(m) +} + // QuarkCMService_ServiceDesc is the grpc.ServiceDesc for QuarkCMService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -175,6 +291,17 @@ var QuarkCMService_ServiceDesc = grpc.ServiceDesc{ Handler: _QuarkCMService_ListPod_Handler, }, }, - Streams: []grpc.StreamDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "WatchNode", + Handler: _QuarkCMService_WatchNode_Handler, + ServerStreams: true, + }, + { + StreamName: "WatchPod", + Handler: _QuarkCMService_WatchPod_Handler, + ServerStreams: true, + }, + }, Metadata: "pkg/grpc/quarkcmsvc.proto", } diff --git a/quarkcmclient/Cargo.lock b/quarkcmclient/Cargo.lock index 949ee7a..365280f 100644 --- a/quarkcmclient/Cargo.lock +++ b/quarkcmclient/Cargo.lock @@ -594,6 +594,7 @@ dependencies = [ "hostname", "prost", "tokio", + "tokio-stream", "tonic", "tonic-build", ] diff --git a/quarkcmclient/Cargo.toml b/quarkcmclient/Cargo.toml index 3c81624..de8d5e3 100644 --- a/quarkcmclient/Cargo.toml +++ b/quarkcmclient/Cargo.toml @@ -10,6 +10,7 @@ hostname = "^0.3" tonic = "0.7" prost = "0.10" tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } +tokio-stream = { version = "0.1", features = ["net"] } [build-dependencies] tonic-build = "0.7" \ No newline at end of file diff --git a/quarkcmclient/src/main.rs b/quarkcmclient/src/main.rs index 12a0911..bb8bb3c 100644 --- a/quarkcmclient/src/main.rs +++ b/quarkcmclient/src/main.rs @@ -1,5 +1,25 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + use quarkcmsvc::quark_cm_service_client::QuarkCmServiceClient; +use quarkcmsvc::MaxResourceVersionMessage; use quarkcmsvc::TestRequestMessage; +use tonic::Request; + +mod svc_client; pub mod quarkcmsvc { tonic::include_proto!("quarkcmsvc"); @@ -9,18 +29,38 @@ pub mod quarkcmsvc { async fn main() -> Result<(), Box> { let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; - let mut name=String::new(); - match hostname::get()?.into_string(){ - Ok(n)=>{name=n}, - _=>{} + let mut name = String::new(); + match hostname::get()?.into_string() { + Ok(n) => name = n, + _ => {} }; - let request=tonic::Request::new(TestRequestMessage{ - client_name: name, - }); + let request = tonic::Request::new(TestRequestMessage { client_name: name }); let response = client.test_ping(request).await?; let all_pods = client.list_pod(()).await?; let all_nodes = client.list_node(()).await?; + let mut pod_stream = client + .watch_pod(Request::new(MaxResourceVersionMessage { + max_resource_version: 0, + })) + .await? + .into_inner(); + + while let Some(pod_message) = pod_stream.message().await? { + println!("Received Pod {:?}", pod_message); + } + + let mut node_stream = client + .watch_node(Request::new(MaxResourceVersionMessage { + max_resource_version: 0, + })) + .await? + .into_inner(); + + while let Some(node_message) = node_stream.message().await? { + println!("Received Node {:?}", node_message); + } + println!("TestPing: {:?}", response); println!("All pods: {:?}", all_pods); println!("All nodes: {:?}", all_nodes); diff --git a/quarkcmclient/src/svc_client.rs b/quarkcmclient/src/svc_client.rs new file mode 100644 index 0000000..37a7dc6 --- /dev/null +++ b/quarkcmclient/src/svc_client.rs @@ -0,0 +1,31 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// use svc_client::quark_cm_service_client::QuarkCmServiceClient; + +// pub mod svc_client{ +// tonic::include_proto!("quarkcmsvc"); +// } + +// pub struct Client { +// client: svc_client::quark_cm_service_client::QuarkCmServiceClient +// } + +// impl Client { +// pub async fn init() -> Result<(), Box> { +// let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; +// } +// } From bccfa4fe2bbbf14d0b30f536e46cf7f1f825d97b Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Fri, 15 Apr 2022 00:19:07 +0000 Subject: [PATCH 16/24] Move grpc client to seperate mod --- quarkcmclient/src/main.rs | 49 +----------- quarkcmclient/src/svc_client/client.rs | 74 +++++++++++++++++++ .../src/{svc_client.rs => svc_client/mod.rs} | 16 +--- 3 files changed, 77 insertions(+), 62 deletions(-) create mode 100644 quarkcmclient/src/svc_client/client.rs rename quarkcmclient/src/{svc_client.rs => svc_client/mod.rs} (55%) diff --git a/quarkcmclient/src/main.rs b/quarkcmclient/src/main.rs index bb8bb3c..5f65964 100644 --- a/quarkcmclient/src/main.rs +++ b/quarkcmclient/src/main.rs @@ -13,56 +13,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ - -use quarkcmsvc::quark_cm_service_client::QuarkCmServiceClient; -use quarkcmsvc::MaxResourceVersionMessage; -use quarkcmsvc::TestRequestMessage; -use tonic::Request; - mod svc_client; - -pub mod quarkcmsvc { - tonic::include_proto!("quarkcmsvc"); -} +use svc_client::client::Client; #[tokio::main] async fn main() -> Result<(), Box> { - let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; - - let mut name = String::new(); - match hostname::get()?.into_string() { - Ok(n) => name = n, - _ => {} - }; - let request = tonic::Request::new(TestRequestMessage { client_name: name }); - let response = client.test_ping(request).await?; - let all_pods = client.list_pod(()).await?; - let all_nodes = client.list_node(()).await?; - - let mut pod_stream = client - .watch_pod(Request::new(MaxResourceVersionMessage { - max_resource_version: 0, - })) - .await? - .into_inner(); - - while let Some(pod_message) = pod_stream.message().await? { - println!("Received Pod {:?}", pod_message); - } - - let mut node_stream = client - .watch_node(Request::new(MaxResourceVersionMessage { - max_resource_version: 0, - })) - .await? - .into_inner(); - - while let Some(node_message) = node_stream.message().await? { - println!("Received Node {:?}", node_message); - } - - println!("TestPing: {:?}", response); - println!("All pods: {:?}", all_pods); - println!("All nodes: {:?}", all_nodes); + Client::init().await?; Ok(()) } \ No newline at end of file diff --git a/quarkcmclient/src/svc_client/client.rs b/quarkcmclient/src/svc_client/client.rs new file mode 100644 index 0000000..d3784ce --- /dev/null +++ b/quarkcmclient/src/svc_client/client.rs @@ -0,0 +1,74 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// use svc_client::quark_cm_service_client::QuarkCmServiceClient; + +use svc_client::quark_cm_service_client::QuarkCmServiceClient; +use svc_client::MaxResourceVersionMessage; +use svc_client::TestRequestMessage; +use tonic::Request; + +pub mod svc_client { + tonic::include_proto!("quarkcmsvc"); +} + +pub struct Client { + //client: svc_client::quark_cm_service_client::QuarkCmServiceClient, +} + +impl Client { + pub async fn init() -> Result<(), Box> { + let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; + + let mut name = String::new(); + match hostname::get()?.into_string() { + Ok(n) => name = n, + _ => {} + }; + let request = tonic::Request::new(TestRequestMessage { client_name: name }); + let response = client.test_ping(request).await?; + println!("TestPing: {:?}", response); + + let all_pods = client.list_pod(()).await?; + println!("All pods: {:?}", all_pods); + + let all_nodes = client.list_node(()).await?; + println!("All nodes: {:?}", all_nodes); + + let mut pod_stream = client + .watch_pod(Request::new(MaxResourceVersionMessage { + max_resource_version: 0, + })) + .await? + .into_inner(); + + while let Some(pod_message) = pod_stream.message().await? { + println!("Received Pod {:?}", pod_message); + } + + let mut node_stream = client + .watch_node(Request::new(MaxResourceVersionMessage { + max_resource_version: 0, + })) + .await? + .into_inner(); + + while let Some(node_message) = node_stream.message().await? { + println!("Received Node {:?}", node_message); + } + Ok(()) + } +} diff --git a/quarkcmclient/src/svc_client.rs b/quarkcmclient/src/svc_client/mod.rs similarity index 55% rename from quarkcmclient/src/svc_client.rs rename to quarkcmclient/src/svc_client/mod.rs index 37a7dc6..17d7cf0 100644 --- a/quarkcmclient/src/svc_client.rs +++ b/quarkcmclient/src/svc_client/mod.rs @@ -14,18 +14,4 @@ See the License for the specific language governing permissions and limitations under the License. */ -// use svc_client::quark_cm_service_client::QuarkCmServiceClient; - -// pub mod svc_client{ -// tonic::include_proto!("quarkcmsvc"); -// } - -// pub struct Client { -// client: svc_client::quark_cm_service_client::QuarkCmServiceClient -// } - -// impl Client { -// pub async fn init() -> Result<(), Box> { -// let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; -// } -// } +pub mod client; \ No newline at end of file From 9dc950707a95d652879bcc1b81d44b5d7ce9f7e4 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Fri, 15 Apr 2022 23:14:20 +0000 Subject: [PATCH 17/24] Refine async func --- quarkcmclient/Cargo.lock | 36 +++++++++ quarkcmclient/Cargo.toml | 7 +- quarkcmclient/src/main.rs | 36 ++++++++- quarkcmclient/src/rdma_ctrlconn.rs | 53 +++++++++++++ quarkcmclient/src/svc_client/client.rs | 3 - quarkcmclient/src/svc_client/mod.rs | 4 +- quarkcmclient/src/svc_client/pod_informer.rs | 81 ++++++++++++++++++++ 7 files changed, 212 insertions(+), 8 deletions(-) create mode 100644 quarkcmclient/src/rdma_ctrlconn.rs create mode 100644 quarkcmclient/src/svc_client/pod_informer.rs diff --git a/quarkcmclient/Cargo.lock b/quarkcmclient/Cargo.lock index 365280f..0d36659 100644 --- a/quarkcmclient/Cargo.lock +++ b/quarkcmclient/Cargo.lock @@ -371,6 +371,9 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] [[package]] name = "libc" @@ -378,6 +381,16 @@ version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd" +[[package]] +name = "lock_api" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.16" @@ -592,7 +605,9 @@ name = "quarkcmclient" version = "0.1.0" dependencies = [ "hostname", + "lazy_static", "prost", + "spin 0.9.2", "tokio", "tokio-stream", "tonic", @@ -671,6 +686,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "serde" version = "1.0.136" @@ -693,6 +714,21 @@ dependencies = [ "winapi", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5" +dependencies = [ + "lock_api", +] + [[package]] name = "syn" version = "1.0.91" diff --git a/quarkcmclient/Cargo.toml b/quarkcmclient/Cargo.toml index de8d5e3..fa59a16 100644 --- a/quarkcmclient/Cargo.toml +++ b/quarkcmclient/Cargo.toml @@ -7,10 +7,15 @@ edition = "2021" [dependencies] hostname = "^0.3" -tonic = "0.7" prost = "0.10" +spin = "0.9.2" tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } tokio-stream = { version = "0.1", features = ["net"] } +tonic = "0.7" + +[dependencies.lazy_static] +version = "1.4" +features = ["spin_no_std"] [build-dependencies] tonic-build = "0.7" \ No newline at end of file diff --git a/quarkcmclient/src/main.rs b/quarkcmclient/src/main.rs index 5f65964..d6276a7 100644 --- a/quarkcmclient/src/main.rs +++ b/quarkcmclient/src/main.rs @@ -13,11 +13,41 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ + +pub mod rdma_ctrlconn; + mod svc_client; -use svc_client::client::Client; +//use svc_client::client::Client; +use crate::rdma_ctrlconn::*; +use svc_client::pod_informer::PodInformer; + +use lazy_static::lazy_static; + +lazy_static! { + pub static ref RDMA_CTLINFO: CtrlInfo = CtrlInfo::default(); +} #[tokio::main] async fn main() -> Result<(), Box> { - Client::init().await?; + //Client::init().await?; + //PodInformer::run().await?; + + let mut pod_informer = PodInformer::new().await?; + tokio::join!( + pod_informer.run(), + sleep_then_print(1), + sleep_then_print(2), + ); + //pod_informer.run().await?; + println!("ok"); Ok(()) -} \ No newline at end of file +} + +async fn sleep_then_print(timer: i32) { + println!("Start timer {}.", timer); + + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; +// ^ execution can be paused here + + println!("Timer {} done.", timer); +} diff --git a/quarkcmclient/src/rdma_ctrlconn.rs b/quarkcmclient/src/rdma_ctrlconn.rs new file mode 100644 index 0000000..a334797 --- /dev/null +++ b/quarkcmclient/src/rdma_ctrlconn.rs @@ -0,0 +1,53 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +use spin::Mutex; +use std::collections::HashMap; + +#[derive(Debug)] +pub struct CtrlInfo { + // nodes: node ip --> Node + pub nodes: Mutex>, + + // pods: pod ip --> Pod + pub pods: Mutex>, +} + +impl Default for CtrlInfo { + fn default() -> Self { + return Self { + nodes: Mutex::>::new(HashMap::::new()), + pods: Mutex::>::new(HashMap::::new()), + }; + } +} + +#[derive(Debug)] +pub struct Node { + pub name: String, + pub hostname: String, + pub ip: String, + pub timestamp: i64, + pub resource_version: i32, +} + +#[derive(Debug)] +pub struct Pod { + pub key: String, + pub ip: String, + pub node_name: String, + pub resource_version: i32, +} diff --git a/quarkcmclient/src/svc_client/client.rs b/quarkcmclient/src/svc_client/client.rs index d3784ce..9aa8e0a 100644 --- a/quarkcmclient/src/svc_client/client.rs +++ b/quarkcmclient/src/svc_client/client.rs @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// use svc_client::quark_cm_service_client::QuarkCmServiceClient; - use svc_client::quark_cm_service_client::QuarkCmServiceClient; use svc_client::MaxResourceVersionMessage; use svc_client::TestRequestMessage; @@ -26,7 +24,6 @@ pub mod svc_client { } pub struct Client { - //client: svc_client::quark_cm_service_client::QuarkCmServiceClient, } impl Client { diff --git a/quarkcmclient/src/svc_client/mod.rs b/quarkcmclient/src/svc_client/mod.rs index 17d7cf0..e6e3272 100644 --- a/quarkcmclient/src/svc_client/mod.rs +++ b/quarkcmclient/src/svc_client/mod.rs @@ -14,4 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -pub mod client; \ No newline at end of file +pub mod client; + +pub mod pod_informer; \ No newline at end of file diff --git a/quarkcmclient/src/svc_client/pod_informer.rs b/quarkcmclient/src/svc_client/pod_informer.rs new file mode 100644 index 0000000..dcf7768 --- /dev/null +++ b/quarkcmclient/src/svc_client/pod_informer.rs @@ -0,0 +1,81 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +use super::super::RDMA_CTLINFO; +use crate::rdma_ctrlconn::*; +use svc_client::quark_cm_service_client::QuarkCmServiceClient; +use svc_client::MaxResourceVersionMessage; +use tonic::Request; + +pub mod svc_client { + tonic::include_proto!("quarkcmsvc"); +} + +#[derive(Debug)] +pub struct PodInformer { + pub max_resource_version: i32, +} + +impl PodInformer { + pub async fn new() -> Result> { + let mut informer = Self { + max_resource_version: 0, + }; + let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; + + let ref pods_message = client.list_pod(()).await?.into_inner().pods; + println!("All pods: {:#?}", pods_message); + if pods_message.len() > 0 { + let mut pods_map = RDMA_CTLINFO.pods.lock(); + + for pod_message in pods_message { + let pod = Pod { + key: pod_message.key.clone(), + ip: pod_message.ip.clone(), + node_name: pod_message.node_name.clone(), + resource_version: pod_message.resource_version, + }; + pods_map.insert(pod_message.ip.clone(), pod); + if pod_message.resource_version > informer.max_resource_version { + informer.max_resource_version = pod_message.resource_version; + } + } + println!("max_resource_version: {}", informer.max_resource_version); + println!("RDMA_CTLINFO {:#?}", pods_map); + } + + Ok(informer) + } +} + +impl PodInformer { + pub async fn run(&mut self) -> Result<(), Box> { + let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; + + let mut pod_stream = client + .watch_pod(Request::new(MaxResourceVersionMessage { + // max_resource_version: self.max_resource_version, + max_resource_version: 0, + })) + .await? + .into_inner(); + + while let Some(pod_message) = pod_stream.message().await? { + println!("Received Pod {:?}", pod_message); + } + Ok(()) + } +} From 7df34a9fb7801c7400507aa455dc550a7071c929 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Mon, 18 Apr 2022 18:14:20 +0000 Subject: [PATCH 18/24] Refine server side --- pkg/datastore/datastore.go | 118 ++++++++++++------- pkg/grpc/quarkcmsvc.go | 60 +++++----- pkg/grpc/quarkcmsvc.pb.go | 102 +++++++++------- pkg/grpc/quarkcmsvc.proto | 2 + pkg/objects/nodeeventobject.go | 23 ++++ pkg/objects/podeventobject.go | 23 ++++ quarkcmclient/src/rdma_ctrlconn.rs | 3 + quarkcmclient/src/svc_client/pod_informer.rs | 37 ++++-- 8 files changed, 244 insertions(+), 124 deletions(-) create mode 100644 pkg/objects/nodeeventobject.go create mode 100644 pkg/objects/podeventobject.go diff --git a/pkg/datastore/datastore.go b/pkg/datastore/datastore.go index d9fb541..a7ad8f7 100644 --- a/pkg/datastore/datastore.go +++ b/pkg/datastore/datastore.go @@ -20,15 +20,18 @@ import ( "encoding/json" "sync" + "github.com/CentaurusInfra/quarkcm/pkg/constants" "github.com/CentaurusInfra/quarkcm/pkg/objects" "k8s.io/klog" ) type DataStore struct { NodeResourceVersion int - NodeMap map[string]*objects.NodeObject // map[node name] => node object + NodeMap map[string]*objects.NodeObject // map[node name] => node object + NodeEventMap map[int]*objects.NodeEventObject // map[resource version] => node event object PodResourceVersion int - PodMap map[string]*objects.PodObject // map[key] => pod object + PodMap map[string]*objects.PodObject // map[key] => pod object + PodEventMap map[int]*objects.PodEventObject // map[resource version] => pod event object } var lock = &sync.Mutex{} @@ -42,8 +45,10 @@ func Instance() *DataStore { dataStore = &DataStore{ NodeResourceVersion: 0, NodeMap: map[string]*objects.NodeObject{}, + NodeEventMap: map[int]*objects.NodeEventObject{}, PodResourceVersion: 0, PodMap: map[string]*objects.PodObject{}, + PodEventMap: map[int]*objects.PodEventObject{}, } } } @@ -66,56 +71,67 @@ func calculateNextPodResourceVersion() int { return instance.PodResourceVersion } -func SetNode(key string, nodeHostname string, nodeIP string, creationTimestamp int64, trackingId string) { +func SetNode(name string, nodeHostname string, nodeIP string, creationTimestamp int64, trackingId string) { nodeMap := Instance().NodeMap - node, exists := nodeMap[key] + node, exists := nodeMap[name] changed := false if exists { if node.Hostname != nodeHostname || node.IP != nodeIP { - node.Hostname = nodeHostname - node.IP = nodeIP - node.CreationTimestamp = creationTimestamp - node.ResourceVersion = calculateNextNodeResourceVersion() changed = true } else { - klog.Infof("Handling node completed. Node %s is unchanged. Tracking Id: %s", key, trackingId) + klog.Infof("Handling node completed. Node %s is unchanged. Tracking Id: %s", name, trackingId) } } else { - nodeMap[key] = &objects.NodeObject{ - Name: key, + changed = true + } + + if changed { + resourceVersion := calculateNextNodeResourceVersion() + newNode := &objects.NodeObject{ + Name: name, Hostname: nodeHostname, IP: nodeIP, CreationTimestamp: creationTimestamp, - ResourceVersion: calculateNextNodeResourceVersion(), + ResourceVersion: resourceVersion, } - changed = true - } - if changed { - nodeStr, _ := json.Marshal(nodeMap[key]) + newNodeEvent := &objects.NodeEventObject{ + ResourceVersion: resourceVersion, + EventType: constants.EventType_Set, + NodeObject: *newNode, + } + nodeMap[name] = newNode + Instance().NodeEventMap[resourceVersion] = newNodeEvent + + nodeStr, _ := json.Marshal(nodeMap[name]) klog.Infof("Handling node completed. Node set as %s. Tracking Id: %s", nodeStr, trackingId) } } -func DeleteNode(key string, trackingId string) { +func DeleteNode(name string, trackingId string) { nodeMap := Instance().NodeMap - _, exists := nodeMap[key] + node, exists := nodeMap[name] if exists { - delete(nodeMap, key) - klog.Infof("Handling node completed. Node %s is deleted. Tracking Id: %s", key, trackingId) + resourceVersion := calculateNextNodeResourceVersion() + newNodeEvent := &objects.NodeEventObject{ + ResourceVersion: resourceVersion, + EventType: constants.EventType_Delete, + NodeObject: *node, + } + Instance().NodeEventMap[resourceVersion] = newNodeEvent + delete(nodeMap, name) + klog.Infof("Handling node completed. Node %s is deleted. Tracking Id: %s", name, trackingId) } } -func ListNode(minResourceVersion int) []objects.NodeObject { +func ListNode(minResourceVersion int) []objects.NodeEventObject { maxResourceVersion := Instance().NodeResourceVersion - nodeMap := Instance().NodeMap + nodeEventMap := Instance().NodeEventMap - var nodes []objects.NodeObject - for _, node := range nodeMap { - if node.ResourceVersion > minResourceVersion && node.ResourceVersion <= maxResourceVersion { - nodes = append(nodes, *node) - } + var nodeEvents []objects.NodeEventObject + for i := minResourceVersion + 1; i <= maxResourceVersion; i++ { + nodeEvents = append(nodeEvents, *nodeEventMap[i]) } - return nodes + return nodeEvents } func SetPod(key string, podIP string, nodeName string, trackingId string) { @@ -124,23 +140,30 @@ func SetPod(key string, podIP string, nodeName string, trackingId string) { changed := false if exists { if pod.IP != podIP || pod.NodeName != nodeName { - pod.IP = podIP - pod.NodeName = nodeName - pod.ResourceVersion = calculateNextPodResourceVersion() changed = true } else { klog.Infof("Handling pod completed. Pod %s is unchanged. Tracking Id: %s", key, trackingId) } } else { - podMap[key] = &objects.PodObject{ + changed = true + } + + if changed { + resourceVersion := calculateNextPodResourceVersion() + newPod := &objects.PodObject{ Key: key, IP: podIP, NodeName: nodeName, - ResourceVersion: calculateNextPodResourceVersion(), + ResourceVersion: resourceVersion, } - changed = true - } - if changed { + newPodEvent := &objects.PodEventObject{ + ResourceVersion: resourceVersion, + EventType: constants.EventType_Set, + PodObject: *newPod, + } + podMap[key] = newPod + Instance().PodEventMap[resourceVersion] = newPodEvent + podStr, _ := json.Marshal(podMap[key]) klog.Infof("Handling pod completed. Pod set as %s. Tracking Id: %s", podStr, trackingId) } @@ -148,22 +171,27 @@ func SetPod(key string, podIP string, nodeName string, trackingId string) { func DeletePod(key string, trackingId string) { podMap := Instance().PodMap - _, exists := podMap[key] + pod, exists := podMap[key] if exists { + resourceVersion := calculateNextPodResourceVersion() + newPodEvent := &objects.PodEventObject{ + ResourceVersion: resourceVersion, + EventType: constants.EventType_Delete, + PodObject: *pod, + } + Instance().PodEventMap[resourceVersion] = newPodEvent delete(podMap, key) klog.Infof("Handling pod completed. Pod %s is deleted. Tracking Id: %s", key, trackingId) } } -func ListPod(minResourceVersion int) []objects.PodObject { +func ListPod(minResourceVersion int) []objects.PodEventObject { maxResourceVersion := Instance().PodResourceVersion - podMap := Instance().PodMap + podEventMap := Instance().PodEventMap - var pods []objects.PodObject - for _, pod := range podMap { - if pod.ResourceVersion > minResourceVersion && pod.ResourceVersion <= maxResourceVersion { - pods = append(pods, *pod) - } + var podEvents []objects.PodEventObject + for i := minResourceVersion + 1; i <= maxResourceVersion; i++ { + podEvents = append(podEvents, *podEventMap[i]) } - return pods + return podEvents } diff --git a/pkg/grpc/quarkcmsvc.go b/pkg/grpc/quarkcmsvc.go index 04abf3e..9db03d1 100644 --- a/pkg/grpc/quarkcmsvc.go +++ b/pkg/grpc/quarkcmsvc.go @@ -62,17 +62,18 @@ func (s *server) TestPing(ctx context.Context, in *TestRequestMessage) (*TestRes func (s *server) ListNode(ctx context.Context, in *emptypb.Empty) (*NodeListMessage, error) { klog.Info("grpc Service called ListNode") - nodeObjects := datastore.ListNode(0) - length := len(nodeObjects) + nodeEventObjects := datastore.ListNode(0) + length := len(nodeEventObjects) nodeMessages := make([]*NodeMessage, 0, length) for i := 0; i < length; i++ { - nodeObject := nodeObjects[i] + nodeEventObject := nodeEventObjects[i] nodeMessages = append(nodeMessages, &NodeMessage{ - Name: nodeObject.Name, - Hostname: nodeObject.Hostname, - Ip: nodeObject.IP, - CreationTimestamp: nodeObject.CreationTimestamp, - ResourceVersion: int32(nodeObject.ResourceVersion), + Name: nodeEventObject.NodeObject.Name, + Hostname: nodeEventObject.NodeObject.Hostname, + Ip: nodeEventObject.NodeObject.IP, + CreationTimestamp: nodeEventObject.NodeObject.CreationTimestamp, + ResourceVersion: int32(nodeEventObject.ResourceVersion), + EventType: nodeEventObject.EventType, }) } @@ -80,14 +81,15 @@ func (s *server) ListNode(ctx context.Context, in *emptypb.Empty) (*NodeListMess } func (s *server) WatchNode(maxResourceVersionMessage *MaxResourceVersionMessage, stream QuarkCMService_WatchNodeServer) error { - nodeObjects := datastore.ListNode(int(maxResourceVersionMessage.MaxResourceVersion)) - for _, nodeObject := range nodeObjects { + nodeEventObjects := datastore.ListNode(int(maxResourceVersionMessage.MaxResourceVersion)) + for _, nodeEventObject := range nodeEventObjects { nodeMessage := &NodeMessage{ - Name: nodeObject.Name, - Hostname: nodeObject.Hostname, - Ip: nodeObject.IP, - CreationTimestamp: nodeObject.CreationTimestamp, - ResourceVersion: int32(nodeObject.ResourceVersion), + Name: nodeEventObject.NodeObject.Name, + Hostname: nodeEventObject.NodeObject.Hostname, + Ip: nodeEventObject.NodeObject.IP, + CreationTimestamp: nodeEventObject.NodeObject.CreationTimestamp, + ResourceVersion: int32(nodeEventObject.ResourceVersion), + EventType: nodeEventObject.EventType, } if err := stream.Send(nodeMessage); err != nil { return err @@ -99,16 +101,17 @@ func (s *server) WatchNode(maxResourceVersionMessage *MaxResourceVersionMessage, func (s *server) ListPod(ctx context.Context, in *emptypb.Empty) (*PodListMessage, error) { klog.Info("grpc Service called ListPod") - podObjects := datastore.ListPod(0) - length := len(podObjects) + podEventObjects := datastore.ListPod(0) + length := len(podEventObjects) podMessages := make([]*PodMessage, 0, length) for i := 0; i < length; i++ { - podObject := podObjects[i] + podEventObject := podEventObjects[i] podMessages = append(podMessages, &PodMessage{ - Key: podObject.Key, - Ip: podObject.IP, - NodeName: podObject.NodeName, - ResourceVersion: int32(podObject.ResourceVersion), + Key: podEventObject.PodObject.Key, + Ip: podEventObject.PodObject.IP, + NodeName: podEventObject.PodObject.NodeName, + ResourceVersion: int32(podEventObject.ResourceVersion), + EventType: podEventObject.EventType, }) } @@ -116,13 +119,14 @@ func (s *server) ListPod(ctx context.Context, in *emptypb.Empty) (*PodListMessag } func (s *server) WatchPod(maxResourceVersionMessage *MaxResourceVersionMessage, stream QuarkCMService_WatchPodServer) error { - podObjects := datastore.ListPod(int(maxResourceVersionMessage.MaxResourceVersion)) - for _, podObject := range podObjects { + podEventObjects := datastore.ListPod(int(maxResourceVersionMessage.MaxResourceVersion)) + for _, podEventObject := range podEventObjects { podMessage := &PodMessage{ - Key: podObject.Key, - Ip: podObject.IP, - NodeName: podObject.NodeName, - ResourceVersion: int32(podObject.ResourceVersion), + Key: podEventObject.PodObject.Key, + Ip: podEventObject.PodObject.IP, + NodeName: podEventObject.PodObject.NodeName, + ResourceVersion: int32(podEventObject.ResourceVersion), + EventType: podEventObject.EventType, } if err := stream.Send(podMessage); err != nil { return err diff --git a/pkg/grpc/quarkcmsvc.pb.go b/pkg/grpc/quarkcmsvc.pb.go index 601eccf..bce2edc 100644 --- a/pkg/grpc/quarkcmsvc.pb.go +++ b/pkg/grpc/quarkcmsvc.pb.go @@ -140,6 +140,7 @@ type NodeMessage struct { Ip string `protobuf:"bytes,3,opt,name=ip,proto3" json:"ip,omitempty"` CreationTimestamp int64 `protobuf:"varint,4,opt,name=creation_timestamp,json=creationTimestamp,proto3" json:"creation_timestamp,omitempty"` ResourceVersion int32 `protobuf:"varint,5,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` + EventType string `protobuf:"bytes,6,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"` } func (x *NodeMessage) Reset() { @@ -209,6 +210,13 @@ func (x *NodeMessage) GetResourceVersion() int32 { return 0 } +func (x *NodeMessage) GetEventType() string { + if x != nil { + return x.EventType + } + return "" +} + type NodeListMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -265,6 +273,7 @@ type PodMessage struct { Ip string `protobuf:"bytes,2,opt,name=ip,proto3" json:"ip,omitempty"` NodeName string `protobuf:"bytes,3,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"` ResourceVersion int32 `protobuf:"varint,4,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` + EventType string `protobuf:"bytes,5,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"` } func (x *PodMessage) Reset() { @@ -327,6 +336,13 @@ func (x *PodMessage) GetResourceVersion() int32 { return 0 } +func (x *PodMessage) GetEventType() string { + if x != nil { + return x.EventType + } + return "" +} + type PodListMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -435,7 +451,7 @@ var file_pkg_grpc_quarkcmsvc_proto_rawDesc = []byte{ 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x22, 0xa7, 0x01, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x6d, 0x65, 0x22, 0xc6, 0x01, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, @@ -445,53 +461,57 @@ var file_pkg_grpc_quarkcmsvc_proto_rawDesc = []byte{ 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x40, 0x0a, - 0x0f, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x2d, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4e, 0x6f, 0x64, - 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, - 0x76, 0x0a, 0x0a, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, + 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x40, 0x0a, 0x0f, + 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x2d, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x95, + 0x01, 0x0a, 0x0a, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3c, 0x0a, 0x0e, 0x50, 0x6f, 0x64, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x70, 0x6f, 0x64, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, - 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, - 0x04, 0x70, 0x6f, 0x64, 0x73, 0x22, 0x4d, 0x0a, 0x19, 0x4d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x12, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x32, 0x83, 0x03, 0x0a, 0x0e, 0x51, 0x75, 0x61, 0x72, 0x6b, 0x43, 0x4d, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x08, 0x54, 0x65, 0x73, 0x74, 0x50, - 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, - 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x1a, 0x1f, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, - 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, - 0x64, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x71, 0x75, 0x61, - 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x09, 0x57, 0x61, 0x74, - 0x63, 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x25, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x3c, 0x0a, 0x0e, 0x50, 0x6f, 0x64, 0x4c, 0x69, 0x73, + 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x70, 0x6f, 0x64, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, + 0x73, 0x76, 0x63, 0x2e, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x04, + 0x70, 0x6f, 0x64, 0x73, 0x22, 0x4d, 0x0a, 0x19, 0x4d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x30, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x12, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x32, 0x83, 0x03, 0x0a, 0x0e, 0x51, 0x75, 0x61, 0x72, 0x6b, 0x43, 0x4d, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x08, 0x54, 0x65, 0x73, 0x74, 0x50, 0x69, + 0x6e, 0x67, 0x12, 0x1e, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, + 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x1a, 0x1f, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, + 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, + 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x71, 0x75, 0x61, 0x72, + 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x09, 0x57, 0x61, 0x74, 0x63, + 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x25, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, + 0x76, 0x63, 0x2e, 0x4d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x17, 0x2e, 0x71, + 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3f, 0x0a, 0x07, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x6f, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x71, + 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x50, 0x6f, 0x64, 0x4c, 0x69, 0x73, + 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x08, 0x57, 0x61, + 0x74, 0x63, 0x68, 0x50, 0x6f, 0x64, 0x12, 0x25, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x17, 0x2e, - 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3f, 0x0a, 0x07, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x6f, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, - 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x50, 0x6f, 0x64, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x08, 0x57, - 0x61, 0x74, 0x63, 0x68, 0x50, 0x6f, 0x64, 0x12, 0x25, 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, - 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x4d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x16, - 0x2e, 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x50, 0x6f, 0x64, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x42, 0x0a, 0x5a, 0x08, 0x70, 0x6b, - 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x16, 0x2e, + 0x71, 0x75, 0x61, 0x72, 0x6b, 0x63, 0x6d, 0x73, 0x76, 0x63, 0x2e, 0x50, 0x6f, 0x64, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x42, 0x0a, 0x5a, 0x08, 0x70, 0x6b, 0x67, + 0x2f, 0x67, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/grpc/quarkcmsvc.proto b/pkg/grpc/quarkcmsvc.proto index 1e39bd8..779a8d1 100644 --- a/pkg/grpc/quarkcmsvc.proto +++ b/pkg/grpc/quarkcmsvc.proto @@ -44,6 +44,7 @@ message NodeMessage { string ip = 3; int64 creation_timestamp = 4; int32 resource_version = 5; + string event_type = 6; } message NodeListMessage { @@ -55,6 +56,7 @@ message PodMessage { string ip = 2; string node_name = 3; int32 resource_version = 4; + string event_type = 5; } message PodListMessage { diff --git a/pkg/objects/nodeeventobject.go b/pkg/objects/nodeeventobject.go new file mode 100644 index 0000000..a76c7b5 --- /dev/null +++ b/pkg/objects/nodeeventobject.go @@ -0,0 +1,23 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package objects + +type NodeEventObject struct { + ResourceVersion int + EventType string + NodeObject NodeObject +} diff --git a/pkg/objects/podeventobject.go b/pkg/objects/podeventobject.go new file mode 100644 index 0000000..83f6714 --- /dev/null +++ b/pkg/objects/podeventobject.go @@ -0,0 +1,23 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package objects + +type PodEventObject struct { + ResourceVersion int + EventType string + PodObject PodObject +} diff --git a/quarkcmclient/src/rdma_ctrlconn.rs b/quarkcmclient/src/rdma_ctrlconn.rs index a334797..1a8c212 100644 --- a/quarkcmclient/src/rdma_ctrlconn.rs +++ b/quarkcmclient/src/rdma_ctrlconn.rs @@ -24,6 +24,8 @@ pub struct CtrlInfo { // pods: pod ip --> Pod pub pods: Mutex>, + + pub exiting: Mutex } impl Default for CtrlInfo { @@ -31,6 +33,7 @@ impl Default for CtrlInfo { return Self { nodes: Mutex::>::new(HashMap::::new()), pods: Mutex::>::new(HashMap::::new()), + exiting: Mutex::::new(false), }; } } diff --git a/quarkcmclient/src/svc_client/pod_informer.rs b/quarkcmclient/src/svc_client/pod_informer.rs index dcf7768..58bed0f 100644 --- a/quarkcmclient/src/svc_client/pod_informer.rs +++ b/quarkcmclient/src/svc_client/pod_informer.rs @@ -19,6 +19,7 @@ use crate::rdma_ctrlconn::*; use svc_client::quark_cm_service_client::QuarkCmServiceClient; use svc_client::MaxResourceVersionMessage; use tonic::Request; +use tokio::time::*; pub mod svc_client { tonic::include_proto!("quarkcmsvc"); @@ -63,19 +64,35 @@ impl PodInformer { impl PodInformer { pub async fn run(&mut self) -> Result<(), Box> { - let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; + loop { + let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; - let mut pod_stream = client - .watch_pod(Request::new(MaxResourceVersionMessage { - // max_resource_version: self.max_resource_version, - max_resource_version: 0, - })) - .await? - .into_inner(); + let mut pod_stream = client + .watch_pod(Request::new(MaxResourceVersionMessage { + max_resource_version: self.max_resource_version, + // max_resource_version: 0, + })) + .await? + .into_inner(); + + while let Some(pod_message) = pod_stream.message().await? { + println!("Received Pod {:?}", pod_message); + } - while let Some(pod_message) = pod_stream.message().await? { - println!("Received Pod {:?}", pod_message); + if *RDMA_CTLINFO.exiting.lock() { + break; + } else { + println!("Wait 1 second for next iteration of watching pod."); + sleep(Duration::from_secs(1)).await; + } } + Ok(()) } } + +impl PodInformer { + fn handle(&mut self) { + + } +} From bd9a6e10542c3c62004ab94d3ee8fff706ab5751 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Mon, 18 Apr 2022 19:11:14 +0000 Subject: [PATCH 19/24] Partially implement pod handle in rs --- quarkcmclient/src/constants.rs | 24 ++++++++++++++++++++ quarkcmclient/src/main.rs | 1 + quarkcmclient/src/svc_client/pod_informer.rs | 24 ++++++++++++++++---- 3 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 quarkcmclient/src/constants.rs diff --git a/quarkcmclient/src/constants.rs b/quarkcmclient/src/constants.rs new file mode 100644 index 0000000..4ee4e71 --- /dev/null +++ b/quarkcmclient/src/constants.rs @@ -0,0 +1,24 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// #[derive(Debug)] +// pub struct Constants { +// pub const EVENT_TYPE_SET: string = "set" +// pub const EVENT_TYPE_DELETE: string = "delete" +// } + +pub const EVENT_TYPE_SET: &str = "set"; +pub const EVENT_TYPE_DELETE: &str = "delete"; \ No newline at end of file diff --git a/quarkcmclient/src/main.rs b/quarkcmclient/src/main.rs index d6276a7..7f9e51a 100644 --- a/quarkcmclient/src/main.rs +++ b/quarkcmclient/src/main.rs @@ -15,6 +15,7 @@ limitations under the License. */ pub mod rdma_ctrlconn; +pub mod constants; mod svc_client; //use svc_client::client::Client; diff --git a/quarkcmclient/src/svc_client/pod_informer.rs b/quarkcmclient/src/svc_client/pod_informer.rs index 58bed0f..266e9c1 100644 --- a/quarkcmclient/src/svc_client/pod_informer.rs +++ b/quarkcmclient/src/svc_client/pod_informer.rs @@ -14,10 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -use super::super::RDMA_CTLINFO; +use crate::RDMA_CTLINFO; +use crate::constants::*; use crate::rdma_ctrlconn::*; use svc_client::quark_cm_service_client::QuarkCmServiceClient; use svc_client::MaxResourceVersionMessage; +use svc_client::PodMessage; use tonic::Request; use tokio::time::*; @@ -38,7 +40,6 @@ impl PodInformer { let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; let ref pods_message = client.list_pod(()).await?.into_inner().pods; - println!("All pods: {:#?}", pods_message); if pods_message.len() > 0 { let mut pods_map = RDMA_CTLINFO.pods.lock(); @@ -92,7 +93,22 @@ impl PodInformer { } impl PodInformer { - fn handle(&mut self) { - + fn handle(&mut self, pod_message: PodMessage) { + let ip = pod_message.ip.clone(); // todo change ip to int, then don't need these clone + if pod_message.event_type == EVENT_TYPE_SET { + let pod = Pod { + key: pod_message.key.clone(), + ip: ip.clone(), + node_name: pod_message.node_name.clone(), + resource_version: pod_message.resource_version, + }; + let mut pods_map = RDMA_CTLINFO.pods.lock(); + pods_map.insert(ip.clone(), pod); + if pod_message.resource_version > self.max_resource_version { + self.max_resource_version = pod_message.resource_version; + } + } else if pod_message.event_type == EVENT_TYPE_DELETE { + + } } } From 0e0bc2b607cd4b3d2232fa5abcde94e84d508a02 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Mon, 18 Apr 2022 19:42:26 +0000 Subject: [PATCH 20/24] Change ip from string to uint32 --- pkg/grpc/quarkcmsvc.go | 13 +++++++++---- pkg/grpc/quarkcmsvc.pb.go | 16 ++++++++-------- pkg/grpc/quarkcmsvc.proto | 4 ++-- quarkcmclient/src/rdma_ctrlconn.rs | 12 ++++++------ quarkcmclient/src/svc_client/pod_informer.rs | 10 +++++----- 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/pkg/grpc/quarkcmsvc.go b/pkg/grpc/quarkcmsvc.go index 9db03d1..85a866c 100644 --- a/pkg/grpc/quarkcmsvc.go +++ b/pkg/grpc/quarkcmsvc.go @@ -18,6 +18,7 @@ package grpc import ( context "context" + "encoding/binary" "encoding/json" "flag" "fmt" @@ -70,7 +71,7 @@ func (s *server) ListNode(ctx context.Context, in *emptypb.Empty) (*NodeListMess nodeMessages = append(nodeMessages, &NodeMessage{ Name: nodeEventObject.NodeObject.Name, Hostname: nodeEventObject.NodeObject.Hostname, - Ip: nodeEventObject.NodeObject.IP, + Ip: convertIP(nodeEventObject.NodeObject.IP), CreationTimestamp: nodeEventObject.NodeObject.CreationTimestamp, ResourceVersion: int32(nodeEventObject.ResourceVersion), EventType: nodeEventObject.EventType, @@ -86,7 +87,7 @@ func (s *server) WatchNode(maxResourceVersionMessage *MaxResourceVersionMessage, nodeMessage := &NodeMessage{ Name: nodeEventObject.NodeObject.Name, Hostname: nodeEventObject.NodeObject.Hostname, - Ip: nodeEventObject.NodeObject.IP, + Ip: convertIP(nodeEventObject.NodeObject.IP), CreationTimestamp: nodeEventObject.NodeObject.CreationTimestamp, ResourceVersion: int32(nodeEventObject.ResourceVersion), EventType: nodeEventObject.EventType, @@ -108,7 +109,7 @@ func (s *server) ListPod(ctx context.Context, in *emptypb.Empty) (*PodListMessag podEventObject := podEventObjects[i] podMessages = append(podMessages, &PodMessage{ Key: podEventObject.PodObject.Key, - Ip: podEventObject.PodObject.IP, + Ip: convertIP(podEventObject.PodObject.IP), NodeName: podEventObject.PodObject.NodeName, ResourceVersion: int32(podEventObject.ResourceVersion), EventType: podEventObject.EventType, @@ -123,7 +124,7 @@ func (s *server) WatchPod(maxResourceVersionMessage *MaxResourceVersionMessage, for _, podEventObject := range podEventObjects { podMessage := &PodMessage{ Key: podEventObject.PodObject.Key, - Ip: podEventObject.PodObject.IP, + Ip: convertIP(podEventObject.PodObject.IP), NodeName: podEventObject.PodObject.NodeName, ResourceVersion: int32(podEventObject.ResourceVersion), EventType: podEventObject.EventType, @@ -134,3 +135,7 @@ func (s *server) WatchPod(maxResourceVersionMessage *MaxResourceVersionMessage, } return nil } + +func convertIP(ip string) uint32 { + return binary.BigEndian.Uint32(net.ParseIP(ip).To4()) +} diff --git a/pkg/grpc/quarkcmsvc.pb.go b/pkg/grpc/quarkcmsvc.pb.go index bce2edc..420d4d4 100644 --- a/pkg/grpc/quarkcmsvc.pb.go +++ b/pkg/grpc/quarkcmsvc.pb.go @@ -137,7 +137,7 @@ type NodeMessage struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` - Ip string `protobuf:"bytes,3,opt,name=ip,proto3" json:"ip,omitempty"` + Ip uint32 `protobuf:"varint,3,opt,name=ip,proto3" json:"ip,omitempty"` CreationTimestamp int64 `protobuf:"varint,4,opt,name=creation_timestamp,json=creationTimestamp,proto3" json:"creation_timestamp,omitempty"` ResourceVersion int32 `protobuf:"varint,5,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` EventType string `protobuf:"bytes,6,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"` @@ -189,11 +189,11 @@ func (x *NodeMessage) GetHostname() string { return "" } -func (x *NodeMessage) GetIp() string { +func (x *NodeMessage) GetIp() uint32 { if x != nil { return x.Ip } - return "" + return 0 } func (x *NodeMessage) GetCreationTimestamp() int64 { @@ -270,7 +270,7 @@ type PodMessage struct { unknownFields protoimpl.UnknownFields Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Ip string `protobuf:"bytes,2,opt,name=ip,proto3" json:"ip,omitempty"` + Ip uint32 `protobuf:"varint,2,opt,name=ip,proto3" json:"ip,omitempty"` NodeName string `protobuf:"bytes,3,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"` ResourceVersion int32 `protobuf:"varint,4,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` EventType string `protobuf:"bytes,5,opt,name=event_type,json=eventType,proto3" json:"event_type,omitempty"` @@ -315,11 +315,11 @@ func (x *PodMessage) GetKey() string { return "" } -func (x *PodMessage) GetIp() string { +func (x *PodMessage) GetIp() uint32 { if x != nil { return x.Ip } - return "" + return 0 } func (x *PodMessage) GetNodeName() string { @@ -455,7 +455,7 @@ var file_pkg_grpc_quarkcmsvc_proto_rawDesc = []byte{ 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x70, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, @@ -470,7 +470,7 @@ var file_pkg_grpc_quarkcmsvc_proto_rawDesc = []byte{ 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x95, 0x01, 0x0a, 0x0a, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, diff --git a/pkg/grpc/quarkcmsvc.proto b/pkg/grpc/quarkcmsvc.proto index 779a8d1..a4e6353 100644 --- a/pkg/grpc/quarkcmsvc.proto +++ b/pkg/grpc/quarkcmsvc.proto @@ -41,7 +41,7 @@ message TestResponseMessage { message NodeMessage { string name = 1; string hostname = 2; - string ip = 3; + uint32 ip = 3; int64 creation_timestamp = 4; int32 resource_version = 5; string event_type = 6; @@ -53,7 +53,7 @@ message NodeListMessage { message PodMessage { string key = 1; - string ip = 2; + uint32 ip = 2; string node_name = 3; int32 resource_version = 4; string event_type = 5; diff --git a/quarkcmclient/src/rdma_ctrlconn.rs b/quarkcmclient/src/rdma_ctrlconn.rs index 1a8c212..83a3a88 100644 --- a/quarkcmclient/src/rdma_ctrlconn.rs +++ b/quarkcmclient/src/rdma_ctrlconn.rs @@ -20,10 +20,10 @@ use std::collections::HashMap; #[derive(Debug)] pub struct CtrlInfo { // nodes: node ip --> Node - pub nodes: Mutex>, + pub nodes: Mutex>, // pods: pod ip --> Pod - pub pods: Mutex>, + pub pods: Mutex>, pub exiting: Mutex } @@ -31,8 +31,8 @@ pub struct CtrlInfo { impl Default for CtrlInfo { fn default() -> Self { return Self { - nodes: Mutex::>::new(HashMap::::new()), - pods: Mutex::>::new(HashMap::::new()), + nodes: Mutex::>::new(HashMap::::new()), + pods: Mutex::>::new(HashMap::::new()), exiting: Mutex::::new(false), }; } @@ -42,7 +42,7 @@ impl Default for CtrlInfo { pub struct Node { pub name: String, pub hostname: String, - pub ip: String, + pub ip: u32, pub timestamp: i64, pub resource_version: i32, } @@ -50,7 +50,7 @@ pub struct Node { #[derive(Debug)] pub struct Pod { pub key: String, - pub ip: String, + pub ip: u32, pub node_name: String, pub resource_version: i32, } diff --git a/quarkcmclient/src/svc_client/pod_informer.rs b/quarkcmclient/src/svc_client/pod_informer.rs index 266e9c1..02e3571 100644 --- a/quarkcmclient/src/svc_client/pod_informer.rs +++ b/quarkcmclient/src/svc_client/pod_informer.rs @@ -46,11 +46,11 @@ impl PodInformer { for pod_message in pods_message { let pod = Pod { key: pod_message.key.clone(), - ip: pod_message.ip.clone(), + ip: pod_message.ip, node_name: pod_message.node_name.clone(), resource_version: pod_message.resource_version, }; - pods_map.insert(pod_message.ip.clone(), pod); + pods_map.insert(pod_message.ip, pod); if pod_message.resource_version > informer.max_resource_version { informer.max_resource_version = pod_message.resource_version; } @@ -94,16 +94,16 @@ impl PodInformer { impl PodInformer { fn handle(&mut self, pod_message: PodMessage) { - let ip = pod_message.ip.clone(); // todo change ip to int, then don't need these clone + let ip = pod_message.ip; if pod_message.event_type == EVENT_TYPE_SET { let pod = Pod { key: pod_message.key.clone(), - ip: ip.clone(), + ip: ip, node_name: pod_message.node_name.clone(), resource_version: pod_message.resource_version, }; let mut pods_map = RDMA_CTLINFO.pods.lock(); - pods_map.insert(ip.clone(), pod); + pods_map.insert(ip, pod); if pod_message.resource_version > self.max_resource_version { self.max_resource_version = pod_message.resource_version; } From 003d3af94931afff86f71a4410e6dc6c2bf0f616 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Tue, 19 Apr 2022 18:14:48 +0000 Subject: [PATCH 21/24] Implement node informer --- quarkcmclient/src/constants.rs | 4 +- quarkcmclient/src/main.rs | 34 +++--- quarkcmclient/src/svc_client/client.rs | 71 ------------ quarkcmclient/src/svc_client/mod.rs | 5 +- quarkcmclient/src/svc_client/node_informer.rs | 109 ++++++++++++++++++ quarkcmclient/src/svc_client/pod_informer.rs | 43 ++++--- 6 files changed, 152 insertions(+), 114 deletions(-) delete mode 100644 quarkcmclient/src/svc_client/client.rs create mode 100644 quarkcmclient/src/svc_client/node_informer.rs diff --git a/quarkcmclient/src/constants.rs b/quarkcmclient/src/constants.rs index 4ee4e71..8727f40 100644 --- a/quarkcmclient/src/constants.rs +++ b/quarkcmclient/src/constants.rs @@ -21,4 +21,6 @@ limitations under the License. // } pub const EVENT_TYPE_SET: &str = "set"; -pub const EVENT_TYPE_DELETE: &str = "delete"; \ No newline at end of file +pub const EVENT_TYPE_DELETE: &str = "delete"; + +pub const GRPC_SERVER_ADDRESS: &str = "http://[::1]:51051"; \ No newline at end of file diff --git a/quarkcmclient/src/main.rs b/quarkcmclient/src/main.rs index 7f9e51a..d4d9a76 100644 --- a/quarkcmclient/src/main.rs +++ b/quarkcmclient/src/main.rs @@ -21,6 +21,7 @@ mod svc_client; //use svc_client::client::Client; use crate::rdma_ctrlconn::*; use svc_client::pod_informer::PodInformer; +use svc_client::node_informer::NodeInformer; use lazy_static::lazy_static; @@ -30,25 +31,26 @@ lazy_static! { #[tokio::main] async fn main() -> Result<(), Box> { - //Client::init().await?; - //PodInformer::run().await?; let mut pod_informer = PodInformer::new().await?; - tokio::join!( + let mut node_informer = NodeInformer::new().await?; + // tokio::join!( + // pod_informer.run(), + // node_informer.run(), + // ); + let (pod_informer_result, node_informer_result) = tokio::join!( pod_informer.run(), - sleep_then_print(1), - sleep_then_print(2), + node_informer.run(), ); - //pod_informer.run().await?; - println!("ok"); + match pod_informer_result { + Err(e) => println!("Pod informer error: {:?}", e), + _ => (), + } + match node_informer_result { + Err(e) => println!("Node informer error: {:?}", e), + _ => (), + } + + println!("Exit!"); Ok(()) } - -async fn sleep_then_print(timer: i32) { - println!("Start timer {}.", timer); - - tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; -// ^ execution can be paused here - - println!("Timer {} done.", timer); -} diff --git a/quarkcmclient/src/svc_client/client.rs b/quarkcmclient/src/svc_client/client.rs deleted file mode 100644 index 9aa8e0a..0000000 --- a/quarkcmclient/src/svc_client/client.rs +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright 2022 quarkcm Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -use svc_client::quark_cm_service_client::QuarkCmServiceClient; -use svc_client::MaxResourceVersionMessage; -use svc_client::TestRequestMessage; -use tonic::Request; - -pub mod svc_client { - tonic::include_proto!("quarkcmsvc"); -} - -pub struct Client { -} - -impl Client { - pub async fn init() -> Result<(), Box> { - let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; - - let mut name = String::new(); - match hostname::get()?.into_string() { - Ok(n) => name = n, - _ => {} - }; - let request = tonic::Request::new(TestRequestMessage { client_name: name }); - let response = client.test_ping(request).await?; - println!("TestPing: {:?}", response); - - let all_pods = client.list_pod(()).await?; - println!("All pods: {:?}", all_pods); - - let all_nodes = client.list_node(()).await?; - println!("All nodes: {:?}", all_nodes); - - let mut pod_stream = client - .watch_pod(Request::new(MaxResourceVersionMessage { - max_resource_version: 0, - })) - .await? - .into_inner(); - - while let Some(pod_message) = pod_stream.message().await? { - println!("Received Pod {:?}", pod_message); - } - - let mut node_stream = client - .watch_node(Request::new(MaxResourceVersionMessage { - max_resource_version: 0, - })) - .await? - .into_inner(); - - while let Some(node_message) = node_stream.message().await? { - println!("Received Node {:?}", node_message); - } - Ok(()) - } -} diff --git a/quarkcmclient/src/svc_client/mod.rs b/quarkcmclient/src/svc_client/mod.rs index e6e3272..bc47bd2 100644 --- a/quarkcmclient/src/svc_client/mod.rs +++ b/quarkcmclient/src/svc_client/mod.rs @@ -14,6 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -pub mod client; - -pub mod pod_informer; \ No newline at end of file +pub mod pod_informer; +pub mod node_informer; \ No newline at end of file diff --git a/quarkcmclient/src/svc_client/node_informer.rs b/quarkcmclient/src/svc_client/node_informer.rs new file mode 100644 index 0000000..9e0af58 --- /dev/null +++ b/quarkcmclient/src/svc_client/node_informer.rs @@ -0,0 +1,109 @@ +/* +Copyright 2022 quarkcm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +use crate::constants::*; +use crate::rdma_ctrlconn::*; +use crate::RDMA_CTLINFO; +use svc_client::quark_cm_service_client::QuarkCmServiceClient; +use svc_client::MaxResourceVersionMessage; +use svc_client::NodeMessage; +use tokio::time::*; +use tonic::Request; + +pub mod svc_client { + tonic::include_proto!("quarkcmsvc"); +} + +#[derive(Debug)] +pub struct NodeInformer { + pub max_resource_version: i32, +} + +impl NodeInformer { + pub async fn new() -> Result> { + let mut informer = Self { + max_resource_version: 0, + }; + let mut client = QuarkCmServiceClient::connect(GRPC_SERVER_ADDRESS).await?; + + let ref nodes_message = client.list_node(()).await?.into_inner().nodes; + if nodes_message.len() > 0 { + for node_message in nodes_message { + informer.handle(node_message); + } + } + + Ok(informer) + } +} + +impl NodeInformer { + pub async fn run(&mut self) -> Result<(), Box> { + let mut client = QuarkCmServiceClient::connect(GRPC_SERVER_ADDRESS).await?; + loop { + let mut node_stream = client + .watch_node(Request::new(MaxResourceVersionMessage { + max_resource_version: self.max_resource_version, + // max_resource_version: 0, + })) + .await? + .into_inner(); + while let Some(node_message) = node_stream.message().await? { + self.handle(&node_message); + } + + if *RDMA_CTLINFO.exiting.lock() { + println!("NodeInformer exit!"); + break; + } else { + // println!("NodeInformer sleeps 1 second for next watch session."); + sleep(Duration::from_secs(1)).await; + } + } + Ok(()) + } +} + +impl NodeInformer { + fn handle(&mut self, node_message: &NodeMessage) { + let ip = node_message.ip; + let mut nodes_map = RDMA_CTLINFO.nodes.lock(); + if node_message.event_type == EVENT_TYPE_SET { + let node = Node { + name: node_message.name.clone(), + hostname: node_message.hostname.clone(), + ip: ip, + timestamp: node_message.creation_timestamp, + resource_version: node_message.resource_version, + }; + nodes_map.insert(ip, node); + if node_message.resource_version > self.max_resource_version { + self.max_resource_version = node_message.resource_version; + } + } else if node_message.event_type == EVENT_TYPE_DELETE { + if nodes_map.contains_key(&ip) { + if nodes_map[&ip].resource_version < node_message.resource_version { + nodes_map.remove(&ip); + } + } + } + if node_message.resource_version > self.max_resource_version { + self.max_resource_version = node_message.resource_version; + } + println!("Handled Node: {:?}", node_message); + println!("Debug: nodes_map len:{} {:?}", nodes_map.len(), nodes_map); + } +} diff --git a/quarkcmclient/src/svc_client/pod_informer.rs b/quarkcmclient/src/svc_client/pod_informer.rs index 02e3571..d9e6e99 100644 --- a/quarkcmclient/src/svc_client/pod_informer.rs +++ b/quarkcmclient/src/svc_client/pod_informer.rs @@ -37,26 +37,13 @@ impl PodInformer { let mut informer = Self { max_resource_version: 0, }; - let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; + let mut client = QuarkCmServiceClient::connect(GRPC_SERVER_ADDRESS).await?; let ref pods_message = client.list_pod(()).await?.into_inner().pods; if pods_message.len() > 0 { - let mut pods_map = RDMA_CTLINFO.pods.lock(); - for pod_message in pods_message { - let pod = Pod { - key: pod_message.key.clone(), - ip: pod_message.ip, - node_name: pod_message.node_name.clone(), - resource_version: pod_message.resource_version, - }; - pods_map.insert(pod_message.ip, pod); - if pod_message.resource_version > informer.max_resource_version { - informer.max_resource_version = pod_message.resource_version; - } + informer.handle(pod_message); } - println!("max_resource_version: {}", informer.max_resource_version); - println!("RDMA_CTLINFO {:#?}", pods_map); } Ok(informer) @@ -65,9 +52,8 @@ impl PodInformer { impl PodInformer { pub async fn run(&mut self) -> Result<(), Box> { - loop { - let mut client = QuarkCmServiceClient::connect("http://[::1]:51051").await?; - + let mut client = QuarkCmServiceClient::connect(GRPC_SERVER_ADDRESS).await?; + loop { let mut pod_stream = client .watch_pod(Request::new(MaxResourceVersionMessage { max_resource_version: self.max_resource_version, @@ -77,13 +63,14 @@ impl PodInformer { .into_inner(); while let Some(pod_message) = pod_stream.message().await? { - println!("Received Pod {:?}", pod_message); + self.handle(&pod_message); } if *RDMA_CTLINFO.exiting.lock() { + println!("PodInformer exit!"); break; } else { - println!("Wait 1 second for next iteration of watching pod."); + // println!("PodInformer sleeps 1 second for next watch session."); sleep(Duration::from_secs(1)).await; } } @@ -93,8 +80,9 @@ impl PodInformer { } impl PodInformer { - fn handle(&mut self, pod_message: PodMessage) { + fn handle(&mut self, pod_message: &PodMessage) { let ip = pod_message.ip; + let mut pods_map = RDMA_CTLINFO.pods.lock(); if pod_message.event_type == EVENT_TYPE_SET { let pod = Pod { key: pod_message.key.clone(), @@ -102,13 +90,22 @@ impl PodInformer { node_name: pod_message.node_name.clone(), resource_version: pod_message.resource_version, }; - let mut pods_map = RDMA_CTLINFO.pods.lock(); + pods_map.insert(ip, pod); if pod_message.resource_version > self.max_resource_version { self.max_resource_version = pod_message.resource_version; } } else if pod_message.event_type == EVENT_TYPE_DELETE { - + if pods_map.contains_key(&ip) { + if pods_map[&ip].resource_version < pod_message.resource_version { + pods_map.remove(&ip); + } + } + } + if pod_message.resource_version > self.max_resource_version { + self.max_resource_version = pod_message.resource_version; } + println!("Handled Pod: {:?}", pod_message); + println!("Debug: pods_map len:{} {:?}", pods_map.len(), pods_map); } } From 6f22257e015d184be0224af4b4dd5f092d0776f3 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Wed, 20 Apr 2022 00:20:34 +0000 Subject: [PATCH 22/24] Ignore error for watch --- quarkcmclient/src/main.rs | 22 +++------ quarkcmclient/src/svc_client/node_informer.rs | 33 ++++++++----- quarkcmclient/src/svc_client/pod_informer.rs | 46 +++++++++++-------- 3 files changed, 54 insertions(+), 47 deletions(-) diff --git a/quarkcmclient/src/main.rs b/quarkcmclient/src/main.rs index d4d9a76..b5027d9 100644 --- a/quarkcmclient/src/main.rs +++ b/quarkcmclient/src/main.rs @@ -14,14 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -pub mod rdma_ctrlconn; pub mod constants; +pub mod rdma_ctrlconn; mod svc_client; -//use svc_client::client::Client; use crate::rdma_ctrlconn::*; -use svc_client::pod_informer::PodInformer; use svc_client::node_informer::NodeInformer; +use svc_client::pod_informer::PodInformer; use lazy_static::lazy_static; @@ -31,26 +30,19 @@ lazy_static! { #[tokio::main] async fn main() -> Result<(), Box> { - let mut pod_informer = PodInformer::new().await?; let mut node_informer = NodeInformer::new().await?; - // tokio::join!( - // pod_informer.run(), - // node_informer.run(), - // ); - let (pod_informer_result, node_informer_result) = tokio::join!( - pod_informer.run(), - node_informer.run(), - ); - match pod_informer_result { + + let (pod_informer_result, node_informer_result) = + tokio::join!(pod_informer.run(), node_informer.run(),); + match pod_informer_result { Err(e) => println!("Pod informer error: {:?}", e), _ => (), } - match node_informer_result { + match node_informer_result { Err(e) => println!("Node informer error: {:?}", e), _ => (), } - println!("Exit!"); Ok(()) } diff --git a/quarkcmclient/src/svc_client/node_informer.rs b/quarkcmclient/src/svc_client/node_informer.rs index 9e0af58..7866c8d 100644 --- a/quarkcmclient/src/svc_client/node_informer.rs +++ b/quarkcmclient/src/svc_client/node_informer.rs @@ -52,17 +52,12 @@ impl NodeInformer { impl NodeInformer { pub async fn run(&mut self) -> Result<(), Box> { - let mut client = QuarkCmServiceClient::connect(GRPC_SERVER_ADDRESS).await?; loop { - let mut node_stream = client - .watch_node(Request::new(MaxResourceVersionMessage { - max_resource_version: self.max_resource_version, - // max_resource_version: 0, - })) - .await? - .into_inner(); - while let Some(node_message) = node_stream.message().await? { - self.handle(&node_message); + match self.run_watch().await { + Ok(_) => {} + Err(e) => { + println!("Node watch error: {:?}", e); + } } if *RDMA_CTLINFO.exiting.lock() { @@ -75,9 +70,23 @@ impl NodeInformer { } Ok(()) } -} -impl NodeInformer { + async fn run_watch(&mut self) -> Result<(), Box> { + let mut client = QuarkCmServiceClient::connect(GRPC_SERVER_ADDRESS).await?; + let mut node_stream = client + .watch_node(Request::new(MaxResourceVersionMessage { + max_resource_version: self.max_resource_version, + // max_resource_version: 0, + })) + .await? + .into_inner(); + + while let Some(node_message) = node_stream.message().await? { + self.handle(&node_message); + } + Ok(()) + } + fn handle(&mut self, node_message: &NodeMessage) { let ip = node_message.ip; let mut nodes_map = RDMA_CTLINFO.nodes.lock(); diff --git a/quarkcmclient/src/svc_client/pod_informer.rs b/quarkcmclient/src/svc_client/pod_informer.rs index d9e6e99..7db7dc6 100644 --- a/quarkcmclient/src/svc_client/pod_informer.rs +++ b/quarkcmclient/src/svc_client/pod_informer.rs @@ -14,14 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -use crate::RDMA_CTLINFO; use crate::constants::*; use crate::rdma_ctrlconn::*; +use crate::RDMA_CTLINFO; use svc_client::quark_cm_service_client::QuarkCmServiceClient; use svc_client::MaxResourceVersionMessage; use svc_client::PodMessage; -use tonic::Request; use tokio::time::*; +use tonic::Request; pub mod svc_client { tonic::include_proto!("quarkcmsvc"); @@ -52,18 +52,12 @@ impl PodInformer { impl PodInformer { pub async fn run(&mut self) -> Result<(), Box> { - let mut client = QuarkCmServiceClient::connect(GRPC_SERVER_ADDRESS).await?; - loop { - let mut pod_stream = client - .watch_pod(Request::new(MaxResourceVersionMessage { - max_resource_version: self.max_resource_version, - // max_resource_version: 0, - })) - .await? - .into_inner(); - - while let Some(pod_message) = pod_stream.message().await? { - self.handle(&pod_message); + loop { + match self.run_watch().await { + Ok(_) => {} + Err(e) => { + println!("Pod watch error: {:?}", e); + } } if *RDMA_CTLINFO.exiting.lock() { @@ -74,12 +68,25 @@ impl PodInformer { sleep(Duration::from_secs(1)).await; } } - Ok(()) } -} -impl PodInformer { + async fn run_watch(&mut self) -> Result<(), Box> { + let mut client = QuarkCmServiceClient::connect(GRPC_SERVER_ADDRESS).await?; + let mut pod_stream = client + .watch_pod(Request::new(MaxResourceVersionMessage { + max_resource_version: self.max_resource_version, + // max_resource_version: 0, + })) + .await? + .into_inner(); + + while let Some(pod_message) = pod_stream.message().await? { + self.handle(&pod_message); + } + Ok(()) + } + fn handle(&mut self, pod_message: &PodMessage) { let ip = pod_message.ip; let mut pods_map = RDMA_CTLINFO.pods.lock(); @@ -90,7 +97,6 @@ impl PodInformer { node_name: pod_message.node_name.clone(), resource_version: pod_message.resource_version, }; - pods_map.insert(ip, pod); if pod_message.resource_version > self.max_resource_version { self.max_resource_version = pod_message.resource_version; @@ -99,8 +105,8 @@ impl PodInformer { if pods_map.contains_key(&ip) { if pods_map[&ip].resource_version < pod_message.resource_version { pods_map.remove(&ip); - } - } + } + } } if pod_message.resource_version > self.max_resource_version { self.max_resource_version = pod_message.resource_version; From 9b075ca39ca1ac3ff4189a5245ebb09fc43e7dfd Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Wed, 20 Apr 2022 18:54:08 +0000 Subject: [PATCH 23/24] Refine watch --- pkg/datastore/datastore.go | 56 ++++++++++++++--- pkg/grpc/quarkcmsvc.go | 125 ++++++++++++++++++++++++++++++++----- 2 files changed, 158 insertions(+), 23 deletions(-) diff --git a/pkg/datastore/datastore.go b/pkg/datastore/datastore.go index a7ad8f7..d317d30 100644 --- a/pkg/datastore/datastore.go +++ b/pkg/datastore/datastore.go @@ -22,16 +22,21 @@ import ( "github.com/CentaurusInfra/quarkcm/pkg/constants" "github.com/CentaurusInfra/quarkcm/pkg/objects" + "github.com/google/uuid" + "k8s.io/client-go/util/workqueue" "k8s.io/klog" ) type DataStore struct { NodeResourceVersion int - NodeMap map[string]*objects.NodeObject // map[node name] => node object - NodeEventMap map[int]*objects.NodeEventObject // map[resource version] => node event object - PodResourceVersion int - PodMap map[string]*objects.PodObject // map[key] => pod object - PodEventMap map[int]*objects.PodEventObject // map[resource version] => pod event object + NodeMap map[string]*objects.NodeObject // map[node name] => node object + NodeEventMap map[int]*objects.NodeEventObject // map[resource version] => node event object + NodeQueueMap map[uuid.UUID]workqueue.RateLimitingInterface // map[guid] => node queue + + PodResourceVersion int + PodMap map[string]*objects.PodObject // map[key] => pod object + PodEventMap map[int]*objects.PodEventObject // map[resource version] => pod event object + PodQueueMap map[uuid.UUID]workqueue.RateLimitingInterface // map[guid] => pod queue } var lock = &sync.Mutex{} @@ -46,9 +51,12 @@ func Instance() *DataStore { NodeResourceVersion: 0, NodeMap: map[string]*objects.NodeObject{}, NodeEventMap: map[int]*objects.NodeEventObject{}, - PodResourceVersion: 0, - PodMap: map[string]*objects.PodObject{}, - PodEventMap: map[int]*objects.PodEventObject{}, + NodeQueueMap: map[uuid.UUID]workqueue.RateLimitingInterface{}, + + PodResourceVersion: 0, + PodMap: map[string]*objects.PodObject{}, + PodEventMap: map[int]*objects.PodEventObject{}, + PodQueueMap: map[uuid.UUID]workqueue.RateLimitingInterface{}, } } } @@ -101,6 +109,7 @@ func SetNode(name string, nodeHostname string, nodeIP string, creationTimestamp } nodeMap[name] = newNode Instance().NodeEventMap[resourceVersion] = newNodeEvent + EnqueueNode(*newNodeEvent) nodeStr, _ := json.Marshal(nodeMap[name]) klog.Infof("Handling node completed. Node set as %s. Tracking Id: %s", nodeStr, trackingId) @@ -118,6 +127,7 @@ func DeleteNode(name string, trackingId string) { NodeObject: *node, } Instance().NodeEventMap[resourceVersion] = newNodeEvent + EnqueueNode(*newNodeEvent) delete(nodeMap, name) klog.Infof("Handling node completed. Node %s is deleted. Tracking Id: %s", name, trackingId) } @@ -134,6 +144,20 @@ func ListNode(minResourceVersion int) []objects.NodeEventObject { return nodeEvents } +func EnqueueNode(nodeEventObject objects.NodeEventObject) { + for _, queue := range Instance().NodeQueueMap { + queue.Add(nodeEventObject) + } +} + +func AddNodeQueue(key uuid.UUID, queue workqueue.RateLimitingInterface) { + Instance().NodeQueueMap[key] = queue +} + +func RemoveNodeQueue(key uuid.UUID) { + delete(Instance().NodeQueueMap, key) +} + func SetPod(key string, podIP string, nodeName string, trackingId string) { podMap := Instance().PodMap pod, exists := podMap[key] @@ -163,6 +187,7 @@ func SetPod(key string, podIP string, nodeName string, trackingId string) { } podMap[key] = newPod Instance().PodEventMap[resourceVersion] = newPodEvent + EnqueuePod(*newPodEvent) podStr, _ := json.Marshal(podMap[key]) klog.Infof("Handling pod completed. Pod set as %s. Tracking Id: %s", podStr, trackingId) @@ -180,6 +205,7 @@ func DeletePod(key string, trackingId string) { PodObject: *pod, } Instance().PodEventMap[resourceVersion] = newPodEvent + EnqueuePod(*newPodEvent) delete(podMap, key) klog.Infof("Handling pod completed. Pod %s is deleted. Tracking Id: %s", key, trackingId) } @@ -195,3 +221,17 @@ func ListPod(minResourceVersion int) []objects.PodEventObject { } return podEvents } + +func EnqueuePod(podEventObject objects.PodEventObject) { + for _, queue := range Instance().PodQueueMap { + queue.Add(podEventObject) + } +} + +func AddPodQueue(key uuid.UUID, queue workqueue.RateLimitingInterface) { + Instance().PodQueueMap[key] = queue +} + +func RemovePodQueue(key uuid.UUID) { + delete(Instance().PodQueueMap, key) +} diff --git a/pkg/grpc/quarkcmsvc.go b/pkg/grpc/quarkcmsvc.go index 85a866c..d81852d 100644 --- a/pkg/grpc/quarkcmsvc.go +++ b/pkg/grpc/quarkcmsvc.go @@ -25,11 +25,14 @@ import ( "net" "os" + "github.com/google/uuid" "google.golang.org/grpc" emptypb "google.golang.org/protobuf/types/known/emptypb" + "k8s.io/client-go/util/workqueue" "k8s.io/klog" "github.com/CentaurusInfra/quarkcm/pkg/datastore" + "github.com/CentaurusInfra/quarkcm/pkg/objects" ) var ( @@ -82,20 +85,66 @@ func (s *server) ListNode(ctx context.Context, in *emptypb.Empty) (*NodeListMess } func (s *server) WatchNode(maxResourceVersionMessage *MaxResourceVersionMessage, stream QuarkCMService_WatchNodeServer) error { + klog.Info("grpc Service called WatchNode") + + key := uuid.New() + queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) + defer queue.ShutDown() + datastore.AddNodeQueue(key, queue) + defer datastore.RemoveNodeQueue(key) + nodeEventObjects := datastore.ListNode(int(maxResourceVersionMessage.MaxResourceVersion)) for _, nodeEventObject := range nodeEventObjects { - nodeMessage := &NodeMessage{ - Name: nodeEventObject.NodeObject.Name, - Hostname: nodeEventObject.NodeObject.Hostname, - Ip: convertIP(nodeEventObject.NodeObject.IP), - CreationTimestamp: nodeEventObject.NodeObject.CreationTimestamp, - ResourceVersion: int32(nodeEventObject.ResourceVersion), - EventType: nodeEventObject.EventType, + if err := sendNodeStream(stream, &nodeEventObject); err != nil { + return err + } + } + + for { + exit, err := processNextNode(queue, stream) + if exit { + break } - if err := stream.Send(nodeMessage); err != nil { + if err != nil { return err } } + + return nil +} + +func processNextNode(queue workqueue.RateLimitingInterface, stream QuarkCMService_WatchNodeServer) (bool, error) { + nodeEventObject, exit := dequeueNode(queue) + if exit { + return exit, nil + } + return exit, sendNodeStream(stream, nodeEventObject) +} + +func dequeueNode(queue workqueue.RateLimitingInterface) (*objects.NodeEventObject, bool) { + queueItem, exit := queue.Get() + if exit { + return nil, exit + } + nodeEventObject := queueItem.(objects.NodeEventObject) + queue.Forget(queueItem) + // defer queue.Done(queueItem) + queue.Done(queueItem) + return &nodeEventObject, exit +} + +func sendNodeStream(stream QuarkCMService_WatchNodeServer, nodeEventObject *objects.NodeEventObject) error { + nodeMessage := &NodeMessage{ + Name: nodeEventObject.NodeObject.Name, + Hostname: nodeEventObject.NodeObject.Hostname, + Ip: convertIP(nodeEventObject.NodeObject.IP), + CreationTimestamp: nodeEventObject.NodeObject.CreationTimestamp, + ResourceVersion: int32(nodeEventObject.ResourceVersion), + EventType: nodeEventObject.EventType, + } + if err := stream.Send(nodeMessage); err != nil { + return err + } return nil } @@ -120,19 +169,65 @@ func (s *server) ListPod(ctx context.Context, in *emptypb.Empty) (*PodListMessag } func (s *server) WatchPod(maxResourceVersionMessage *MaxResourceVersionMessage, stream QuarkCMService_WatchPodServer) error { + klog.Info("grpc Service called WatchPod") + + key := uuid.New() + queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) + defer queue.ShutDown() + datastore.AddPodQueue(key, queue) + defer datastore.RemovePodQueue(key) + podEventObjects := datastore.ListPod(int(maxResourceVersionMessage.MaxResourceVersion)) for _, podEventObject := range podEventObjects { - podMessage := &PodMessage{ - Key: podEventObject.PodObject.Key, - Ip: convertIP(podEventObject.PodObject.IP), - NodeName: podEventObject.PodObject.NodeName, - ResourceVersion: int32(podEventObject.ResourceVersion), - EventType: podEventObject.EventType, + if err := sendPodStream(stream, &podEventObject); err != nil { + return err + } + } + + for { + exit, err := processNextPod(queue, stream) + if exit { + break } - if err := stream.Send(podMessage); err != nil { + if err != nil { return err } } + + return nil +} + +func processNextPod(queue workqueue.RateLimitingInterface, stream QuarkCMService_WatchPodServer) (bool, error) { + podEventObject, exit := dequeuePod(queue) + if exit { + return exit, nil + } + return exit, sendPodStream(stream, podEventObject) +} + +func dequeuePod(queue workqueue.RateLimitingInterface) (*objects.PodEventObject, bool) { + queueItem, exit := queue.Get() + if exit { + return nil, exit + } + podEventObject := queueItem.(objects.PodEventObject) + queue.Forget(queueItem) + // defer queue.Done(queueItem) + queue.Done(queueItem) + return &podEventObject, exit +} + +func sendPodStream(stream QuarkCMService_WatchPodServer, podEventObject *objects.PodEventObject) error { + podMessage := &PodMessage{ + Key: podEventObject.PodObject.Key, + Ip: convertIP(podEventObject.PodObject.IP), + NodeName: podEventObject.PodObject.NodeName, + ResourceVersion: int32(podEventObject.ResourceVersion), + EventType: podEventObject.EventType, + } + if err := stream.Send(podMessage); err != nil { + return err + } return nil } From fa1c2a32ee441dd4a711265937730a2d56a8eb83 Mon Sep 17 00:00:00 2001 From: Hong-Chang Date: Fri, 22 Apr 2022 17:23:20 +0000 Subject: [PATCH 24/24] Filter out system pod --- pkg/controller/controller.go | 25 ++++++++++++++++--------- pkg/datastore/datastore.go | 11 +++++++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 1364a05..09771de 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -56,28 +56,32 @@ func Start() { kubeClient = utils.GetClient() } + nodeController := NewNodeController(kubeClient) + nodeStopCh := make(chan struct{}) + defer close(nodeStopCh) + + nodeController.Start(nodeStopCh) // Sync start node controller first, to generating node ip set for filtering pod ip + go nodeController.Wait(nodeStopCh) + podController := NewPodController(kubeClient) podStopCh := make(chan struct{}) defer close(podStopCh) go podController.Run(podStopCh) - nodeController := NewNodeController(kubeClient) - nodeStopCh := make(chan struct{}) - defer close(nodeStopCh) - - go nodeController.Run(nodeStopCh) - sigterm := make(chan os.Signal, 1) signal.Notify(sigterm, syscall.SIGTERM) signal.Notify(sigterm, syscall.SIGINT) <-sigterm } -// Run starts the quarkcm controller func (c *Controller) Run(stopCh <-chan struct{}) { + c.Start(stopCh) + c.Wait(stopCh) +} + +func (c *Controller) Start(stopCh <-chan struct{}) { defer utilruntime.HandleCrash() - defer c.queue.ShutDown() klog.Infof("Starting quarkcm %s controller", c.resourceType) go c.informer.Run(stopCh) @@ -86,9 +90,12 @@ func (c *Controller) Run(stopCh <-chan struct{}) { utilruntime.HandleError(fmt.Errorf("%s controller timed out waiting for caches to sync", c.resourceType)) return } - klog.Infof("quarkcm %s controller synced and ready", c.resourceType) +} +func (c *Controller) Wait(stopCh <-chan struct{}) { + defer utilruntime.HandleCrash() + defer c.queue.ShutDown() wait.Until(c.runWorker, time.Second, stopCh) } diff --git a/pkg/datastore/datastore.go b/pkg/datastore/datastore.go index d317d30..95655cf 100644 --- a/pkg/datastore/datastore.go +++ b/pkg/datastore/datastore.go @@ -32,6 +32,7 @@ type DataStore struct { NodeMap map[string]*objects.NodeObject // map[node name] => node object NodeEventMap map[int]*objects.NodeEventObject // map[resource version] => node event object NodeQueueMap map[uuid.UUID]workqueue.RateLimitingInterface // map[guid] => node queue + NodeIPMap map[string]bool // map[node ip] => not using, this map is used as hashset PodResourceVersion int PodMap map[string]*objects.PodObject // map[key] => pod object @@ -52,6 +53,7 @@ func Instance() *DataStore { NodeMap: map[string]*objects.NodeObject{}, NodeEventMap: map[int]*objects.NodeEventObject{}, NodeQueueMap: map[uuid.UUID]workqueue.RateLimitingInterface{}, + NodeIPMap: map[string]bool{}, PodResourceVersion: 0, PodMap: map[string]*objects.PodObject{}, @@ -111,6 +113,8 @@ func SetNode(name string, nodeHostname string, nodeIP string, creationTimestamp Instance().NodeEventMap[resourceVersion] = newNodeEvent EnqueueNode(*newNodeEvent) + Instance().NodeIPMap[nodeIP] = true + nodeStr, _ := json.Marshal(nodeMap[name]) klog.Infof("Handling node completed. Node set as %s. Tracking Id: %s", nodeStr, trackingId) } @@ -120,6 +124,7 @@ func DeleteNode(name string, trackingId string) { nodeMap := Instance().NodeMap node, exists := nodeMap[name] if exists { + delete(Instance().NodeIPMap, node.IP) resourceVersion := calculateNextNodeResourceVersion() newNodeEvent := &objects.NodeEventObject{ ResourceVersion: resourceVersion, @@ -159,6 +164,12 @@ func RemoveNodeQueue(key uuid.UUID) { } func SetPod(key string, podIP string, nodeName string, trackingId string) { + _, isNodeIP := Instance().NodeIPMap[podIP] + if isNodeIP { + klog.Infof("IP of pod %s is the same as node's ip. Ignore the pod. Tracking Id: %s", key, trackingId) + return + } + podMap := Instance().PodMap pod, exists := podMap[key] changed := false