├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .goreleaser.yml ├── LICENSE ├── Makefile ├── OWNERS ├── README.md ├── examples ├── output │ ├── .gitignore │ └── main.go ├── output_bidi │ ├── .gitignore │ └── main.go ├── output_unix_socket │ ├── .gitignore │ └── main.go ├── output_unix_socket_bidi │ ├── .gitignore │ └── main.go ├── version │ ├── .gitignore │ └── main.go └── version_unix_socket │ ├── .gitignore │ └── main.go ├── go.mod ├── go.sum ├── pkg ├── api │ ├── outputs │ │ ├── mocks │ │ │ └── outputs.go │ │ ├── outputs.pb.go │ │ └── outputs_grpc.pb.go │ ├── schema │ │ └── schema.pb.go │ └── version │ │ ├── mocks │ │ └── version.go │ │ ├── version.pb.go │ │ └── version_grpc.pb.go └── client │ ├── client.go │ ├── client_test.go │ └── example_test.go └── release.md /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 11 | 12 | **What type of PR is this?** 13 | 14 | > Uncomment one (or more) `/kind <>` lines: 15 | 16 | > /kind bug 17 | 18 | > /kind cleanup 19 | 20 | > /kind design 21 | 22 | > /kind documentation 23 | 24 | > /kind failing-test 25 | 26 | > /kind feature 27 | 28 | **Any specific area of the project related to this PR?** 29 | 30 | > Uncomment one (or more) `/area <>` lines: 31 | 32 | > /area api 33 | 34 | > /area client 35 | 36 | > /area tests 37 | 38 | > /area examples 39 | 40 | **What this PR does / why we need it**: 41 | 42 | **Which issue(s) this PR fixes**: 43 | 44 | 49 | 50 | Fixes # 51 | 52 | **Special notes for your reviewer**: 53 | 54 | **Does this PR introduce a user-facing change?**: 55 | 56 | 62 | 63 | ```release-note 64 | 65 | ``` 66 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI build 2 | on: 3 | pull_request: 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 11 | with: 12 | fetch-depth: 0 13 | 14 | - name: Setup Go 15 | uses: actions/setup-go@0caeaed6fd66a828038c2da3c0f662a42862658f # v1 16 | with: 17 | go-version: 1.17 18 | 19 | - name: Test 20 | run: make test 21 | 22 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Release 3 | 4 | on: 5 | push: 6 | tags: 7 | - 'v[0-9]+.[0-9]+.[0-9]+' 8 | 9 | jobs: 10 | release: 11 | runs-on: ubuntu-22.04 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 15 | with: 16 | fetch-depth: 0 17 | 18 | - name: Setup Go 19 | uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3 20 | with: 21 | go-version: 1.14 22 | 23 | - name: Run GoReleaser 24 | uses: goreleaser/goreleaser-action@b508e2e3ef3b19d4e4146d4f8fb3ba9db644a757 # v3 25 | with: 26 | distribution: goreleaser 27 | version: v1.10.3 28 | args: release --rm-dist --timeout 60m 29 | env: 30 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | **/*.proto -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | project_name: client-go 2 | build: 3 | skip: true 4 | release: 5 | github: 6 | prerelease: auto -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | Copyright 2019 The Falco Authors 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL := /bin/bash 2 | 3 | GO ?= $(shell which go) 4 | PROTOC ?= $(shell which protoc) 5 | MOCKGEN ?= $(shell which mockgen) 6 | 7 | ifeq ($(MOCKGEN),) 8 | # keep this in sync with the version of github.com/golang/mock in go.mod 9 | $(shell $(GO) get github.com/golang/mock/mockgen@v1.4.3) 10 | endif 11 | 12 | TEST_FLAGS ?= -v -race 13 | 14 | PROTOS := pkg/api/schema/schema.proto pkg/api/outputs/outputs.proto pkg/api/version/version.proto 15 | PROTO_URLS := https://raw.githubusercontent.com/falcosecurity/falco/master/userspace/falco/schema.proto https://raw.githubusercontent.com/falcosecurity/falco/master/userspace/falco/outputs.proto https://raw.githubusercontent.com/falcosecurity/falco/master/userspace/falco/version.proto 16 | PROTO_SHAS := b9042e3dbde9e8ebecaeeb5cf943ae04c56ee93a80e14cdc42c94d80d69c61fb 8fdd0a921d87908df2731b8b8b40ac9a51d2369bad4351db4a3ad79584deaa61 c57a8a3f37a14ca8f33ce6d26156c9348e716029bca87bf9143807a68b1f31f5 17 | 18 | PROTO_DIRS := $(dir ${PROTOS}) 19 | PROTO_DIRS_INCLUDES := $(patsubst %/, -I %, ${PROTO_DIRS}) 20 | 21 | all: protos mocks 22 | 23 | .PHONY: protos 24 | protos: ${PROTOS} 25 | 26 | # $(1): the proto path 27 | # $(2): the proto URL 28 | # $(3): the proto SHA256 29 | define download_rule 30 | $(1): 31 | @rm -f $(1) 32 | @mkdir -p ${PROTO_DIRS} 33 | @curl --silent -Lo $(1) $(2) 34 | @echo $(3) $(1) | sha256sum -c 35 | @${PROTOC} ${PROTO_DIRS_INCLUDES} $(1) --go_out=paths=source_relative:$(dir $(1)) --go-grpc_out=paths=source_relative:$(dir $(1)) 36 | endef 37 | $(foreach PROTO,$(PROTOS),\ 38 | $(eval $(call download_rule,$(PROTO),$(firstword $(PROTO_URLS)),$(firstword $(PROTO_SHAS))))\ 39 | $(eval PROTO_URLS := $(wordlist 2,$(words $(PROTO_URLS)),$(PROTO_URLS)))\ 40 | $(eval PROTO_SHAS := $(wordlist 2,$(words $(PROTO_SHAS)),$(PROTO_SHAS)))\ 41 | ) 42 | 43 | MOCK_PROTOS := pkg/api/outputs/outputs.proto pkg/api/version/version.proto 44 | MOCK_SYMBOLS := ServiceClient,Service_GetClient,Service_SubClient ServiceClient 45 | 46 | # $(1): the proto path 47 | # $(2): the mock directory 48 | # $(3): the mock filename 49 | # $(4): the symbols to mock 50 | define generate_mock 51 | $(2)/$(3): $(1) protos 52 | @mkdir -p $(2) 53 | $(MOCKGEN) $$(shell cat $(1) | sed -n -e 's/^option go_package = "\(.*\)";/\1/p') $(4) > $(2)/$(3) 54 | endef 55 | $(foreach PROTO,$(MOCK_PROTOS),\ 56 | $(eval $(call generate_mock,$(PROTO),$(dir $(PROTO))mocks,$(patsubst %.proto,%.go,$(notdir $(PROTO))),$(firstword $(MOCK_SYMBOLS))))\ 57 | $(eval MOCK_SYMBOLS := $(wordlist 2,$(words $(MOCK_SYMBOLS)),$(MOCK_SYMBOLS)))\ 58 | ) 59 | 60 | MOCKS := $(join $(dir ${MOCK_PROTOS}),$(patsubst %.proto,mocks/%.go,$(notdir ${MOCK_PROTOS}))) 61 | 62 | .PHONY: mocks 63 | mocks: protos ${MOCKS} 64 | 65 | .PHONY: test 66 | test: 67 | @$(GO) vet ./... 68 | @$(GO) test ${TEST_FLAGS} ./... 69 | 70 | .PHONY: clean 71 | clean: ${PROTO_DIRS} 72 | @rm -rf $^ 73 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - leodido 3 | - leogr 4 | emeritus_approvers: 5 | - fntlnz 6 | - kris-nova 7 | - mfdii 8 | - markyjackson-taulia 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Falco Go Client 2 | 3 | [![Falco Ecosystem Repository](https://github.com/falcosecurity/evolution/blob/main/repos/badges/falco-ecosystem-blue.svg)](https://github.com/falcosecurity/evolution/blob/main/REPOSITORIES.md#ecosystem-scope) [![Incubating](https://img.shields.io/badge/status-incubating-orange?style=for-the-badge)](https://github.com/falcosecurity/evolution/blob/main/REPOSITORIES.md#incubating) 4 | 5 | [![GoDoc](https://godoc.org/github.com/falcosecurity/client-go/pkg/client?status.svg)](https://godoc.org/github.com/falcosecurity/client-go/pkg/client) 6 | 7 | > Go client and SDK for Falco 8 | 9 | Learn more about the gRPC API by reading [the docs](https://falco.org/docs/grpc/). 10 | 11 | ## Install 12 | 13 | ```bash 14 | go get -u github.com/falcosecurity/client-go 15 | ``` 16 | 17 | ## Usage 18 | 19 | ### Network Client creation 20 | 21 | If you are binding the Falco gRPC server to a network socket 22 | with mTLS (mutual TLS authentication) you need this one. Please remember that since this is 23 | enabling mTLS you will need to generate a pair of certificates for this client 24 | specifically and provide the CA certificate. If you need something simpler, 25 | go for the unix socket. 26 | 27 | ```go 28 | package main 29 | 30 | imports( 31 | "context" 32 | "github.com/falcosecurity/client-go/pkg/client" 33 | ) 34 | 35 | func main() { 36 | c, err := client.NewForConfig(context.Background(), &client.Config{ 37 | Hostname: "localhost", 38 | Port: 5060, 39 | CertFile: "/etc/falco/certs/client.crt", 40 | KeyFile: "/etc/falco/certs/client.key", 41 | CARootFile: "/etc/falco/certs/ca.crt", 42 | }) 43 | } 44 | ``` 45 | 46 | ### Unix Socket Client creation 47 | 48 | If you are binding the Falco gRPC server to unix socket, this is what you need. 49 | 50 | ```go 51 | package main 52 | 53 | imports( 54 | "context" 55 | "github.com/falcosecurity/client-go/pkg/client" 56 | ) 57 | 58 | func main() { 59 | c, err := client.NewForConfig(context.Background(), &client.Config{ 60 | UnixSocketPath: "unix:///run/falco/falco.sock", 61 | }) 62 | } 63 | ``` 64 | 65 | ### Falco outputs API 66 | 67 | ```go 68 | outputsClient, err := c.Outputs() 69 | if err != nil { 70 | log.Fatalf("unable to obtain an output client: %v", err) 71 | } 72 | 73 | ctx := context.Background() 74 | fcs, err := outputsClient.Get(ctx, &outputs.Request{}) 75 | if err != nil { 76 | log.Fatalf("could not subscribe: %v", err) 77 | } 78 | 79 | for { 80 | res, err := fcs.Recv() 81 | if err == io.EOF { 82 | break 83 | } 84 | if err != nil { 85 | log.Fatalf("error closing stream after EOF: %v", err) 86 | } 87 | fmt.Printf("rule: %s\n", res.Rule) 88 | } 89 | ``` 90 | 91 | ### Falco version API 92 | 93 | ```go 94 | // Set up a connection to the server. 95 | c, err := client.NewForConfig(context.Background(), &client.Config{ 96 | Hostname: "localhost", 97 | Port: 5060, 98 | CertFile: "/etc/falco/certs/client.crt", 99 | KeyFile: "/etc/falco/certs/client.key", 100 | CARootFile: "/etc/falco/certs/ca.crt", 101 | }) 102 | if err != nil { 103 | log.Fatalf("unable to create a Falco client: %v", err) 104 | } 105 | defer c.Close() 106 | versionClient, err := c.Version() 107 | if err != nil { 108 | log.Fatalf("unable to obtain a version client: %v", err) 109 | } 110 | 111 | ctx := context.Background() 112 | res, err := versionClient.Version(ctx, &version.Request{}) 113 | if err != nil { 114 | log.Fatalf("error obtaining the Falco version: %v", err) 115 | } 116 | fmt.Printf("%v\n", res) 117 | ``` 118 | 119 | ## Full Examples 120 | 121 | - [Outputs events over mTLS example](examples/output/main.go) 122 | - [Outputs events over Unix socket example](examples/output_unix_socket/main.go) 123 | - [Outputs events over mTLS bidirectional example](examples/output_bidi/main.go) 124 | - [Outputs events over Unix socket bidirectional example](examples/output_unix_socket_bidi/main.go) 125 | - [Version over mTLS example](examples/version/main.go) 126 | - [Version over Unix socket example](examples/version_unix_socket/main.go) 127 | 128 | ## Update protos 129 | 130 | Perform the following edits to the Makefile: 131 | 132 | 1. Update the `PROTOS` array with the destination path of the `.proto` file. 133 | 2. Update the `PROTO_URLS` array with the URL from which to download it. 134 | 3. Update the `PROTO_SHAS` array with the SHA256 sum of the file to download. 135 | 4. Execute the following commands: 136 | 137 | ```console 138 | make clean 139 | make protos 140 | ``` 141 | 142 | ## Generate mocks for protos 143 | 144 | 1. Follow the steps in the `Update protos` section 145 | 2. Execute the following commands: 146 | 147 | ```console 148 | make mocks 149 | ``` 150 | -------------------------------------------------------------------------------- /examples/output/.gitignore: -------------------------------------------------------------------------------- 1 | output 2 | -------------------------------------------------------------------------------- /examples/output/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io" 7 | "log" 8 | 9 | "github.com/falcosecurity/client-go/pkg/api/outputs" 10 | "github.com/falcosecurity/client-go/pkg/client" 11 | "github.com/gogo/protobuf/jsonpb" 12 | ) 13 | 14 | func main() { 15 | // Set up a connection to the server. 16 | c, err := client.NewForConfig(context.Background(), &client.Config{ 17 | Hostname: "localhost", 18 | Port: 5060, 19 | CertFile: "/etc/falco/certs/client.crt", 20 | KeyFile: "/etc/falco/certs/client.key", 21 | CARootFile: "/etc/falco/certs/ca.crt", 22 | }) 23 | if err != nil { 24 | log.Fatalf("unable to connect: %v", err) 25 | } 26 | defer c.Close() 27 | outputsClient, err := c.Outputs() 28 | if err != nil { 29 | log.Fatalf("unable to obtain an output client: %v", err) 30 | } 31 | 32 | ctx := context.Background() 33 | fcs, err := outputsClient.Get(ctx, &outputs.Request{}) 34 | if err != nil { 35 | log.Fatalf("could not subscribe: %v", err) 36 | } 37 | 38 | for { 39 | res, err := fcs.Recv() 40 | if err == io.EOF { 41 | break 42 | } 43 | if err != nil { 44 | log.Fatalf("error closing stream after EOF: %v", err) 45 | } 46 | out, err := (&jsonpb.Marshaler{}).MarshalToString(res) 47 | if err != nil { 48 | log.Fatal(err) 49 | } 50 | fmt.Println(out) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /examples/output_bidi/.gitignore: -------------------------------------------------------------------------------- 1 | output_bidi 2 | -------------------------------------------------------------------------------- /examples/output_bidi/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "time" 8 | 9 | "github.com/falcosecurity/client-go/pkg/api/outputs" 10 | "github.com/falcosecurity/client-go/pkg/client" 11 | "github.com/gogo/protobuf/jsonpb" 12 | ) 13 | 14 | func printOutput(res *outputs.Response) error { 15 | out, err := (&jsonpb.Marshaler{}).MarshalToString(res) 16 | if err != nil { 17 | return err 18 | } 19 | fmt.Println(out) 20 | return nil 21 | } 22 | 23 | func main() { 24 | c, err := client.NewForConfig(context.Background(), &client.Config{ 25 | Hostname: "localhost", 26 | Port: 5060, 27 | CertFile: "/etc/falco/certs/client.crt", 28 | KeyFile: "/etc/falco/certs/client.key", 29 | CARootFile: "/etc/falco/certs/ca.crt", 30 | }) 31 | if err != nil { 32 | log.Fatalf("unable to connect: %v", err) 33 | } 34 | defer c.Close() 35 | ctx := context.Background() 36 | 37 | err = c.OutputsWatch(ctx, printOutput, time.Second*1) 38 | if err != nil { 39 | log.Fatalf("outputs watch error: %v", err) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /examples/output_unix_socket/.gitignore: -------------------------------------------------------------------------------- 1 | output_unix_socket 2 | -------------------------------------------------------------------------------- /examples/output_unix_socket/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io" 7 | "log" 8 | 9 | "github.com/falcosecurity/client-go/pkg/api/outputs" 10 | "github.com/falcosecurity/client-go/pkg/client" 11 | "github.com/gogo/protobuf/jsonpb" 12 | ) 13 | 14 | func main() { 15 | //Set up a connection to the server. 16 | c, err := client.NewForConfig(context.Background(), &client.Config{ 17 | UnixSocketPath: "unix:///run/falco/falco.sock", 18 | }) 19 | if err != nil { 20 | log.Fatalf("unable to connect: %v", err) 21 | } 22 | defer c.Close() 23 | outputsClient, err := c.Outputs() 24 | if err != nil { 25 | log.Fatalf("unable to obtain an output client: %v", err) 26 | } 27 | 28 | ctx := context.Background() 29 | fcs, err := outputsClient.Get(ctx, &outputs.Request{}) 30 | if err != nil { 31 | log.Fatalf("could not subscribe: %v", err) 32 | } 33 | 34 | for { 35 | res, err := fcs.Recv() 36 | if err == io.EOF { 37 | break 38 | } 39 | if err != nil { 40 | log.Fatalf("error closing stream after EOF: %v", err) 41 | } 42 | out, err := (&jsonpb.Marshaler{}).MarshalToString(res) 43 | if err != nil { 44 | log.Fatal(err) 45 | } 46 | fmt.Println(out) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /examples/output_unix_socket_bidi/.gitignore: -------------------------------------------------------------------------------- 1 | output_unix_socket_bidi 2 | -------------------------------------------------------------------------------- /examples/output_unix_socket_bidi/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "time" 8 | 9 | "github.com/falcosecurity/client-go/pkg/api/outputs" 10 | "github.com/falcosecurity/client-go/pkg/client" 11 | "github.com/gogo/protobuf/jsonpb" 12 | ) 13 | 14 | func printOutput(res *outputs.Response) error { 15 | out, err := (&jsonpb.Marshaler{}).MarshalToString(res) 16 | if err != nil { 17 | return err 18 | } 19 | fmt.Println(out) 20 | return nil 21 | } 22 | 23 | func main() { 24 | //Set up a connection to the server. 25 | c, err := client.NewForConfig(context.Background(), &client.Config{ 26 | UnixSocketPath: "unix:///run/falco/falco.sock", 27 | }) 28 | if err != nil { 29 | log.Fatalf("unable to connect: %v", err) 30 | } 31 | defer c.Close() 32 | ctx := context.Background() 33 | 34 | err = c.OutputsWatch(ctx, printOutput, time.Second*1) 35 | if err != nil { 36 | log.Fatalf("outputs watch error: %v", err) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/version/.gitignore: -------------------------------------------------------------------------------- 1 | version 2 | -------------------------------------------------------------------------------- /examples/version/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | 8 | "github.com/falcosecurity/client-go/pkg/api/version" 9 | "github.com/falcosecurity/client-go/pkg/client" 10 | "github.com/gogo/protobuf/jsonpb" 11 | ) 12 | 13 | func main() { 14 | // Set up a connection to the server. 15 | c, err := client.NewForConfig(context.Background(), &client.Config{ 16 | Hostname: "localhost", 17 | Port: 5060, 18 | CertFile: "/etc/falco/certs/client.crt", 19 | KeyFile: "/etc/falco/certs/client.key", 20 | CARootFile: "/etc/falco/certs/ca.crt", 21 | }) 22 | if err != nil { 23 | log.Fatalf("unable to create a Falco client: %v", err) 24 | } 25 | defer c.Close() 26 | versionClient, err := c.Version() 27 | if err != nil { 28 | log.Fatalf("unable to obtain a version client: %v", err) 29 | } 30 | 31 | ctx := context.Background() 32 | res, err := versionClient.Version(ctx, &version.Request{}) 33 | if err != nil { 34 | log.Fatalf("error obtaining the Falco version: %v", err) 35 | } 36 | out, err := (&jsonpb.Marshaler{}).MarshalToString(res) 37 | if err != nil { 38 | log.Fatal(err) 39 | } 40 | fmt.Println(out) 41 | } 42 | -------------------------------------------------------------------------------- /examples/version_unix_socket/.gitignore: -------------------------------------------------------------------------------- 1 | version_unix_socket 2 | -------------------------------------------------------------------------------- /examples/version_unix_socket/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | 8 | "github.com/falcosecurity/client-go/pkg/api/version" 9 | "github.com/falcosecurity/client-go/pkg/client" 10 | "github.com/gogo/protobuf/jsonpb" 11 | ) 12 | 13 | func main() { 14 | // Set up a connection to the server. 15 | c, err := client.NewForConfig(context.Background(), &client.Config{ 16 | UnixSocketPath: "unix:///run/falco/falco.sock", 17 | }) 18 | if err != nil { 19 | log.Fatalf("unable to create a Falco client: %v", err) 20 | } 21 | defer c.Close() 22 | versionClient, err := c.Version() 23 | if err != nil { 24 | log.Fatalf("unable to obtain a version client: %v", err) 25 | } 26 | 27 | ctx := context.Background() 28 | res, err := versionClient.Version(ctx, &version.Request{}) 29 | if err != nil { 30 | log.Fatalf("error obtaining the Falco version: %v", err) 31 | } 32 | out, err := (&jsonpb.Marshaler{}).MarshalToString(res) 33 | if err != nil { 34 | log.Fatal(err) 35 | } 36 | fmt.Println(out) 37 | } 38 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/falcosecurity/client-go 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/gogo/protobuf v1.3.2 7 | github.com/golang/mock v1.6.0 8 | github.com/golang/protobuf v1.5.3 9 | github.com/stretchr/testify v1.8.2 10 | google.golang.org/grpc v1.56.3 11 | google.golang.org/protobuf v1.33.0 12 | ) 13 | 14 | require ( 15 | github.com/davecgh/go-spew v1.1.1 // indirect 16 | github.com/pmezard/go-difflib v1.0.0 // indirect 17 | golang.org/x/net v0.17.0 // indirect 18 | golang.org/x/sys v0.13.0 // indirect 19 | golang.org/x/text v0.13.0 // indirect 20 | google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect 21 | gopkg.in/yaml.v3 v3.0.1 // indirect 22 | ) 23 | -------------------------------------------------------------------------------- /pkg/api/outputs/mocks/outputs.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: github.com/falcosecurity/client-go/pkg/api/outputs (interfaces: ServiceClient,Service_GetClient,Service_SubClient) 3 | 4 | // Package mock_outputs is a generated GoMock package. 5 | package mock_outputs 6 | 7 | import ( 8 | context "context" 9 | reflect "reflect" 10 | 11 | outputs "github.com/falcosecurity/client-go/pkg/api/outputs" 12 | gomock "github.com/golang/mock/gomock" 13 | grpc "google.golang.org/grpc" 14 | metadata "google.golang.org/grpc/metadata" 15 | ) 16 | 17 | // MockServiceClient is a mock of ServiceClient interface. 18 | type MockServiceClient struct { 19 | ctrl *gomock.Controller 20 | recorder *MockServiceClientMockRecorder 21 | } 22 | 23 | // MockServiceClientMockRecorder is the mock recorder for MockServiceClient. 24 | type MockServiceClientMockRecorder struct { 25 | mock *MockServiceClient 26 | } 27 | 28 | // NewMockServiceClient creates a new mock instance. 29 | func NewMockServiceClient(ctrl *gomock.Controller) *MockServiceClient { 30 | mock := &MockServiceClient{ctrl: ctrl} 31 | mock.recorder = &MockServiceClientMockRecorder{mock} 32 | return mock 33 | } 34 | 35 | // EXPECT returns an object that allows the caller to indicate expected use. 36 | func (m *MockServiceClient) EXPECT() *MockServiceClientMockRecorder { 37 | return m.recorder 38 | } 39 | 40 | // Get mocks base method. 41 | func (m *MockServiceClient) Get(arg0 context.Context, arg1 *outputs.Request, arg2 ...grpc.CallOption) (outputs.Service_GetClient, error) { 42 | m.ctrl.T.Helper() 43 | varargs := []interface{}{arg0, arg1} 44 | for _, a := range arg2 { 45 | varargs = append(varargs, a) 46 | } 47 | ret := m.ctrl.Call(m, "Get", varargs...) 48 | ret0, _ := ret[0].(outputs.Service_GetClient) 49 | ret1, _ := ret[1].(error) 50 | return ret0, ret1 51 | } 52 | 53 | // Get indicates an expected call of Get. 54 | func (mr *MockServiceClientMockRecorder) Get(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { 55 | mr.mock.ctrl.T.Helper() 56 | varargs := append([]interface{}{arg0, arg1}, arg2...) 57 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockServiceClient)(nil).Get), varargs...) 58 | } 59 | 60 | // Sub mocks base method. 61 | func (m *MockServiceClient) Sub(arg0 context.Context, arg1 ...grpc.CallOption) (outputs.Service_SubClient, error) { 62 | m.ctrl.T.Helper() 63 | varargs := []interface{}{arg0} 64 | for _, a := range arg1 { 65 | varargs = append(varargs, a) 66 | } 67 | ret := m.ctrl.Call(m, "Sub", varargs...) 68 | ret0, _ := ret[0].(outputs.Service_SubClient) 69 | ret1, _ := ret[1].(error) 70 | return ret0, ret1 71 | } 72 | 73 | // Sub indicates an expected call of Sub. 74 | func (mr *MockServiceClientMockRecorder) Sub(arg0 interface{}, arg1 ...interface{}) *gomock.Call { 75 | mr.mock.ctrl.T.Helper() 76 | varargs := append([]interface{}{arg0}, arg1...) 77 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sub", reflect.TypeOf((*MockServiceClient)(nil).Sub), varargs...) 78 | } 79 | 80 | // MockService_GetClient is a mock of Service_GetClient interface. 81 | type MockService_GetClient struct { 82 | ctrl *gomock.Controller 83 | recorder *MockService_GetClientMockRecorder 84 | } 85 | 86 | // MockService_GetClientMockRecorder is the mock recorder for MockService_GetClient. 87 | type MockService_GetClientMockRecorder struct { 88 | mock *MockService_GetClient 89 | } 90 | 91 | // NewMockService_GetClient creates a new mock instance. 92 | func NewMockService_GetClient(ctrl *gomock.Controller) *MockService_GetClient { 93 | mock := &MockService_GetClient{ctrl: ctrl} 94 | mock.recorder = &MockService_GetClientMockRecorder{mock} 95 | return mock 96 | } 97 | 98 | // EXPECT returns an object that allows the caller to indicate expected use. 99 | func (m *MockService_GetClient) EXPECT() *MockService_GetClientMockRecorder { 100 | return m.recorder 101 | } 102 | 103 | // CloseSend mocks base method. 104 | func (m *MockService_GetClient) CloseSend() error { 105 | m.ctrl.T.Helper() 106 | ret := m.ctrl.Call(m, "CloseSend") 107 | ret0, _ := ret[0].(error) 108 | return ret0 109 | } 110 | 111 | // CloseSend indicates an expected call of CloseSend. 112 | func (mr *MockService_GetClientMockRecorder) CloseSend() *gomock.Call { 113 | mr.mock.ctrl.T.Helper() 114 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockService_GetClient)(nil).CloseSend)) 115 | } 116 | 117 | // Context mocks base method. 118 | func (m *MockService_GetClient) Context() context.Context { 119 | m.ctrl.T.Helper() 120 | ret := m.ctrl.Call(m, "Context") 121 | ret0, _ := ret[0].(context.Context) 122 | return ret0 123 | } 124 | 125 | // Context indicates an expected call of Context. 126 | func (mr *MockService_GetClientMockRecorder) Context() *gomock.Call { 127 | mr.mock.ctrl.T.Helper() 128 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockService_GetClient)(nil).Context)) 129 | } 130 | 131 | // Header mocks base method. 132 | func (m *MockService_GetClient) Header() (metadata.MD, error) { 133 | m.ctrl.T.Helper() 134 | ret := m.ctrl.Call(m, "Header") 135 | ret0, _ := ret[0].(metadata.MD) 136 | ret1, _ := ret[1].(error) 137 | return ret0, ret1 138 | } 139 | 140 | // Header indicates an expected call of Header. 141 | func (mr *MockService_GetClientMockRecorder) Header() *gomock.Call { 142 | mr.mock.ctrl.T.Helper() 143 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockService_GetClient)(nil).Header)) 144 | } 145 | 146 | // Recv mocks base method. 147 | func (m *MockService_GetClient) Recv() (*outputs.Response, error) { 148 | m.ctrl.T.Helper() 149 | ret := m.ctrl.Call(m, "Recv") 150 | ret0, _ := ret[0].(*outputs.Response) 151 | ret1, _ := ret[1].(error) 152 | return ret0, ret1 153 | } 154 | 155 | // Recv indicates an expected call of Recv. 156 | func (mr *MockService_GetClientMockRecorder) Recv() *gomock.Call { 157 | mr.mock.ctrl.T.Helper() 158 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockService_GetClient)(nil).Recv)) 159 | } 160 | 161 | // RecvMsg mocks base method. 162 | func (m *MockService_GetClient) RecvMsg(arg0 interface{}) error { 163 | m.ctrl.T.Helper() 164 | ret := m.ctrl.Call(m, "RecvMsg", arg0) 165 | ret0, _ := ret[0].(error) 166 | return ret0 167 | } 168 | 169 | // RecvMsg indicates an expected call of RecvMsg. 170 | func (mr *MockService_GetClientMockRecorder) RecvMsg(arg0 interface{}) *gomock.Call { 171 | mr.mock.ctrl.T.Helper() 172 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockService_GetClient)(nil).RecvMsg), arg0) 173 | } 174 | 175 | // SendMsg mocks base method. 176 | func (m *MockService_GetClient) SendMsg(arg0 interface{}) error { 177 | m.ctrl.T.Helper() 178 | ret := m.ctrl.Call(m, "SendMsg", arg0) 179 | ret0, _ := ret[0].(error) 180 | return ret0 181 | } 182 | 183 | // SendMsg indicates an expected call of SendMsg. 184 | func (mr *MockService_GetClientMockRecorder) SendMsg(arg0 interface{}) *gomock.Call { 185 | mr.mock.ctrl.T.Helper() 186 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockService_GetClient)(nil).SendMsg), arg0) 187 | } 188 | 189 | // Trailer mocks base method. 190 | func (m *MockService_GetClient) Trailer() metadata.MD { 191 | m.ctrl.T.Helper() 192 | ret := m.ctrl.Call(m, "Trailer") 193 | ret0, _ := ret[0].(metadata.MD) 194 | return ret0 195 | } 196 | 197 | // Trailer indicates an expected call of Trailer. 198 | func (mr *MockService_GetClientMockRecorder) Trailer() *gomock.Call { 199 | mr.mock.ctrl.T.Helper() 200 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockService_GetClient)(nil).Trailer)) 201 | } 202 | 203 | // MockService_SubClient is a mock of Service_SubClient interface. 204 | type MockService_SubClient struct { 205 | ctrl *gomock.Controller 206 | recorder *MockService_SubClientMockRecorder 207 | } 208 | 209 | // MockService_SubClientMockRecorder is the mock recorder for MockService_SubClient. 210 | type MockService_SubClientMockRecorder struct { 211 | mock *MockService_SubClient 212 | } 213 | 214 | // NewMockService_SubClient creates a new mock instance. 215 | func NewMockService_SubClient(ctrl *gomock.Controller) *MockService_SubClient { 216 | mock := &MockService_SubClient{ctrl: ctrl} 217 | mock.recorder = &MockService_SubClientMockRecorder{mock} 218 | return mock 219 | } 220 | 221 | // EXPECT returns an object that allows the caller to indicate expected use. 222 | func (m *MockService_SubClient) EXPECT() *MockService_SubClientMockRecorder { 223 | return m.recorder 224 | } 225 | 226 | // CloseSend mocks base method. 227 | func (m *MockService_SubClient) CloseSend() error { 228 | m.ctrl.T.Helper() 229 | ret := m.ctrl.Call(m, "CloseSend") 230 | ret0, _ := ret[0].(error) 231 | return ret0 232 | } 233 | 234 | // CloseSend indicates an expected call of CloseSend. 235 | func (mr *MockService_SubClientMockRecorder) CloseSend() *gomock.Call { 236 | mr.mock.ctrl.T.Helper() 237 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockService_SubClient)(nil).CloseSend)) 238 | } 239 | 240 | // Context mocks base method. 241 | func (m *MockService_SubClient) Context() context.Context { 242 | m.ctrl.T.Helper() 243 | ret := m.ctrl.Call(m, "Context") 244 | ret0, _ := ret[0].(context.Context) 245 | return ret0 246 | } 247 | 248 | // Context indicates an expected call of Context. 249 | func (mr *MockService_SubClientMockRecorder) Context() *gomock.Call { 250 | mr.mock.ctrl.T.Helper() 251 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockService_SubClient)(nil).Context)) 252 | } 253 | 254 | // Header mocks base method. 255 | func (m *MockService_SubClient) Header() (metadata.MD, error) { 256 | m.ctrl.T.Helper() 257 | ret := m.ctrl.Call(m, "Header") 258 | ret0, _ := ret[0].(metadata.MD) 259 | ret1, _ := ret[1].(error) 260 | return ret0, ret1 261 | } 262 | 263 | // Header indicates an expected call of Header. 264 | func (mr *MockService_SubClientMockRecorder) Header() *gomock.Call { 265 | mr.mock.ctrl.T.Helper() 266 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockService_SubClient)(nil).Header)) 267 | } 268 | 269 | // Recv mocks base method. 270 | func (m *MockService_SubClient) Recv() (*outputs.Response, error) { 271 | m.ctrl.T.Helper() 272 | ret := m.ctrl.Call(m, "Recv") 273 | ret0, _ := ret[0].(*outputs.Response) 274 | ret1, _ := ret[1].(error) 275 | return ret0, ret1 276 | } 277 | 278 | // Recv indicates an expected call of Recv. 279 | func (mr *MockService_SubClientMockRecorder) Recv() *gomock.Call { 280 | mr.mock.ctrl.T.Helper() 281 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockService_SubClient)(nil).Recv)) 282 | } 283 | 284 | // RecvMsg mocks base method. 285 | func (m *MockService_SubClient) RecvMsg(arg0 interface{}) error { 286 | m.ctrl.T.Helper() 287 | ret := m.ctrl.Call(m, "RecvMsg", arg0) 288 | ret0, _ := ret[0].(error) 289 | return ret0 290 | } 291 | 292 | // RecvMsg indicates an expected call of RecvMsg. 293 | func (mr *MockService_SubClientMockRecorder) RecvMsg(arg0 interface{}) *gomock.Call { 294 | mr.mock.ctrl.T.Helper() 295 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockService_SubClient)(nil).RecvMsg), arg0) 296 | } 297 | 298 | // Send mocks base method. 299 | func (m *MockService_SubClient) Send(arg0 *outputs.Request) error { 300 | m.ctrl.T.Helper() 301 | ret := m.ctrl.Call(m, "Send", arg0) 302 | ret0, _ := ret[0].(error) 303 | return ret0 304 | } 305 | 306 | // Send indicates an expected call of Send. 307 | func (mr *MockService_SubClientMockRecorder) Send(arg0 interface{}) *gomock.Call { 308 | mr.mock.ctrl.T.Helper() 309 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockService_SubClient)(nil).Send), arg0) 310 | } 311 | 312 | // SendMsg mocks base method. 313 | func (m *MockService_SubClient) SendMsg(arg0 interface{}) error { 314 | m.ctrl.T.Helper() 315 | ret := m.ctrl.Call(m, "SendMsg", arg0) 316 | ret0, _ := ret[0].(error) 317 | return ret0 318 | } 319 | 320 | // SendMsg indicates an expected call of SendMsg. 321 | func (mr *MockService_SubClientMockRecorder) SendMsg(arg0 interface{}) *gomock.Call { 322 | mr.mock.ctrl.T.Helper() 323 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockService_SubClient)(nil).SendMsg), arg0) 324 | } 325 | 326 | // Trailer mocks base method. 327 | func (m *MockService_SubClient) Trailer() metadata.MD { 328 | m.ctrl.T.Helper() 329 | ret := m.ctrl.Call(m, "Trailer") 330 | ret0, _ := ret[0].(metadata.MD) 331 | return ret0 332 | } 333 | 334 | // Trailer indicates an expected call of Trailer. 335 | func (mr *MockService_SubClientMockRecorder) Trailer() *gomock.Call { 336 | mr.mock.ctrl.T.Helper() 337 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockService_SubClient)(nil).Trailer)) 338 | } 339 | -------------------------------------------------------------------------------- /pkg/api/outputs/outputs.pb.go: -------------------------------------------------------------------------------- 1 | // 2 | //Copyright (C) 2020 The Falco Authors. 3 | // 4 | //Licensed under the Apache License, Version 2.0 (the "License"); 5 | //you may not use this file except in compliance with the License. 6 | //You may obtain a copy of the License at 7 | // 8 | //http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | //Unless required by applicable law or agreed to in writing, software 11 | //distributed under the License is distributed on an "AS IS" BASIS, 12 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | //See the License for the specific language governing permissions and 14 | //limitations under the License. 15 | 16 | // Code generated by protoc-gen-go. DO NOT EDIT. 17 | // versions: 18 | // protoc-gen-go v1.27.1 19 | // protoc v3.12.4 20 | // source: outputs.proto 21 | 22 | package outputs 23 | 24 | import ( 25 | schema "github.com/falcosecurity/client-go/pkg/api/schema" 26 | timestamp "github.com/golang/protobuf/ptypes/timestamp" 27 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 28 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 29 | reflect "reflect" 30 | sync "sync" 31 | ) 32 | 33 | const ( 34 | // Verify that this generated code is sufficiently up-to-date. 35 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 36 | // Verify that runtime/protoimpl is sufficiently up-to-date. 37 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 38 | ) 39 | 40 | // The `request` message is the logical representation of the request model. 41 | // It is the input of the `output.service` service. 42 | type Request struct { 43 | state protoimpl.MessageState 44 | sizeCache protoimpl.SizeCache 45 | unknownFields protoimpl.UnknownFields 46 | } 47 | 48 | func (x *Request) Reset() { 49 | *x = Request{} 50 | if protoimpl.UnsafeEnabled { 51 | mi := &file_outputs_proto_msgTypes[0] 52 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 53 | ms.StoreMessageInfo(mi) 54 | } 55 | } 56 | 57 | func (x *Request) String() string { 58 | return protoimpl.X.MessageStringOf(x) 59 | } 60 | 61 | func (*Request) ProtoMessage() {} 62 | 63 | func (x *Request) ProtoReflect() protoreflect.Message { 64 | mi := &file_outputs_proto_msgTypes[0] 65 | if protoimpl.UnsafeEnabled && x != nil { 66 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 67 | if ms.LoadMessageInfo() == nil { 68 | ms.StoreMessageInfo(mi) 69 | } 70 | return ms 71 | } 72 | return mi.MessageOf(x) 73 | } 74 | 75 | // Deprecated: Use Request.ProtoReflect.Descriptor instead. 76 | func (*Request) Descriptor() ([]byte, []int) { 77 | return file_outputs_proto_rawDescGZIP(), []int{0} 78 | } 79 | 80 | // The `response` message is the representation of the output model. 81 | // It contains all the elements that Falco emits in an output along with the 82 | // definitions for priorities and source. 83 | type Response struct { 84 | state protoimpl.MessageState 85 | sizeCache protoimpl.SizeCache 86 | unknownFields protoimpl.UnknownFields 87 | 88 | Time *timestamp.Timestamp `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` 89 | Priority schema.Priority `protobuf:"varint,2,opt,name=priority,proto3,enum=falco.schema.Priority" json:"priority,omitempty"` 90 | // Deprecated: Do not use. 91 | SourceDeprecated schema.Source `protobuf:"varint,3,opt,name=source_deprecated,json=sourceDeprecated,proto3,enum=falco.schema.Source" json:"source_deprecated,omitempty"` 92 | Rule string `protobuf:"bytes,4,opt,name=rule,proto3" json:"rule,omitempty"` 93 | Output string `protobuf:"bytes,5,opt,name=output,proto3" json:"output,omitempty"` 94 | OutputFields map[string]string `protobuf:"bytes,6,rep,name=output_fields,json=outputFields,proto3" json:"output_fields,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` 95 | Hostname string `protobuf:"bytes,7,opt,name=hostname,proto3" json:"hostname,omitempty"` 96 | Tags []string `protobuf:"bytes,8,rep,name=tags,proto3" json:"tags,omitempty"` 97 | Source string `protobuf:"bytes,9,opt,name=source,proto3" json:"source,omitempty"` 98 | } 99 | 100 | func (x *Response) Reset() { 101 | *x = Response{} 102 | if protoimpl.UnsafeEnabled { 103 | mi := &file_outputs_proto_msgTypes[1] 104 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 105 | ms.StoreMessageInfo(mi) 106 | } 107 | } 108 | 109 | func (x *Response) String() string { 110 | return protoimpl.X.MessageStringOf(x) 111 | } 112 | 113 | func (*Response) ProtoMessage() {} 114 | 115 | func (x *Response) ProtoReflect() protoreflect.Message { 116 | mi := &file_outputs_proto_msgTypes[1] 117 | if protoimpl.UnsafeEnabled && x != nil { 118 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 119 | if ms.LoadMessageInfo() == nil { 120 | ms.StoreMessageInfo(mi) 121 | } 122 | return ms 123 | } 124 | return mi.MessageOf(x) 125 | } 126 | 127 | // Deprecated: Use Response.ProtoReflect.Descriptor instead. 128 | func (*Response) Descriptor() ([]byte, []int) { 129 | return file_outputs_proto_rawDescGZIP(), []int{1} 130 | } 131 | 132 | func (x *Response) GetTime() *timestamp.Timestamp { 133 | if x != nil { 134 | return x.Time 135 | } 136 | return nil 137 | } 138 | 139 | func (x *Response) GetPriority() schema.Priority { 140 | if x != nil { 141 | return x.Priority 142 | } 143 | return schema.Priority(0) 144 | } 145 | 146 | // Deprecated: Do not use. 147 | func (x *Response) GetSourceDeprecated() schema.Source { 148 | if x != nil { 149 | return x.SourceDeprecated 150 | } 151 | return schema.Source(0) 152 | } 153 | 154 | func (x *Response) GetRule() string { 155 | if x != nil { 156 | return x.Rule 157 | } 158 | return "" 159 | } 160 | 161 | func (x *Response) GetOutput() string { 162 | if x != nil { 163 | return x.Output 164 | } 165 | return "" 166 | } 167 | 168 | func (x *Response) GetOutputFields() map[string]string { 169 | if x != nil { 170 | return x.OutputFields 171 | } 172 | return nil 173 | } 174 | 175 | func (x *Response) GetHostname() string { 176 | if x != nil { 177 | return x.Hostname 178 | } 179 | return "" 180 | } 181 | 182 | func (x *Response) GetTags() []string { 183 | if x != nil { 184 | return x.Tags 185 | } 186 | return nil 187 | } 188 | 189 | func (x *Response) GetSource() string { 190 | if x != nil { 191 | return x.Source 192 | } 193 | return "" 194 | } 195 | 196 | var File_outputs_proto protoreflect.FileDescriptor 197 | 198 | var file_outputs_proto_rawDesc = []byte{ 199 | 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 200 | 0x0d, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x1a, 0x1f, 201 | 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 202 | 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 203 | 0x0c, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x09, 0x0a, 204 | 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xba, 0x03, 0x0a, 0x08, 0x72, 0x65, 0x73, 205 | 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 206 | 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 207 | 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 208 | 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 209 | 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x2e, 210 | 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x52, 211 | 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x45, 0x0a, 0x11, 0x73, 0x6f, 0x75, 212 | 0x72, 0x63, 0x65, 0x5f, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 213 | 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x2e, 0x73, 0x63, 0x68, 214 | 0x65, 0x6d, 0x61, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x10, 215 | 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 216 | 0x12, 0x12, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 217 | 0x72, 0x75, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x05, 218 | 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x4e, 0x0a, 0x0d, 219 | 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x06, 0x20, 220 | 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x2e, 0x6f, 0x75, 0x74, 0x70, 221 | 0x75, 0x74, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4f, 0x75, 0x74, 222 | 0x70, 0x75, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 223 | 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x1a, 0x0a, 0x08, 224 | 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 225 | 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 226 | 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x16, 0x0a, 0x06, 227 | 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 228 | 0x75, 0x72, 0x63, 0x65, 0x1a, 0x3f, 0x0a, 0x11, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x46, 0x69, 229 | 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 230 | 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 231 | 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 232 | 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0x7f, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 233 | 0x12, 0x3a, 0x0a, 0x03, 0x73, 0x75, 0x62, 0x12, 0x16, 0x2e, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x2e, 234 | 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 235 | 0x17, 0x2e, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x2e, 236 | 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x38, 0x0a, 0x03, 237 | 0x67, 0x65, 0x74, 0x12, 0x16, 0x2e, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x2e, 0x6f, 0x75, 0x74, 0x70, 238 | 0x75, 0x74, 0x73, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x66, 0x61, 239 | 0x6c, 0x63, 0x6f, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x70, 240 | 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 241 | 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 242 | 0x74, 0x79, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x6b, 0x67, 243 | 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72, 244 | 0x6f, 0x74, 0x6f, 0x33, 245 | } 246 | 247 | var ( 248 | file_outputs_proto_rawDescOnce sync.Once 249 | file_outputs_proto_rawDescData = file_outputs_proto_rawDesc 250 | ) 251 | 252 | func file_outputs_proto_rawDescGZIP() []byte { 253 | file_outputs_proto_rawDescOnce.Do(func() { 254 | file_outputs_proto_rawDescData = protoimpl.X.CompressGZIP(file_outputs_proto_rawDescData) 255 | }) 256 | return file_outputs_proto_rawDescData 257 | } 258 | 259 | var file_outputs_proto_msgTypes = make([]protoimpl.MessageInfo, 3) 260 | var file_outputs_proto_goTypes = []interface{}{ 261 | (*Request)(nil), // 0: falco.outputs.request 262 | (*Response)(nil), // 1: falco.outputs.response 263 | nil, // 2: falco.outputs.response.OutputFieldsEntry 264 | (*timestamp.Timestamp)(nil), // 3: google.protobuf.Timestamp 265 | (schema.Priority)(0), // 4: falco.schema.priority 266 | (schema.Source)(0), // 5: falco.schema.source 267 | } 268 | var file_outputs_proto_depIdxs = []int32{ 269 | 3, // 0: falco.outputs.response.time:type_name -> google.protobuf.Timestamp 270 | 4, // 1: falco.outputs.response.priority:type_name -> falco.schema.priority 271 | 5, // 2: falco.outputs.response.source_deprecated:type_name -> falco.schema.source 272 | 2, // 3: falco.outputs.response.output_fields:type_name -> falco.outputs.response.OutputFieldsEntry 273 | 0, // 4: falco.outputs.service.sub:input_type -> falco.outputs.request 274 | 0, // 5: falco.outputs.service.get:input_type -> falco.outputs.request 275 | 1, // 6: falco.outputs.service.sub:output_type -> falco.outputs.response 276 | 1, // 7: falco.outputs.service.get:output_type -> falco.outputs.response 277 | 6, // [6:8] is the sub-list for method output_type 278 | 4, // [4:6] is the sub-list for method input_type 279 | 4, // [4:4] is the sub-list for extension type_name 280 | 4, // [4:4] is the sub-list for extension extendee 281 | 0, // [0:4] is the sub-list for field type_name 282 | } 283 | 284 | func init() { file_outputs_proto_init() } 285 | func file_outputs_proto_init() { 286 | if File_outputs_proto != nil { 287 | return 288 | } 289 | if !protoimpl.UnsafeEnabled { 290 | file_outputs_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 291 | switch v := v.(*Request); i { 292 | case 0: 293 | return &v.state 294 | case 1: 295 | return &v.sizeCache 296 | case 2: 297 | return &v.unknownFields 298 | default: 299 | return nil 300 | } 301 | } 302 | file_outputs_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 303 | switch v := v.(*Response); i { 304 | case 0: 305 | return &v.state 306 | case 1: 307 | return &v.sizeCache 308 | case 2: 309 | return &v.unknownFields 310 | default: 311 | return nil 312 | } 313 | } 314 | } 315 | type x struct{} 316 | out := protoimpl.TypeBuilder{ 317 | File: protoimpl.DescBuilder{ 318 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 319 | RawDescriptor: file_outputs_proto_rawDesc, 320 | NumEnums: 0, 321 | NumMessages: 3, 322 | NumExtensions: 0, 323 | NumServices: 1, 324 | }, 325 | GoTypes: file_outputs_proto_goTypes, 326 | DependencyIndexes: file_outputs_proto_depIdxs, 327 | MessageInfos: file_outputs_proto_msgTypes, 328 | }.Build() 329 | File_outputs_proto = out.File 330 | file_outputs_proto_rawDesc = nil 331 | file_outputs_proto_goTypes = nil 332 | file_outputs_proto_depIdxs = nil 333 | } 334 | -------------------------------------------------------------------------------- /pkg/api/outputs/outputs_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // 2 | //Copyright (C) 2020 The Falco Authors. 3 | // 4 | //Licensed under the Apache License, Version 2.0 (the "License"); 5 | //you may not use this file except in compliance with the License. 6 | //You may obtain a copy of the License at 7 | // 8 | //http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | //Unless required by applicable law or agreed to in writing, software 11 | //distributed under the License is distributed on an "AS IS" BASIS, 12 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | //See the License for the specific language governing permissions and 14 | //limitations under the License. 15 | 16 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 17 | // versions: 18 | // - protoc-gen-go-grpc v1.3.0 19 | // - protoc v3.12.4 20 | // source: outputs.proto 21 | 22 | package outputs 23 | 24 | import ( 25 | context "context" 26 | grpc "google.golang.org/grpc" 27 | codes "google.golang.org/grpc/codes" 28 | status "google.golang.org/grpc/status" 29 | ) 30 | 31 | // This is a compile-time assertion to ensure that this generated file 32 | // is compatible with the grpc package it is being compiled against. 33 | // Requires gRPC-Go v1.32.0 or later. 34 | const _ = grpc.SupportPackageIsVersion7 35 | 36 | const ( 37 | Service_Sub_FullMethodName = "/falco.outputs.service/sub" 38 | Service_Get_FullMethodName = "/falco.outputs.service/get" 39 | ) 40 | 41 | // ServiceClient is the client API for Service service. 42 | // 43 | // 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. 44 | type ServiceClient interface { 45 | // Subscribe to a stream of Falco outputs by sending a stream of requests. 46 | Sub(ctx context.Context, opts ...grpc.CallOption) (Service_SubClient, error) 47 | // Get all the Falco outputs present in the system up to this call. 48 | Get(ctx context.Context, in *Request, opts ...grpc.CallOption) (Service_GetClient, error) 49 | } 50 | 51 | type serviceClient struct { 52 | cc grpc.ClientConnInterface 53 | } 54 | 55 | func NewServiceClient(cc grpc.ClientConnInterface) ServiceClient { 56 | return &serviceClient{cc} 57 | } 58 | 59 | func (c *serviceClient) Sub(ctx context.Context, opts ...grpc.CallOption) (Service_SubClient, error) { 60 | stream, err := c.cc.NewStream(ctx, &Service_ServiceDesc.Streams[0], Service_Sub_FullMethodName, opts...) 61 | if err != nil { 62 | return nil, err 63 | } 64 | x := &serviceSubClient{stream} 65 | return x, nil 66 | } 67 | 68 | type Service_SubClient interface { 69 | Send(*Request) error 70 | Recv() (*Response, error) 71 | grpc.ClientStream 72 | } 73 | 74 | type serviceSubClient struct { 75 | grpc.ClientStream 76 | } 77 | 78 | func (x *serviceSubClient) Send(m *Request) error { 79 | return x.ClientStream.SendMsg(m) 80 | } 81 | 82 | func (x *serviceSubClient) Recv() (*Response, error) { 83 | m := new(Response) 84 | if err := x.ClientStream.RecvMsg(m); err != nil { 85 | return nil, err 86 | } 87 | return m, nil 88 | } 89 | 90 | func (c *serviceClient) Get(ctx context.Context, in *Request, opts ...grpc.CallOption) (Service_GetClient, error) { 91 | stream, err := c.cc.NewStream(ctx, &Service_ServiceDesc.Streams[1], Service_Get_FullMethodName, opts...) 92 | if err != nil { 93 | return nil, err 94 | } 95 | x := &serviceGetClient{stream} 96 | if err := x.ClientStream.SendMsg(in); err != nil { 97 | return nil, err 98 | } 99 | if err := x.ClientStream.CloseSend(); err != nil { 100 | return nil, err 101 | } 102 | return x, nil 103 | } 104 | 105 | type Service_GetClient interface { 106 | Recv() (*Response, error) 107 | grpc.ClientStream 108 | } 109 | 110 | type serviceGetClient struct { 111 | grpc.ClientStream 112 | } 113 | 114 | func (x *serviceGetClient) Recv() (*Response, error) { 115 | m := new(Response) 116 | if err := x.ClientStream.RecvMsg(m); err != nil { 117 | return nil, err 118 | } 119 | return m, nil 120 | } 121 | 122 | // ServiceServer is the server API for Service service. 123 | // All implementations must embed UnimplementedServiceServer 124 | // for forward compatibility 125 | type ServiceServer interface { 126 | // Subscribe to a stream of Falco outputs by sending a stream of requests. 127 | Sub(Service_SubServer) error 128 | // Get all the Falco outputs present in the system up to this call. 129 | Get(*Request, Service_GetServer) error 130 | mustEmbedUnimplementedServiceServer() 131 | } 132 | 133 | // UnimplementedServiceServer must be embedded to have forward compatible implementations. 134 | type UnimplementedServiceServer struct { 135 | } 136 | 137 | func (UnimplementedServiceServer) Sub(Service_SubServer) error { 138 | return status.Errorf(codes.Unimplemented, "method Sub not implemented") 139 | } 140 | func (UnimplementedServiceServer) Get(*Request, Service_GetServer) error { 141 | return status.Errorf(codes.Unimplemented, "method Get not implemented") 142 | } 143 | func (UnimplementedServiceServer) mustEmbedUnimplementedServiceServer() {} 144 | 145 | // UnsafeServiceServer may be embedded to opt out of forward compatibility for this service. 146 | // Use of this interface is not recommended, as added methods to ServiceServer will 147 | // result in compilation errors. 148 | type UnsafeServiceServer interface { 149 | mustEmbedUnimplementedServiceServer() 150 | } 151 | 152 | func RegisterServiceServer(s grpc.ServiceRegistrar, srv ServiceServer) { 153 | s.RegisterService(&Service_ServiceDesc, srv) 154 | } 155 | 156 | func _Service_Sub_Handler(srv interface{}, stream grpc.ServerStream) error { 157 | return srv.(ServiceServer).Sub(&serviceSubServer{stream}) 158 | } 159 | 160 | type Service_SubServer interface { 161 | Send(*Response) error 162 | Recv() (*Request, error) 163 | grpc.ServerStream 164 | } 165 | 166 | type serviceSubServer struct { 167 | grpc.ServerStream 168 | } 169 | 170 | func (x *serviceSubServer) Send(m *Response) error { 171 | return x.ServerStream.SendMsg(m) 172 | } 173 | 174 | func (x *serviceSubServer) Recv() (*Request, error) { 175 | m := new(Request) 176 | if err := x.ServerStream.RecvMsg(m); err != nil { 177 | return nil, err 178 | } 179 | return m, nil 180 | } 181 | 182 | func _Service_Get_Handler(srv interface{}, stream grpc.ServerStream) error { 183 | m := new(Request) 184 | if err := stream.RecvMsg(m); err != nil { 185 | return err 186 | } 187 | return srv.(ServiceServer).Get(m, &serviceGetServer{stream}) 188 | } 189 | 190 | type Service_GetServer interface { 191 | Send(*Response) error 192 | grpc.ServerStream 193 | } 194 | 195 | type serviceGetServer struct { 196 | grpc.ServerStream 197 | } 198 | 199 | func (x *serviceGetServer) Send(m *Response) error { 200 | return x.ServerStream.SendMsg(m) 201 | } 202 | 203 | // Service_ServiceDesc is the grpc.ServiceDesc for Service service. 204 | // It's only intended for direct use with grpc.RegisterService, 205 | // and not to be introspected or modified (even as a copy) 206 | var Service_ServiceDesc = grpc.ServiceDesc{ 207 | ServiceName: "falco.outputs.service", 208 | HandlerType: (*ServiceServer)(nil), 209 | Methods: []grpc.MethodDesc{}, 210 | Streams: []grpc.StreamDesc{ 211 | { 212 | StreamName: "sub", 213 | Handler: _Service_Sub_Handler, 214 | ServerStreams: true, 215 | ClientStreams: true, 216 | }, 217 | { 218 | StreamName: "get", 219 | Handler: _Service_Get_Handler, 220 | ServerStreams: true, 221 | }, 222 | }, 223 | Metadata: "outputs.proto", 224 | } 225 | -------------------------------------------------------------------------------- /pkg/api/schema/schema.pb.go: -------------------------------------------------------------------------------- 1 | // 2 | //Copyright (C) 2022 The Falco Authors. 3 | // 4 | //Licensed under the Apache License, Version 2.0 (the "License"); 5 | //you may not use this file except in compliance with the License. 6 | //You may obtain a copy of the License at 7 | // 8 | //http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | //Unless required by applicable law or agreed to in writing, software 11 | //distributed under the License is distributed on an "AS IS" BASIS, 12 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | //See the License for the specific language governing permissions and 14 | //limitations under the License. 15 | 16 | // Code generated by protoc-gen-go. DO NOT EDIT. 17 | // versions: 18 | // protoc-gen-go v1.27.1 19 | // protoc v3.12.4 20 | // source: schema.proto 21 | 22 | package schema 23 | 24 | import ( 25 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 26 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 27 | reflect "reflect" 28 | sync "sync" 29 | ) 30 | 31 | const ( 32 | // Verify that this generated code is sufficiently up-to-date. 33 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 34 | // Verify that runtime/protoimpl is sufficiently up-to-date. 35 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 36 | ) 37 | 38 | type Priority int32 39 | 40 | const ( 41 | Priority_EMERGENCY Priority = 0 42 | Priority_emergency Priority = 0 43 | Priority_Emergency Priority = 0 44 | Priority_ALERT Priority = 1 45 | Priority_alert Priority = 1 46 | Priority_Alert Priority = 1 47 | Priority_CRITICAL Priority = 2 48 | Priority_critical Priority = 2 49 | Priority_Critical Priority = 2 50 | Priority_ERROR Priority = 3 51 | Priority_error Priority = 3 52 | Priority_Error Priority = 3 53 | Priority_WARNING Priority = 4 54 | Priority_warning Priority = 4 55 | Priority_Warning Priority = 4 56 | Priority_NOTICE Priority = 5 57 | Priority_notice Priority = 5 58 | Priority_Notice Priority = 5 59 | Priority_INFORMATIONAL Priority = 6 60 | Priority_informational Priority = 6 61 | Priority_Informational Priority = 6 62 | Priority_DEBUG Priority = 7 63 | Priority_debug Priority = 7 64 | Priority_Debug Priority = 7 65 | ) 66 | 67 | // Enum value maps for Priority. 68 | var ( 69 | Priority_name = map[int32]string{ 70 | 0: "EMERGENCY", 71 | // Duplicate value: 0: "emergency", 72 | // Duplicate value: 0: "Emergency", 73 | 1: "ALERT", 74 | // Duplicate value: 1: "alert", 75 | // Duplicate value: 1: "Alert", 76 | 2: "CRITICAL", 77 | // Duplicate value: 2: "critical", 78 | // Duplicate value: 2: "Critical", 79 | 3: "ERROR", 80 | // Duplicate value: 3: "error", 81 | // Duplicate value: 3: "Error", 82 | 4: "WARNING", 83 | // Duplicate value: 4: "warning", 84 | // Duplicate value: 4: "Warning", 85 | 5: "NOTICE", 86 | // Duplicate value: 5: "notice", 87 | // Duplicate value: 5: "Notice", 88 | 6: "INFORMATIONAL", 89 | // Duplicate value: 6: "informational", 90 | // Duplicate value: 6: "Informational", 91 | 7: "DEBUG", 92 | // Duplicate value: 7: "debug", 93 | // Duplicate value: 7: "Debug", 94 | } 95 | Priority_value = map[string]int32{ 96 | "EMERGENCY": 0, 97 | "emergency": 0, 98 | "Emergency": 0, 99 | "ALERT": 1, 100 | "alert": 1, 101 | "Alert": 1, 102 | "CRITICAL": 2, 103 | "critical": 2, 104 | "Critical": 2, 105 | "ERROR": 3, 106 | "error": 3, 107 | "Error": 3, 108 | "WARNING": 4, 109 | "warning": 4, 110 | "Warning": 4, 111 | "NOTICE": 5, 112 | "notice": 5, 113 | "Notice": 5, 114 | "INFORMATIONAL": 6, 115 | "informational": 6, 116 | "Informational": 6, 117 | "DEBUG": 7, 118 | "debug": 7, 119 | "Debug": 7, 120 | } 121 | ) 122 | 123 | func (x Priority) Enum() *Priority { 124 | p := new(Priority) 125 | *p = x 126 | return p 127 | } 128 | 129 | func (x Priority) String() string { 130 | return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) 131 | } 132 | 133 | func (Priority) Descriptor() protoreflect.EnumDescriptor { 134 | return file_schema_proto_enumTypes[0].Descriptor() 135 | } 136 | 137 | func (Priority) Type() protoreflect.EnumType { 138 | return &file_schema_proto_enumTypes[0] 139 | } 140 | 141 | func (x Priority) Number() protoreflect.EnumNumber { 142 | return protoreflect.EnumNumber(x) 143 | } 144 | 145 | // Deprecated: Use Priority.Descriptor instead. 146 | func (Priority) EnumDescriptor() ([]byte, []int) { 147 | return file_schema_proto_rawDescGZIP(), []int{0} 148 | } 149 | 150 | type Source int32 151 | 152 | const ( 153 | Source_SYSCALL Source = 0 154 | Source_syscall Source = 0 155 | Source_Syscall Source = 0 156 | Source_K8S_AUDIT Source = 1 157 | Source_k8s_audit Source = 1 158 | Source_K8s_audit Source = 1 159 | Source_K8S_audit Source = 1 160 | Source_INTERNAL Source = 2 161 | Source_internal Source = 2 162 | Source_Internal Source = 2 163 | Source_PLUGIN Source = 3 164 | Source_plugin Source = 3 165 | Source_Plugin Source = 3 166 | ) 167 | 168 | // Enum value maps for Source. 169 | var ( 170 | Source_name = map[int32]string{ 171 | 0: "SYSCALL", 172 | // Duplicate value: 0: "syscall", 173 | // Duplicate value: 0: "Syscall", 174 | 1: "K8S_AUDIT", 175 | // Duplicate value: 1: "k8s_audit", 176 | // Duplicate value: 1: "K8s_audit", 177 | // Duplicate value: 1: "K8S_audit", 178 | 2: "INTERNAL", 179 | // Duplicate value: 2: "internal", 180 | // Duplicate value: 2: "Internal", 181 | 3: "PLUGIN", 182 | // Duplicate value: 3: "plugin", 183 | // Duplicate value: 3: "Plugin", 184 | } 185 | Source_value = map[string]int32{ 186 | "SYSCALL": 0, 187 | "syscall": 0, 188 | "Syscall": 0, 189 | "K8S_AUDIT": 1, 190 | "k8s_audit": 1, 191 | "K8s_audit": 1, 192 | "K8S_audit": 1, 193 | "INTERNAL": 2, 194 | "internal": 2, 195 | "Internal": 2, 196 | "PLUGIN": 3, 197 | "plugin": 3, 198 | "Plugin": 3, 199 | } 200 | ) 201 | 202 | func (x Source) Enum() *Source { 203 | p := new(Source) 204 | *p = x 205 | return p 206 | } 207 | 208 | func (x Source) String() string { 209 | return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) 210 | } 211 | 212 | func (Source) Descriptor() protoreflect.EnumDescriptor { 213 | return file_schema_proto_enumTypes[1].Descriptor() 214 | } 215 | 216 | func (Source) Type() protoreflect.EnumType { 217 | return &file_schema_proto_enumTypes[1] 218 | } 219 | 220 | func (x Source) Number() protoreflect.EnumNumber { 221 | return protoreflect.EnumNumber(x) 222 | } 223 | 224 | // Deprecated: Use Source.Descriptor instead. 225 | func (Source) EnumDescriptor() ([]byte, []int) { 226 | return file_schema_proto_rawDescGZIP(), []int{1} 227 | } 228 | 229 | var File_schema_proto protoreflect.FileDescriptor 230 | 231 | var file_schema_proto_rawDesc = []byte{ 232 | 0x0a, 0x0c, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 233 | 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2a, 0xcc, 0x02, 0x0a, 234 | 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x0d, 0x0a, 0x09, 0x45, 0x4d, 0x45, 235 | 0x52, 0x47, 0x45, 0x4e, 0x43, 0x59, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x65, 0x6d, 0x65, 0x72, 236 | 0x67, 0x65, 0x6e, 0x63, 0x79, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x45, 0x6d, 0x65, 0x72, 0x67, 237 | 0x65, 0x6e, 0x63, 0x79, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x4c, 0x45, 0x52, 0x54, 0x10, 238 | 0x01, 0x12, 0x09, 0x0a, 0x05, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 239 | 0x41, 0x6c, 0x65, 0x72, 0x74, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x52, 0x49, 0x54, 0x49, 240 | 0x43, 0x41, 0x4c, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 241 | 0x6c, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x10, 242 | 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 243 | 0x65, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 244 | 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 245 | 0x0b, 0x0a, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x10, 0x04, 0x12, 0x0b, 0x0a, 0x07, 246 | 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x54, 247 | 0x49, 0x43, 0x45, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x10, 248 | 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x10, 0x05, 0x12, 0x11, 0x0a, 249 | 0x0d, 0x49, 0x4e, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x06, 250 | 0x12, 0x11, 0x0a, 0x0d, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 251 | 0x6c, 0x10, 0x06, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 252 | 0x6f, 0x6e, 0x61, 0x6c, 0x10, 0x06, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 253 | 0x07, 0x12, 0x09, 0x0a, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x10, 0x07, 0x12, 0x09, 0x0a, 0x05, 254 | 0x44, 0x65, 0x62, 0x75, 0x67, 0x10, 0x07, 0x1a, 0x02, 0x10, 0x01, 0x2a, 0xbd, 0x01, 0x0a, 0x06, 255 | 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x59, 0x53, 0x43, 0x41, 0x4c, 256 | 0x4c, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x73, 0x79, 0x73, 0x63, 0x61, 0x6c, 0x6c, 0x10, 0x00, 257 | 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x79, 0x73, 0x63, 0x61, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 258 | 0x09, 0x4b, 0x38, 0x53, 0x5f, 0x41, 0x55, 0x44, 0x49, 0x54, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 259 | 0x6b, 0x38, 0x73, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4b, 260 | 0x38, 0x73, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4b, 0x38, 261 | 0x53, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4e, 0x54, 262 | 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 263 | 0x6e, 0x61, 0x6c, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 264 | 0x6c, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x4c, 0x55, 0x47, 0x49, 0x4e, 0x10, 0x03, 0x12, 265 | 0x0a, 0x0a, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x50, 266 | 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x10, 0x03, 0x1a, 0x02, 0x10, 0x01, 0x42, 0x33, 0x5a, 0x31, 0x67, 267 | 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x73, 268 | 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x67, 269 | 0x6f, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 270 | 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 271 | } 272 | 273 | var ( 274 | file_schema_proto_rawDescOnce sync.Once 275 | file_schema_proto_rawDescData = file_schema_proto_rawDesc 276 | ) 277 | 278 | func file_schema_proto_rawDescGZIP() []byte { 279 | file_schema_proto_rawDescOnce.Do(func() { 280 | file_schema_proto_rawDescData = protoimpl.X.CompressGZIP(file_schema_proto_rawDescData) 281 | }) 282 | return file_schema_proto_rawDescData 283 | } 284 | 285 | var file_schema_proto_enumTypes = make([]protoimpl.EnumInfo, 2) 286 | var file_schema_proto_goTypes = []interface{}{ 287 | (Priority)(0), // 0: falco.schema.priority 288 | (Source)(0), // 1: falco.schema.source 289 | } 290 | var file_schema_proto_depIdxs = []int32{ 291 | 0, // [0:0] is the sub-list for method output_type 292 | 0, // [0:0] is the sub-list for method input_type 293 | 0, // [0:0] is the sub-list for extension type_name 294 | 0, // [0:0] is the sub-list for extension extendee 295 | 0, // [0:0] is the sub-list for field type_name 296 | } 297 | 298 | func init() { file_schema_proto_init() } 299 | func file_schema_proto_init() { 300 | if File_schema_proto != nil { 301 | return 302 | } 303 | type x struct{} 304 | out := protoimpl.TypeBuilder{ 305 | File: protoimpl.DescBuilder{ 306 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 307 | RawDescriptor: file_schema_proto_rawDesc, 308 | NumEnums: 2, 309 | NumMessages: 0, 310 | NumExtensions: 0, 311 | NumServices: 0, 312 | }, 313 | GoTypes: file_schema_proto_goTypes, 314 | DependencyIndexes: file_schema_proto_depIdxs, 315 | EnumInfos: file_schema_proto_enumTypes, 316 | }.Build() 317 | File_schema_proto = out.File 318 | file_schema_proto_rawDesc = nil 319 | file_schema_proto_goTypes = nil 320 | file_schema_proto_depIdxs = nil 321 | } 322 | -------------------------------------------------------------------------------- /pkg/api/version/mocks/version.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: github.com/falcosecurity/client-go/pkg/api/version (interfaces: ServiceClient) 3 | 4 | // Package mock_version is a generated GoMock package. 5 | package mock_version 6 | 7 | import ( 8 | context "context" 9 | reflect "reflect" 10 | 11 | version "github.com/falcosecurity/client-go/pkg/api/version" 12 | gomock "github.com/golang/mock/gomock" 13 | grpc "google.golang.org/grpc" 14 | ) 15 | 16 | // MockServiceClient is a mock of ServiceClient interface. 17 | type MockServiceClient struct { 18 | ctrl *gomock.Controller 19 | recorder *MockServiceClientMockRecorder 20 | } 21 | 22 | // MockServiceClientMockRecorder is the mock recorder for MockServiceClient. 23 | type MockServiceClientMockRecorder struct { 24 | mock *MockServiceClient 25 | } 26 | 27 | // NewMockServiceClient creates a new mock instance. 28 | func NewMockServiceClient(ctrl *gomock.Controller) *MockServiceClient { 29 | mock := &MockServiceClient{ctrl: ctrl} 30 | mock.recorder = &MockServiceClientMockRecorder{mock} 31 | return mock 32 | } 33 | 34 | // EXPECT returns an object that allows the caller to indicate expected use. 35 | func (m *MockServiceClient) EXPECT() *MockServiceClientMockRecorder { 36 | return m.recorder 37 | } 38 | 39 | // Version mocks base method. 40 | func (m *MockServiceClient) Version(arg0 context.Context, arg1 *version.Request, arg2 ...grpc.CallOption) (*version.Response, error) { 41 | m.ctrl.T.Helper() 42 | varargs := []interface{}{arg0, arg1} 43 | for _, a := range arg2 { 44 | varargs = append(varargs, a) 45 | } 46 | ret := m.ctrl.Call(m, "Version", varargs...) 47 | ret0, _ := ret[0].(*version.Response) 48 | ret1, _ := ret[1].(error) 49 | return ret0, ret1 50 | } 51 | 52 | // Version indicates an expected call of Version. 53 | func (mr *MockServiceClientMockRecorder) Version(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { 54 | mr.mock.ctrl.T.Helper() 55 | varargs := append([]interface{}{arg0, arg1}, arg2...) 56 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockServiceClient)(nil).Version), varargs...) 57 | } 58 | -------------------------------------------------------------------------------- /pkg/api/version/version.pb.go: -------------------------------------------------------------------------------- 1 | // 2 | //Copyright (C) 2020 The Falco Authors. 3 | // 4 | //Licensed under the Apache License, Version 2.0 (the "License"); 5 | //you may not use this file except in compliance with the License. 6 | //You may obtain a copy of the License at 7 | // 8 | //http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | //Unless required by applicable law or agreed to in writing, software 11 | //distributed under the License is distributed on an "AS IS" BASIS, 12 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | //See the License for the specific language governing permissions and 14 | //limitations under the License. 15 | 16 | // Code generated by protoc-gen-go. DO NOT EDIT. 17 | // versions: 18 | // protoc-gen-go v1.27.1 19 | // protoc v3.12.4 20 | // source: version.proto 21 | 22 | package version 23 | 24 | import ( 25 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 26 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 27 | reflect "reflect" 28 | sync "sync" 29 | ) 30 | 31 | const ( 32 | // Verify that this generated code is sufficiently up-to-date. 33 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 34 | // Verify that runtime/protoimpl is sufficiently up-to-date. 35 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 36 | ) 37 | 38 | // The `request` message is an empty one. 39 | type Request struct { 40 | state protoimpl.MessageState 41 | sizeCache protoimpl.SizeCache 42 | unknownFields protoimpl.UnknownFields 43 | } 44 | 45 | func (x *Request) Reset() { 46 | *x = Request{} 47 | if protoimpl.UnsafeEnabled { 48 | mi := &file_version_proto_msgTypes[0] 49 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 50 | ms.StoreMessageInfo(mi) 51 | } 52 | } 53 | 54 | func (x *Request) String() string { 55 | return protoimpl.X.MessageStringOf(x) 56 | } 57 | 58 | func (*Request) ProtoMessage() {} 59 | 60 | func (x *Request) ProtoReflect() protoreflect.Message { 61 | mi := &file_version_proto_msgTypes[0] 62 | if protoimpl.UnsafeEnabled && x != nil { 63 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 64 | if ms.LoadMessageInfo() == nil { 65 | ms.StoreMessageInfo(mi) 66 | } 67 | return ms 68 | } 69 | return mi.MessageOf(x) 70 | } 71 | 72 | // Deprecated: Use Request.ProtoReflect.Descriptor instead. 73 | func (*Request) Descriptor() ([]byte, []int) { 74 | return file_version_proto_rawDescGZIP(), []int{0} 75 | } 76 | 77 | // The `response` message contains the version of Falco. 78 | // It provides the whole version as a string and also 79 | // its parts as per semver 2.0 specification (https://semver.org). 80 | type Response struct { 81 | state protoimpl.MessageState 82 | sizeCache protoimpl.SizeCache 83 | unknownFields protoimpl.UnknownFields 84 | 85 | // falco version 86 | Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` 87 | Major uint32 `protobuf:"varint,2,opt,name=major,proto3" json:"major,omitempty"` 88 | Minor uint32 `protobuf:"varint,3,opt,name=minor,proto3" json:"minor,omitempty"` 89 | Patch uint32 `protobuf:"varint,4,opt,name=patch,proto3" json:"patch,omitempty"` 90 | Prerelease string `protobuf:"bytes,5,opt,name=prerelease,proto3" json:"prerelease,omitempty"` 91 | Build string `protobuf:"bytes,6,opt,name=build,proto3" json:"build,omitempty"` 92 | // falco engine version 93 | EngineVersion uint32 `protobuf:"varint,7,opt,name=engine_version,json=engineVersion,proto3" json:"engine_version,omitempty"` 94 | EngineFieldsChecksum string `protobuf:"bytes,8,opt,name=engine_fields_checksum,json=engineFieldsChecksum,proto3" json:"engine_fields_checksum,omitempty"` 95 | } 96 | 97 | func (x *Response) Reset() { 98 | *x = Response{} 99 | if protoimpl.UnsafeEnabled { 100 | mi := &file_version_proto_msgTypes[1] 101 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 102 | ms.StoreMessageInfo(mi) 103 | } 104 | } 105 | 106 | func (x *Response) String() string { 107 | return protoimpl.X.MessageStringOf(x) 108 | } 109 | 110 | func (*Response) ProtoMessage() {} 111 | 112 | func (x *Response) ProtoReflect() protoreflect.Message { 113 | mi := &file_version_proto_msgTypes[1] 114 | if protoimpl.UnsafeEnabled && x != nil { 115 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 116 | if ms.LoadMessageInfo() == nil { 117 | ms.StoreMessageInfo(mi) 118 | } 119 | return ms 120 | } 121 | return mi.MessageOf(x) 122 | } 123 | 124 | // Deprecated: Use Response.ProtoReflect.Descriptor instead. 125 | func (*Response) Descriptor() ([]byte, []int) { 126 | return file_version_proto_rawDescGZIP(), []int{1} 127 | } 128 | 129 | func (x *Response) GetVersion() string { 130 | if x != nil { 131 | return x.Version 132 | } 133 | return "" 134 | } 135 | 136 | func (x *Response) GetMajor() uint32 { 137 | if x != nil { 138 | return x.Major 139 | } 140 | return 0 141 | } 142 | 143 | func (x *Response) GetMinor() uint32 { 144 | if x != nil { 145 | return x.Minor 146 | } 147 | return 0 148 | } 149 | 150 | func (x *Response) GetPatch() uint32 { 151 | if x != nil { 152 | return x.Patch 153 | } 154 | return 0 155 | } 156 | 157 | func (x *Response) GetPrerelease() string { 158 | if x != nil { 159 | return x.Prerelease 160 | } 161 | return "" 162 | } 163 | 164 | func (x *Response) GetBuild() string { 165 | if x != nil { 166 | return x.Build 167 | } 168 | return "" 169 | } 170 | 171 | func (x *Response) GetEngineVersion() uint32 { 172 | if x != nil { 173 | return x.EngineVersion 174 | } 175 | return 0 176 | } 177 | 178 | func (x *Response) GetEngineFieldsChecksum() string { 179 | if x != nil { 180 | return x.EngineFieldsChecksum 181 | } 182 | return "" 183 | } 184 | 185 | var File_version_proto protoreflect.FileDescriptor 186 | 187 | var file_version_proto_rawDesc = []byte{ 188 | 0x0a, 0x0d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 189 | 0x0d, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x2e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x09, 190 | 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xf9, 0x01, 0x0a, 0x08, 0x72, 0x65, 191 | 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 192 | 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 193 | 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 194 | 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 195 | 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 196 | 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 197 | 0x63, 0x68, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 198 | 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 199 | 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 200 | 0x09, 0x52, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x6e, 0x67, 0x69, 201 | 0x6e, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 202 | 0x52, 0x0d, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 203 | 0x34, 0x0a, 0x16, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 204 | 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 205 | 0x14, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x43, 0x68, 0x65, 206 | 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x32, 0x45, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 207 | 0x12, 0x3a, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x66, 0x61, 208 | 0x6c, 0x63, 0x6f, 0x2e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x72, 0x65, 0x71, 0x75, 209 | 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x2e, 0x76, 0x65, 0x72, 0x73, 210 | 0x69, 0x6f, 0x6e, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x34, 0x5a, 0x32, 211 | 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, 0x61, 0x6c, 0x63, 0x6f, 212 | 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 213 | 0x67, 0x6f, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 214 | 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 215 | } 216 | 217 | var ( 218 | file_version_proto_rawDescOnce sync.Once 219 | file_version_proto_rawDescData = file_version_proto_rawDesc 220 | ) 221 | 222 | func file_version_proto_rawDescGZIP() []byte { 223 | file_version_proto_rawDescOnce.Do(func() { 224 | file_version_proto_rawDescData = protoimpl.X.CompressGZIP(file_version_proto_rawDescData) 225 | }) 226 | return file_version_proto_rawDescData 227 | } 228 | 229 | var file_version_proto_msgTypes = make([]protoimpl.MessageInfo, 2) 230 | var file_version_proto_goTypes = []interface{}{ 231 | (*Request)(nil), // 0: falco.version.request 232 | (*Response)(nil), // 1: falco.version.response 233 | } 234 | var file_version_proto_depIdxs = []int32{ 235 | 0, // 0: falco.version.service.version:input_type -> falco.version.request 236 | 1, // 1: falco.version.service.version:output_type -> falco.version.response 237 | 1, // [1:2] is the sub-list for method output_type 238 | 0, // [0:1] is the sub-list for method input_type 239 | 0, // [0:0] is the sub-list for extension type_name 240 | 0, // [0:0] is the sub-list for extension extendee 241 | 0, // [0:0] is the sub-list for field type_name 242 | } 243 | 244 | func init() { file_version_proto_init() } 245 | func file_version_proto_init() { 246 | if File_version_proto != nil { 247 | return 248 | } 249 | if !protoimpl.UnsafeEnabled { 250 | file_version_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 251 | switch v := v.(*Request); i { 252 | case 0: 253 | return &v.state 254 | case 1: 255 | return &v.sizeCache 256 | case 2: 257 | return &v.unknownFields 258 | default: 259 | return nil 260 | } 261 | } 262 | file_version_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 263 | switch v := v.(*Response); i { 264 | case 0: 265 | return &v.state 266 | case 1: 267 | return &v.sizeCache 268 | case 2: 269 | return &v.unknownFields 270 | default: 271 | return nil 272 | } 273 | } 274 | } 275 | type x struct{} 276 | out := protoimpl.TypeBuilder{ 277 | File: protoimpl.DescBuilder{ 278 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 279 | RawDescriptor: file_version_proto_rawDesc, 280 | NumEnums: 0, 281 | NumMessages: 2, 282 | NumExtensions: 0, 283 | NumServices: 1, 284 | }, 285 | GoTypes: file_version_proto_goTypes, 286 | DependencyIndexes: file_version_proto_depIdxs, 287 | MessageInfos: file_version_proto_msgTypes, 288 | }.Build() 289 | File_version_proto = out.File 290 | file_version_proto_rawDesc = nil 291 | file_version_proto_goTypes = nil 292 | file_version_proto_depIdxs = nil 293 | } 294 | -------------------------------------------------------------------------------- /pkg/api/version/version_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // 2 | //Copyright (C) 2020 The Falco Authors. 3 | // 4 | //Licensed under the Apache License, Version 2.0 (the "License"); 5 | //you may not use this file except in compliance with the License. 6 | //You may obtain a copy of the License at 7 | // 8 | //http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | //Unless required by applicable law or agreed to in writing, software 11 | //distributed under the License is distributed on an "AS IS" BASIS, 12 | //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | //See the License for the specific language governing permissions and 14 | //limitations under the License. 15 | 16 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 17 | // versions: 18 | // - protoc-gen-go-grpc v1.3.0 19 | // - protoc v3.12.4 20 | // source: version.proto 21 | 22 | package version 23 | 24 | import ( 25 | context "context" 26 | grpc "google.golang.org/grpc" 27 | codes "google.golang.org/grpc/codes" 28 | status "google.golang.org/grpc/status" 29 | ) 30 | 31 | // This is a compile-time assertion to ensure that this generated file 32 | // is compatible with the grpc package it is being compiled against. 33 | // Requires gRPC-Go v1.32.0 or later. 34 | const _ = grpc.SupportPackageIsVersion7 35 | 36 | const ( 37 | Service_Version_FullMethodName = "/falco.version.service/version" 38 | ) 39 | 40 | // ServiceClient is the client API for Service service. 41 | // 42 | // 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. 43 | type ServiceClient interface { 44 | Version(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) 45 | } 46 | 47 | type serviceClient struct { 48 | cc grpc.ClientConnInterface 49 | } 50 | 51 | func NewServiceClient(cc grpc.ClientConnInterface) ServiceClient { 52 | return &serviceClient{cc} 53 | } 54 | 55 | func (c *serviceClient) Version(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) { 56 | out := new(Response) 57 | err := c.cc.Invoke(ctx, Service_Version_FullMethodName, in, out, opts...) 58 | if err != nil { 59 | return nil, err 60 | } 61 | return out, nil 62 | } 63 | 64 | // ServiceServer is the server API for Service service. 65 | // All implementations must embed UnimplementedServiceServer 66 | // for forward compatibility 67 | type ServiceServer interface { 68 | Version(context.Context, *Request) (*Response, error) 69 | mustEmbedUnimplementedServiceServer() 70 | } 71 | 72 | // UnimplementedServiceServer must be embedded to have forward compatible implementations. 73 | type UnimplementedServiceServer struct { 74 | } 75 | 76 | func (UnimplementedServiceServer) Version(context.Context, *Request) (*Response, error) { 77 | return nil, status.Errorf(codes.Unimplemented, "method Version not implemented") 78 | } 79 | func (UnimplementedServiceServer) mustEmbedUnimplementedServiceServer() {} 80 | 81 | // UnsafeServiceServer may be embedded to opt out of forward compatibility for this service. 82 | // Use of this interface is not recommended, as added methods to ServiceServer will 83 | // result in compilation errors. 84 | type UnsafeServiceServer interface { 85 | mustEmbedUnimplementedServiceServer() 86 | } 87 | 88 | func RegisterServiceServer(s grpc.ServiceRegistrar, srv ServiceServer) { 89 | s.RegisterService(&Service_ServiceDesc, srv) 90 | } 91 | 92 | func _Service_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 93 | in := new(Request) 94 | if err := dec(in); err != nil { 95 | return nil, err 96 | } 97 | if interceptor == nil { 98 | return srv.(ServiceServer).Version(ctx, in) 99 | } 100 | info := &grpc.UnaryServerInfo{ 101 | Server: srv, 102 | FullMethod: Service_Version_FullMethodName, 103 | } 104 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 105 | return srv.(ServiceServer).Version(ctx, req.(*Request)) 106 | } 107 | return interceptor(ctx, in, info, handler) 108 | } 109 | 110 | // Service_ServiceDesc is the grpc.ServiceDesc for Service service. 111 | // It's only intended for direct use with grpc.RegisterService, 112 | // and not to be introspected or modified (even as a copy) 113 | var Service_ServiceDesc = grpc.ServiceDesc{ 114 | ServiceName: "falco.version.service", 115 | HandlerType: (*ServiceServer)(nil), 116 | Methods: []grpc.MethodDesc{ 117 | { 118 | MethodName: "version", 119 | Handler: _Service_Version_Handler, 120 | }, 121 | }, 122 | Streams: []grpc.StreamDesc{}, 123 | Metadata: "version.proto", 124 | } 125 | -------------------------------------------------------------------------------- /pkg/client/client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "crypto/tls" 6 | "crypto/x509" 7 | "fmt" 8 | "io" 9 | "io/ioutil" 10 | "time" 11 | 12 | "github.com/falcosecurity/client-go/pkg/api/outputs" 13 | "github.com/falcosecurity/client-go/pkg/api/version" 14 | "google.golang.org/grpc" 15 | "google.golang.org/grpc/credentials" 16 | ) 17 | 18 | // Client is a wrapper for the gRPC connection 19 | // it allows to connect to a Falco gRPC server. 20 | // It is created using the function `NewForConfig(context.Context, *Config)`. 21 | type Client struct { 22 | conn *grpc.ClientConn 23 | versionServiceClient version.ServiceClient 24 | outputsServiceClient outputs.ServiceClient 25 | } 26 | 27 | // Config is the configuration definition for connecting to a Falco gRPC server. 28 | type Config struct { 29 | Hostname string 30 | Port uint16 31 | CertFile string 32 | KeyFile string 33 | CARootFile string 34 | UnixSocketPath string 35 | DialOptions []grpc.DialOption 36 | InsecureSkipMutualTLSAuth bool 37 | } 38 | 39 | const targetFormat = "%s:%d" 40 | 41 | // NewForConfig is used to create a new Falco gRPC client. 42 | func NewForConfig(ctx context.Context, config *Config) (*Client, error) { 43 | if len(config.UnixSocketPath) > 0 { 44 | return newUnixSocketClient(ctx, config) 45 | } 46 | return newNetworkClient(ctx, config) 47 | } 48 | 49 | func newUnixSocketClient(ctx context.Context, config *Config) (*Client, error) { 50 | dialOptions := append(config.DialOptions, grpc.WithInsecure()) 51 | conn, err := grpc.DialContext(ctx, config.UnixSocketPath, dialOptions...) 52 | if err != nil { 53 | return nil, fmt.Errorf("error dialing server: %v", err) 54 | } 55 | return &Client{ 56 | conn: conn, 57 | }, nil 58 | } 59 | 60 | func newNetworkClient(ctx context.Context, config *Config) (*Client, error) { 61 | certificate, err := tls.LoadX509KeyPair( 62 | config.CertFile, 63 | config.KeyFile, 64 | ) 65 | if err != nil { 66 | return nil, fmt.Errorf("error loading the X.509 key pair: %v", err) 67 | } 68 | tlsConfig := tls.Config { 69 | ServerName: config.Hostname, 70 | Certificates: []tls.Certificate{certificate}, 71 | InsecureSkipVerify: config.InsecureSkipMutualTLSAuth, 72 | } 73 | certPool := x509.NewCertPool() 74 | if !config.InsecureSkipMutualTLSAuth { 75 | rootCA, err := ioutil.ReadFile(config.CARootFile) 76 | if err != nil { 77 | return nil, fmt.Errorf("error reading the CA Root file certificate: %v", err) 78 | } 79 | ok := certPool.AppendCertsFromPEM(rootCA) 80 | if !ok { 81 | return nil, fmt.Errorf("error appending the root CA to the certificate pool") 82 | } 83 | tlsConfig.RootCAs = certPool 84 | } 85 | transportCreds := credentials.NewTLS(&tls.Config{ 86 | ServerName: config.Hostname, 87 | Certificates: []tls.Certificate{certificate}, 88 | RootCAs: certPool, 89 | }) 90 | dialOptions := append(config.DialOptions, grpc.WithTransportCredentials(transportCreds)) 91 | conn, err := grpc.DialContext(ctx, fmt.Sprintf(targetFormat, config.Hostname, config.Port), dialOptions...) 92 | if err != nil { 93 | return nil, fmt.Errorf("error dialing server: %v", err) 94 | } 95 | return &Client{ 96 | conn: conn, 97 | }, nil 98 | } 99 | 100 | // Outputs is the client for Falco Outputs. 101 | // When using it you can use `Sub()` or `Get()` to receive a stream of Falco output events. 102 | func (c *Client) Outputs() (outputs.ServiceClient, error) { 103 | if err := c.checkConn(); err != nil { 104 | return nil, err 105 | } 106 | if c.outputsServiceClient == nil { 107 | c.outputsServiceClient = outputs.NewServiceClient(c.conn) 108 | } 109 | return c.outputsServiceClient, nil 110 | } 111 | 112 | // OutputsWatchCallback is passed to OutputsWatch to perform an 113 | // action for each *outputs.Response while retrieving a stream outputs 114 | type OutputsWatchCallback func(res *outputs.Response) error 115 | 116 | // OutputsWatch allows to watch and process a stream of *outputs.Response 117 | // using a callback function of type OutputsWatchCallback. 118 | // 119 | // The timeout parameter specifies the frequency of the watch operation. 120 | func OutputsWatch(ctx context.Context, 121 | fcs outputs.Service_SubClient, 122 | cb OutputsWatchCallback, 123 | timeout time.Duration) error { 124 | 125 | resCh := make(chan *outputs.Response, 1) 126 | errCh := make(chan error, 1) 127 | 128 | go func() { 129 | for { 130 | res, err := fcs.Recv() 131 | if err != nil { 132 | errCh <- err 133 | return 134 | } 135 | resCh <- res 136 | } 137 | }() 138 | 139 | for { 140 | select { 141 | case res := <-resCh: 142 | err := cb(res) 143 | if err != nil { 144 | return err 145 | } 146 | case err := <-errCh: 147 | if err == io.EOF { 148 | return nil 149 | } 150 | return err 151 | case <-time.After(timeout): 152 | fcs.Send(&outputs.Request{}) 153 | case <-ctx.Done(): 154 | return ctx.Err() 155 | } 156 | } 157 | } 158 | 159 | // OutputsWatch subscribes to a stream of Falco outputs 160 | // and allows to watch and process a stream of *outputs.Response 161 | // using a callback function of type OutputsWatchCallback. 162 | // 163 | // The timeout parameter specifies the frequency of the watch operation. 164 | func (c *Client) OutputsWatch(ctx context.Context, 165 | cb OutputsWatchCallback, 166 | timeout time.Duration, 167 | opts ...grpc.CallOption) error { 168 | oc, err := c.Outputs() 169 | if err != nil { 170 | return err 171 | } 172 | fcs, err := oc.Sub(ctx, opts...) 173 | if err != nil { 174 | return err 175 | } 176 | return OutputsWatch(ctx, fcs, cb, timeout) 177 | } 178 | 179 | // Version it the client for Falco Version API. 180 | // When using it you can use `version()` to receive the Falco version. 181 | func (c *Client) Version() (version.ServiceClient, error) { 182 | if err := c.checkConn(); err != nil { 183 | return nil, err 184 | } 185 | if c.versionServiceClient == nil { 186 | c.versionServiceClient = version.NewServiceClient(c.conn) 187 | } 188 | return c.versionServiceClient, nil 189 | } 190 | 191 | // Close the connection to the falco gRPC server. 192 | func (c *Client) Close() error { 193 | if err := c.checkConn(); err != nil { 194 | return err 195 | } 196 | return c.conn.Close() 197 | } 198 | 199 | func (c *Client) checkConn() error { 200 | if c.conn == nil { 201 | return fmt.Errorf("missing connection for the current client") 202 | } 203 | return nil 204 | } 205 | -------------------------------------------------------------------------------- /pkg/client/client_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/falcosecurity/client-go/pkg/api/outputs" 8 | outputsmock "github.com/falcosecurity/client-go/pkg/api/outputs/mocks" 9 | "github.com/falcosecurity/client-go/pkg/api/version" 10 | versionmock "github.com/falcosecurity/client-go/pkg/api/version/mocks" 11 | "github.com/golang/mock/gomock" 12 | "github.com/stretchr/testify/assert" 13 | "google.golang.org/grpc" 14 | ) 15 | 16 | func TestClient_Version(t *testing.T) { 17 | ctrl := gomock.NewController(t) 18 | 19 | mockVersionClient := versionmock.NewMockServiceClient(ctrl) 20 | mockVersionClient.EXPECT().Version( 21 | gomock.Any(), 22 | gomock.Any(), 23 | ).Return(&version.Response{Version: "mockVersion"}, nil) 24 | 25 | c := Client{ 26 | conn: &grpc.ClientConn{}, 27 | versionServiceClient: mockVersionClient, 28 | } 29 | 30 | versionServiceClient, err := c.Version() 31 | assert.Nil(t, err) 32 | 33 | res, err := versionServiceClient.Version(context.Background(), &version.Request{}) 34 | assert.Nil(t, err) 35 | assert.Equal(t, res.Version, "mockVersion", "version does not match mockVersion") 36 | } 37 | 38 | func TestClient_Outputs(t *testing.T) { 39 | ctrl := gomock.NewController(t) 40 | 41 | streamStub := outputsmock.NewMockService_GetClient(ctrl) 42 | streamStub.EXPECT().Recv().Return(&outputs.Response{Rule: "testRule", Output: "testOutput"}, nil) 43 | 44 | mockOutputClient := outputsmock.NewMockServiceClient(ctrl) 45 | mockOutputClient.EXPECT().Get( 46 | gomock.Any(), 47 | gomock.Any(), 48 | ).Return(streamStub, nil) 49 | 50 | c := Client{ 51 | conn: &grpc.ClientConn{}, 52 | outputsServiceClient: mockOutputClient, 53 | } 54 | 55 | outputsServiceClient, err := c.Outputs() 56 | assert.Nil(t, err) 57 | 58 | stream, err := outputsServiceClient.Get(context.Background(), &outputs.Request{}) 59 | assert.Nil(t, err) 60 | res, err := stream.Recv() 61 | assert.Nil(t, err) 62 | assert.Equal(t, res.Rule, "testRule", "rule does not match testRule") 63 | assert.Equal(t, res.Output, "testOutput", "output does not match testOutput") 64 | } 65 | -------------------------------------------------------------------------------- /pkg/client/example_test.go: -------------------------------------------------------------------------------- 1 | package client_test 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io" 7 | "log" 8 | 9 | "github.com/falcosecurity/client-go/pkg/api/outputs" 10 | "github.com/falcosecurity/client-go/pkg/api/version" 11 | "github.com/falcosecurity/client-go/pkg/client" 12 | ) 13 | 14 | // The simplest use of a Client, just create and Close it. 15 | func ExampleClient() { 16 | //Set up a connection to the server. 17 | c, err := client.NewForConfig(context.Background(), &client.Config{ 18 | Hostname: "localhost", 19 | Port: 5060, 20 | CertFile: "/etc/falco/certs/client.crt", 21 | KeyFile: "/etc/falco/certs/client.key", 22 | CARootFile: "/etc/falco/certs/ca.crt", 23 | }) 24 | if err != nil { 25 | log.Fatalf("unable to create a Falco client: %v", err) 26 | } 27 | defer c.Close() 28 | } 29 | 30 | // A client that is created and then used to get the Falco output events. 31 | func ExampleClient_outputsGet() { 32 | // Set up a connection to the server. 33 | c, err := client.NewForConfig(context.Background(), &client.Config{ 34 | Hostname: "localhost", 35 | Port: 5060, 36 | CertFile: "/etc/falco/certs/client.crt", 37 | KeyFile: "/etc/falco/certs/client.key", 38 | CARootFile: "/etc/falco/certs/ca.crt", 39 | }) 40 | if err != nil { 41 | log.Fatalf("unable to create a Falco client: %v", err) 42 | } 43 | defer c.Close() 44 | outputsClient, err := c.Outputs() 45 | if err != nil { 46 | log.Fatalf("unable to obtain an output client: %v", err) 47 | } 48 | 49 | ctx := context.Background() 50 | fcs, err := outputsClient.Get(ctx, &outputs.Request{}) 51 | if err != nil { 52 | log.Fatalf("could not subscribe: %v", err) 53 | } 54 | 55 | for { 56 | res, err := fcs.Recv() 57 | if err == io.EOF { 58 | break 59 | } 60 | if err != nil { 61 | log.Fatalf("error closing stream after EOF: %v", err) 62 | } 63 | fmt.Printf("rule: %s\n", res.Rule) 64 | } 65 | } 66 | 67 | func ExampleClient_version() { 68 | // Set up a connection to the server. 69 | c, err := client.NewForConfig(context.Background(), &client.Config{ 70 | Hostname: "localhost", 71 | Port: 5060, 72 | CertFile: "/etc/falco/certs/client.crt", 73 | KeyFile: "/etc/falco/certs/client.key", 74 | CARootFile: "/etc/falco/certs/ca.crt", 75 | }) 76 | if err != nil { 77 | log.Fatalf("unable to create a Falco client: %v", err) 78 | } 79 | defer c.Close() 80 | versionClient, err := c.Version() 81 | if err != nil { 82 | log.Fatalf("unable to obtain a version client: %v", err) 83 | } 84 | 85 | ctx := context.Background() 86 | res, err := versionClient.Version(ctx, &version.Request{}) 87 | if err != nil { 88 | log.Fatalf("error obtaining the Falco version: %v", err) 89 | } 90 | fmt.Printf("%v\n", res) 91 | } 92 | -------------------------------------------------------------------------------- /release.md: -------------------------------------------------------------------------------- 1 | # Release Process 2 | 3 | When we release we do the following process: 4 | 5 | 1. We decide together (usually in the #falco channel in [slack](https://kubernetes.slack.com/messages/falco)) what's the [next version](#About-versioning) to tag 6 | 2. A person with repository rights does the tag 7 | 3. The same person runs commands in their machine following the "Release commands" section below 8 | 4. The tag is live on [Github](https://github.com/falcosecurity/client-go/releases) with the changelog attached 9 | 10 | ## Release commands 11 | 12 | Just tag the [version](#About-versioning). For example: 13 | 14 | ```bash 15 | git tag -a v0.1.0-rc.0 -m "v0.1.0-rc.0" 16 | git push origin v0.1.0-rc.0 17 | ``` 18 | 19 | The [goreleaser](https://goreleaser.com/ci/) will run on CircleCI and do the magic :) 20 | 21 | ## About versioning 22 | 23 | Basically, this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 24 | 25 | Furthermore, although the `go-client` version is NOT paired with the Falco version directly, the major version MUST be incremented when any backwards incompatible changes are introduced to the proto definitions. The only notable exception is [major version zero](https://semver.org/spec/v2.0.0.html#spec-item-4), indeed, for initial development just the minor version MUST be incremented. 26 | --------------------------------------------------------------------------------