mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 00:45:19 +00:00
Move kubequery
dependency to monorepo (#16027)
#15561 We didn't find a way to preserve history of the original fork (see [here](https://github.com/fleetdm/fleet/issues/15561#issuecomment-1883473504), thus we are moving it with one commit. The second commit updates a reference.
This commit is contained in:
parent
78ad2ed558
commit
3b2e97db89
18
infrastructure/kubequery/.fossa.yml
Normal file
18
infrastructure/kubequery/.fossa.yml
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
version: 2
|
||||
cli:
|
||||
server: https://app.fossa.com
|
||||
fetcher: custom
|
||||
project: git@github.com:Uptycs/kubequery.git
|
||||
analyze:
|
||||
modules:
|
||||
- name: github.com/Uptycs/kubequery/cmd/kubequery
|
||||
type: go
|
||||
target: github.com/Uptycs/kubequery/cmd/kubequery
|
||||
path: cmd/kubequery
|
14
infrastructure/kubequery/.gitignore
vendored
Normal file
14
infrastructure/kubequery/.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
.vscode
|
||||
vendor
|
||||
kubequery.yaml
|
||||
/bin/genschema
|
||||
/bin/gentables
|
||||
/bin/kubequery
|
||||
/bin/uuidgen
|
158
infrastructure/kubequery/CHANGELOG.md
Normal file
158
infrastructure/kubequery/CHANGELOG.md
Normal file
@ -0,0 +1,158 @@
|
||||
# kubequery change log
|
||||
|
||||
|
||||
<a name="1.1.1"></a>
|
||||
## [1.1.1](https://github.com/Uptycs/kubequery/releases/tag/1.1.1)
|
||||
|
||||
[Git Commits](https://github.com/Uptycs/kubequery/compare/1.1.0...1.1.1)
|
||||
|
||||
### New Features
|
||||
|
||||
### Under the Hood improvements
|
||||
|
||||
* Upgrade to basequery 5.0.2
|
||||
* Upgraded to Go 1.17
|
||||
|
||||
### Table Changes
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
### Documentation
|
||||
|
||||
### Build
|
||||
|
||||
### Security Issues
|
||||
|
||||
### Packs
|
||||
|
||||
|
||||
<a name="1.1.0"></a>
|
||||
## [1.1.0](https://github.com/Uptycs/kubequery/releases/tag/1.1.0)
|
||||
|
||||
[Git Commits](https://github.com/Uptycs/kubequery/compare/1.0.0...1.1.0)
|
||||
|
||||
### New Features
|
||||
|
||||
* Helm chart to install kubequery
|
||||
* Support for Kubernetes 1.22
|
||||
|
||||
### Under the Hood improvements
|
||||
|
||||
* Upgrade to basequery 4.9.0
|
||||
* Upgraded to client go version 0.22
|
||||
|
||||
### Table Changes
|
||||
|
||||
* k8s 1.22 caused few table [schemas changes](https://github.com/Uptycs/kubequery/commit/a70e9a42f6f85ca1a0ebd23575590c73562fab83#diff-79f5d80ee02a931b2bf12fd018b6edeb447abd58e1fb85ae155ae932ec29ad9d):
|
||||
* kubernetes_stateful_sets
|
||||
* kubernetes_jobs
|
||||
* kubernetes_persistent_volume_claims
|
||||
* kubernetes_services
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Check container status before iterating over contents. [Issue 16](https://github.com/Uptycs/kubequery/issues/16)
|
||||
|
||||
### Documentation
|
||||
|
||||
* Added helm related details in README.md
|
||||
|
||||
### Build
|
||||
|
||||
### Security Issues
|
||||
|
||||
### Packs
|
||||
|
||||
|
||||
<a name="1.0.0"></a>
|
||||
## [1.0.0](https://github.com/Uptycs/kubequery/releases/tag/1.0.0)
|
||||
|
||||
[Git Commits](https://github.com/Uptycs/kubequery/compare/0.3.0...1.0.0)
|
||||
|
||||
### New Features
|
||||
|
||||
* New `kubequeryi` command line to easily invoke shell
|
||||
* Easy to use with [query-tls](https://github.com/Uptycs/query-tls)
|
||||
|
||||
### Under the Hood improvements
|
||||
|
||||
* Upgrade to basequery 4.8.0
|
||||
* Switch to light weight busybox docker image
|
||||
* Simple NodeJS based integration test
|
||||
|
||||
### Table Changes
|
||||
|
||||
* Added `cluster_name` and `cluster_uid` to tables missing those columns
|
||||
* Break up `resources` in `*_containers` tables to `resource_limits` and `resource_requests`
|
||||
* Added new table `kubernetes_component_statuses`
|
||||
* Removed table `kubernetes_storage_capacities`
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
### Documentation
|
||||
|
||||
### Build
|
||||
|
||||
* Upgrade to Go 1.16
|
||||
|
||||
### Security Issues
|
||||
|
||||
### Packs
|
||||
|
||||
* Added default query pack for all kubernetes tables
|
||||
|
||||
|
||||
<a name="0.3.0"></a>
|
||||
## [0.3.0](https://github.com/Uptycs/kubequery/releases/tag/0.3.0)
|
||||
|
||||
[Git Commits](https://github.com/Uptycs/kubequery/compare/0.2.0...0.3.0)
|
||||
|
||||
### New Features
|
||||
|
||||
### Under the Hood improvements
|
||||
|
||||
* Upgrade to basequery 4.7.0
|
||||
|
||||
### Table Changes
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
### Documentation
|
||||
|
||||
* Validate the installation was successful [PR-12](https://github.com/Uptycs/kubequery/pull/12)
|
||||
|
||||
### Build
|
||||
|
||||
### Security Issues
|
||||
|
||||
### Packs
|
||||
|
||||
|
||||
<a name="0.2.0"></a>
|
||||
## [0.2.0](https://github.com/Uptycs/kubequery/releases/tag/0.2.0)
|
||||
|
||||
[Git Commits](https://github.com/Uptycs/kubequery/compare/0.1.0...0.2.0)
|
||||
|
||||
### New Features
|
||||
|
||||
* Added `kubernetes_events` table.
|
||||
|
||||
### Under the Hood improvements
|
||||
|
||||
* Switch to [basequery](https://github.com/Uptycs/basequery). This is stripped download version of Osquery with support for extension events and other features.
|
||||
|
||||
### Table Changes
|
||||
|
||||
* kubernetes_events
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
### Documentation
|
||||
|
||||
* Validate the installation was successful [PR-12](https://github.com/Uptycs/kubequery/pull/12)
|
||||
|
||||
### Build
|
||||
|
||||
### Security Issues
|
||||
|
||||
### Packs
|
133
infrastructure/kubequery/CODE_OF_CONDUCT.md
Normal file
133
infrastructure/kubequery/CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,133 @@
|
||||
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
[kubequery@uptycs.com](mailto:kubequery@uptycs.com).
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
|
||||
|
||||
Community Impact Guidelines were inspired by
|
||||
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
|
||||
at [https://www.contributor-covenant.org/translations][translations].
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
|
||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||
[FAQ]: https://www.contributor-covenant.org/faq
|
||||
[translations]: https://www.contributor-covenant.org/translations
|
51
infrastructure/kubequery/CONTRIBUTING.md
Normal file
51
infrastructure/kubequery/CONTRIBUTING.md
Normal file
@ -0,0 +1,51 @@
|
||||
# Contributing to kubequery
|
||||
|
||||
Welcome and thank you for considering contributing to kubequery open source.
|
||||
|
||||
Reading and following these guidelines will help us make the contribution process easy and effective for everyone involved. It also communicates that you agree to respect the time of the developers managing and developing these open source projects. In return, we will reciprocate that respect by addressing your issue, assessing changes, and helping you finalize your pull requests.
|
||||
|
||||
## Quicklinks
|
||||
|
||||
* [Code of Conduct](#code-of-conduct)
|
||||
* [Getting Started](#getting-started)
|
||||
* [Issues](#issues)
|
||||
* [Pull Requests](#pull-requests)
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
By participating and contributing to this project, you agree to uphold our [Code of Conduct](https://github.com/Uptycs/kubequery/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
## Getting Started
|
||||
|
||||
Contributions are made to this repo via Issues and Pull Requests (PRs). A few general guidelines that cover both:
|
||||
|
||||
- To report security vulnerabilities, please email [kubequery@uptycs.com](mailto:kubequery@uptycs.com).
|
||||
- Search for existing Issues and PRs before creating your own.
|
||||
|
||||
### Issues
|
||||
|
||||
Issues should be used to report problems with kubequery, request a new feature, or to discuss potential changes before a PR is created. When you create a new issue, a template will be loaded that will guide you through collecting and providing the information we need to investigate.
|
||||
|
||||
If you find an issue that addresses the problem you're having, please add your own reproduction information to the existing issue rather than creating a new one. Adding a [reaction](https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) can also help be indicating to our maintainers that a particular problem is affecting more than just the reporter.
|
||||
|
||||
### Pull Requests
|
||||
|
||||
PRs to our libraries are always welcome and can be a quick way to get your fix or improvement slated for the next release. In general, PRs should:
|
||||
|
||||
- Only fix/add the functionality in question.
|
||||
- Add unit tests for fixed or changed functionality.
|
||||
- Address a single concern in the least number of changed lines as possible.
|
||||
- Include documentation in the repo.
|
||||
- Be accompanied by a complete Pull Request template (loaded automatically when a PR is created).
|
||||
|
||||
For changes that address core functionality or would require breaking changes (e.g. a major release), it's best to open an Issue to discuss your proposal first. This is not required but can save time creating and reviewing changes.
|
||||
|
||||
In general, we follow the ["fork-and-pull" Git workflow](https://github.com/susam/gitpr)
|
||||
|
||||
1. Fork the repository to your own Github account
|
||||
2. Clone the project to your machine
|
||||
3. Create a branch locally with a succinct but descriptive name
|
||||
4. Commit changes to the branch
|
||||
5. Following any formatting and testing guidelines specific to this repo
|
||||
6. Push changes to your fork
|
||||
7. Open a PR in our repository and follow the PR template so that we can efficiently review the changes.
|
45
infrastructure/kubequery/Dockerfile
Normal file
45
infrastructure/kubequery/Dockerfile
Normal file
@ -0,0 +1,45 @@
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
FROM ubuntu:20.04 AS builder
|
||||
|
||||
ARG BASEQUERY_VERSION=5.0.2
|
||||
|
||||
ADD https://uptycs-basequery.s3.amazonaws.com/${BASEQUERY_VERSION}/basequery_${BASEQUERY_VERSION}-1.linux_amd64.deb /tmp/basequery.deb
|
||||
|
||||
RUN dpkg -i /tmp/basequery.deb
|
||||
|
||||
# =====
|
||||
|
||||
FROM uptycs/busybox:v1.33.0
|
||||
|
||||
ARG BASEQUERY_VERSION
|
||||
ARG KUBEQUERY_VERSION
|
||||
|
||||
LABEL \
|
||||
name="kubequery" \
|
||||
description="kubequery powered by Osquery" \
|
||||
version="${KUBEQUERY_VERSION}" \
|
||||
url="https://github.com/Uptycs/kubequery"
|
||||
|
||||
# uptycs/busybox comes with this user predefined. We need a non-root user
|
||||
USER uptycs
|
||||
|
||||
WORKDIR /opt/uptycs
|
||||
|
||||
RUN set -ex; \
|
||||
mkdir /opt/uptycs/bin /opt/uptycs/etc /opt/uptycs/logs /opt/uptycs/var && \
|
||||
echo "/opt/uptycs/bin/kubequery.ext" > /opt/uptycs/etc/autoload.exts
|
||||
|
||||
COPY --from=0 --chown=uptycs:uptycs /opt/osquery/bin/osqueryd /opt/uptycs/bin/basequery
|
||||
COPY --from=0 --chown=uptycs:uptycs /opt/osquery/share/osquery/certs/certs.pem /opt/uptycs/etc/
|
||||
COPY --chown=uptycs:uptycs bin/entrypoint.sh bin/kubequeryi bin/uuidgen /opt/uptycs/bin/
|
||||
COPY --chown=uptycs:uptycs bin/kubequery /opt/uptycs/bin/kubequery.ext
|
||||
|
||||
ENV KUBEQUERY_VERSION=${KUBEQUERY_VERSION}
|
||||
|
||||
ENTRYPOINT ["/opt/uptycs/bin/entrypoint.sh"]
|
9
infrastructure/kubequery/LICENSE
Normal file
9
infrastructure/kubequery/LICENSE
Normal file
@ -0,0 +1,9 @@
|
||||
# License
|
||||
|
||||
By contributing to kubequery you agree that your contributions will be licensed
|
||||
under the terms of both the [LICENSE-Apache-2.0](LICENSE-Apache-2.0) and the
|
||||
[LICENSE-GPL-2.0](LICENSE-GPL-2.0) files in the root of this source tree.
|
||||
|
||||
If you're using kubequery you are free to choose one of the provided licenses.
|
||||
|
||||
`SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-only`
|
202
infrastructure/kubequery/LICENSE-Apache-2.0
Normal file
202
infrastructure/kubequery/LICENSE-Apache-2.0
Normal file
@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
340
infrastructure/kubequery/LICENSE-GPL-2.0
Normal file
340
infrastructure/kubequery/LICENSE-GPL-2.0
Normal file
@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
55
infrastructure/kubequery/Makefile
Normal file
55
infrastructure/kubequery/Makefile
Normal file
@ -0,0 +1,55 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
ifeq ($(VERSION),)
|
||||
VERSION := $(shell git describe --tags HEAD | cut -d'-' -f1-2 | sed 's/-/./')
|
||||
endif
|
||||
|
||||
all: deps lint test build kubequery.yaml
|
||||
|
||||
deps:
|
||||
@go mod download
|
||||
|
||||
lint:
|
||||
@go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||
@go install golang.org/x/lint/golint
|
||||
@staticcheck ./...
|
||||
@golint ./...
|
||||
|
||||
build: deps
|
||||
@go build -ldflags="-s -w -X main.VERSION=${VERSION}" -o bin ./...
|
||||
|
||||
test:
|
||||
@go test -race -cover ./...
|
||||
|
||||
integration:
|
||||
@node integration/index.js
|
||||
|
||||
docker: build
|
||||
@docker build --build-arg KUBEQUERY_VERSION=${VERSION} -t uptycs/kubequery:${VERSION} .
|
||||
|
||||
genschema: build
|
||||
@./bin/gentables > docs/tables.json
|
||||
@echo "\`\`\`sql" > docs/schema.md
|
||||
@./bin/genschema >> docs/schema.md
|
||||
@echo "\`\`\`" >> docs/schema.md
|
||||
|
||||
kubequery.yaml:
|
||||
@sed -e "s/^/ /g" etc/kubequery.flags > etc/kubequery.flags.tmp
|
||||
@sed -e "s/^/ /g" etc/kubequery.conf > etc/kubequery.conf.tmp
|
||||
@sed -e "/kubequery.flags: |/r etc/kubequery.flags.tmp" \
|
||||
-e "/kubequery.conf: |/r etc/kubequery.conf.tmp" \
|
||||
-e "s/version: latest/version: ${VERSION}/g" \
|
||||
kubequery-template.yaml > kubequery.yaml
|
||||
@rm -f etc/*.tmp
|
||||
|
||||
clean:
|
||||
@rm -rf vendor kubequery.yaml bin/kubequery bin/genschema bin/uuidgen etc/*.tmp
|
||||
|
||||
.PHONY: all integration
|
180
infrastructure/kubequery/README.md
Normal file
180
infrastructure/kubequery/README.md
Normal file
@ -0,0 +1,180 @@
|
||||
[![Build](https://github.com/Uptycs/kubequery/workflows/Build/badge.svg?branch=master)](https://github.com/Uptycs/kubequery/actions?query=workflow%3ABuild)
|
||||
[![CodeQL](https://github.com/Uptycs/kubequery/workflows/CodeQL/badge.svg?branch=master)](https://github.com/Uptycs/kubequery/actions?query=workflow%3ACodeQL)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/Uptycs/kubequery)](https://goreportcard.com/report/github.com/Uptycs/kubequery)
|
||||
[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B22616%2Fgit%40github.com%3AUptycs%2Fkubequery.git.svg?type=shield)](https://app.fossa.com/projects/custom%2B22616%2Fgit%40github.com%3AUptycs%2Fkubequery.git?ref=badge_shield) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md)
|
||||
|
||||
---
|
||||
|
||||
# kubequery powered by Osquery
|
||||
|
||||
kubequery is a [Osquery](https://osquery.io) extension that provides SQL based analytics for [Kubernetes](https://kubernetes.io) clusters
|
||||
|
||||
kubequery will be packaged as docker image available from [dockerhub](https://hub.docker.com/r/uptycs/kubequery). It is expected to be deployed as a [Kubernetes Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment) per cluster. A sample deployment template is available [here](kubequery-template.yaml)
|
||||
|
||||
kubequery tables [schema is available here](docs/schema.md)
|
||||
|
||||
---
|
||||
|
||||
## Build
|
||||
|
||||
`Go 1.17` and `make` are required to build kubequery. Run: `make`
|
||||
|
||||
Container image for master branch will be available on [dockerhub](https://hub.docker.com/r/uptycs/kubequery)
|
||||
```sh
|
||||
docker pull uptycs/kubequery:latest
|
||||
```
|
||||
|
||||
For production, tagged container images should be used instead of `latest`.
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
[kubequery-template.yaml](kubequery-template.yaml) is a template that creates the following Kubernetes resources:
|
||||
* [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/)
|
||||
* [ServiceAccount](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens)
|
||||
* [ClusterRole](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole)
|
||||
* [ClusterRoleBinding](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding)
|
||||
* [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/)
|
||||
* [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)
|
||||
|
||||
`kubequery` Namespace will be the placeholder for all resources that are namespaced.
|
||||
|
||||
`kubequery-sa` is ServiceAccount that is associated with the kubequery deployment pod specification. The container uses the service account token to authenticate with the API server.
|
||||
|
||||
`kubequery-clusterrole` is a ClusterRole that allows `get` and `list` operations on all resources in the following API groups:
|
||||
- "" (core)
|
||||
- admissionregistration.k8s.io
|
||||
- apps
|
||||
- autoscaling
|
||||
- batch
|
||||
- networking.k8s.io
|
||||
- policy
|
||||
- rbac.authorization.k8s.io
|
||||
- storage.k8s.io
|
||||
|
||||
`kubequery-clusterrolebinding` is a ClusterRoleBinding that binds the cluster role with the service account.
|
||||
|
||||
`kubequery-config` is a ConfigMap that will be mounted inside the container image as a directory. The contents of this config map should be similar to `/etc/osquery`. For example, kubequery.flags, kubequery.conf, etc. should be part of this config map.
|
||||
|
||||
`kubequery` is the Deployment that creates one replica pod. The container launched as a part of the pod is run as non-root user.
|
||||
|
||||
By default pod resource `requests` and `limits` are set to 500m (half a core) and 200MB. kubequery.yaml file should be tweaked to suite your needs before applying:
|
||||
|
||||
```sh
|
||||
kubectl apply -f kubequery.yaml
|
||||
```
|
||||
|
||||
Check the status of the pod using the following command. Pod should be in Running Status.
|
||||
```sh
|
||||
kubectl get pods -n kubequery
|
||||
```
|
||||
|
||||
Validate the installation was successful by first executing:
|
||||
|
||||
```sh
|
||||
kubectl exec -it $(kubectl get pods -n kubequery -o jsonpath='{.items[0].metadata.name}') -n kubequery -- kubequeryi '.tables'
|
||||
```
|
||||
|
||||
Which should produce the following output:
|
||||
|
||||
```
|
||||
=> kubernetes_api_resources
|
||||
=> kubernetes_cluster_role_binding_subjects
|
||||
=> kubernetes_cluster_role_policy_rule
|
||||
=> kubernetes_config_maps
|
||||
=> kubernetes_cron_jobs
|
||||
=> kubernetes_csi_drivers
|
||||
=> kubernetes_csi_node_drivers
|
||||
=> kubernetes_daemon_set_containers
|
||||
...
|
||||
```
|
||||
|
||||
Queries can be run using kubequeryi on the deployed container:
|
||||
|
||||
```sh
|
||||
kubectl exec -it $(kubectl get pods -n kubequery -o jsonpath='{.items[0].metadata.name}') -n kubequery -- kubequeryi --line 'SELECT * FROM kubernetes_pods'
|
||||
```
|
||||
|
||||
Pod logs can be viewed using:
|
||||
```sh
|
||||
kubectl logs $(kubectl get pods -n kubequery -o jsonpath='{.items[0].metadata.name}') -n kubequery
|
||||
```
|
||||
|
||||
## Helm
|
||||
|
||||
[Helm](https://helm.sh) must be installed to use the charts. Please refer to Helm's [documentation](https://helm.sh/docs) to get started.
|
||||
|
||||
Once Helm has been set up correctly, add the repo as follows:
|
||||
|
||||
```sh
|
||||
helm repo add uptycs https://uptycs.github.io/kubequery
|
||||
```
|
||||
|
||||
If you had already added this repo earlier, run `helm repo update` to retrieve the latest versions of the packages. You can then run `helm search repo uptycs` to see the charts.
|
||||
|
||||
To install the kubequery chart:
|
||||
```sh
|
||||
helm install my-kubequery uptycs/kubequery
|
||||
```
|
||||
|
||||
To uninstall the chart:
|
||||
```sh
|
||||
helm delete my-kubequery
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## FAQ
|
||||
|
||||
### Use kubequery instead of Osquery in Kubernetes?
|
||||
|
||||
No. kubequery should to be deployed as a [Kubernetes Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/). Which means there will be one [Pod](https://kubernetes.io/docs/concepts/workloads/pods/) of kubequery running per Kubernetes cluster. Osquery should be deployed to every node in the cluster. Querying most Osquery tables from an ephemeral pod does not provide much value. kubequery container image also runs as non-root user, which means most of the Osquery tables will either return an error or partial data.
|
||||
|
||||
![Deployment](docs/deployment.svg)
|
||||
|
||||
### Why are some columns JSON?
|
||||
|
||||
Normalizing nested JSON data like Kubernetes API responses will create an explosion of tables. So some of the columns in kuberenetes tables are left as JSON. Data is eventually processed by [SQLite](https://www.sqlite.org/index.html) with-in Osquery. SQLite has very [good JSON](https://www.sqlite.org/json1.html) support.
|
||||
|
||||
For example if `run_as_user` in `kubernetes_pod_security_policies` table looks like the following:
|
||||
```json
|
||||
{"rule": "MustRunAsNonRoot"}
|
||||
```
|
||||
|
||||
To get the value of `rule`, the following query can be used:
|
||||
```sql
|
||||
SELECT value AS 'rule'
|
||||
FROM kubernetes_pod_security_policies, json_tree(kubernetes_pod_security_policies.run_as_user)
|
||||
WHERE key = 'rule';
|
||||
|
||||
+------------------+
|
||||
| rule |
|
||||
+------------------+
|
||||
| MustRunAsNonRoot |
|
||||
+------------------+
|
||||
```
|
||||
|
||||
[json_each](https://www.sqlite.org/json1.html#jeach) can be used to explode JSON array types. For example if `volumes` in `kubernetes_pod_security_policies` table looks like the following:
|
||||
```json
|
||||
{"volumes": ["configMap","emptyDir","projected","secret","downwardAPI","persistentVolumeClaim"]}
|
||||
```
|
||||
|
||||
To get a separate row for each volume, the following query can be used:
|
||||
```sql
|
||||
SELECT value
|
||||
FROM kubernetes_pod_security_policies, json_each(kubernetes_pod_security_policies.volumes);
|
||||
|
||||
+-----------------------+
|
||||
| value |
|
||||
+-----------------------+
|
||||
| configMap |
|
||||
| emptyDir |
|
||||
| projected |
|
||||
| secret |
|
||||
| downwardAPI |
|
||||
| persistentVolumeClaim |
|
||||
+-----------------------+
|
||||
```
|
||||
|
||||
Osquery logger's like TLS, Kafka loggers can be used to export scheduled query data to remove fleet management/security analytics platforms. Lamba like functions can be applied on rows of streaming data in these platforms. These lamba functions can extract necessary fields from embedded JSON to detect compliance issues or security concerns. If tables are normalized and are streamed at different schedules, it will not be trivial to JOIN across tables and trigger events/alerts.
|
15
infrastructure/kubequery/SECURITY.md
Normal file
15
infrastructure/kubequery/SECURITY.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 1.1.1 | :white_check_mark: |
|
||||
| 1.1.0 | :white_check_mark: |
|
||||
| 1.0.0 | :white_check_mark: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please report vulnerabilties to [kubequery@uptycs.com](mailto:kubequery@uptycs.com).
|
||||
We will evaluate the details and get back ASAP.
|
||||
We are working on creating other communication channels for kubequery developers and users.
|
28
infrastructure/kubequery/bin/entrypoint.sh
Executable file
28
infrastructure/kubequery/bin/entrypoint.sh
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
|
||||
UUID=$(/opt/uptycs/bin/uuidgen)
|
||||
if [ $? -eq 0 ]; then
|
||||
# Use kube-system UUID as the host identifier
|
||||
ADDITIONAL_FLAGS="--host_identifier=specified --specified_identifier=${UUID}"
|
||||
fi
|
||||
|
||||
if [ -d /opt/uptycs/config ]; then
|
||||
# Copy bootstrap flags and configuration from volume mount
|
||||
cp /opt/uptycs/config/* /opt/uptycs/etc/
|
||||
fi
|
||||
|
||||
exec /opt/uptycs/bin/basequery \
|
||||
--flagfile=/opt/uptycs/etc/kubequery.flags \
|
||||
--config_path=/opt/uptycs/etc/kubequery.conf \
|
||||
--database_path=/opt/uptycs/kubequery.db \
|
||||
--logger_path=/opt/uptycs/logs \
|
||||
--pidfile=/opt/uptycs/var/kubequery.pid \
|
||||
--disable_watchdog \
|
||||
--enroll_tables=osquery_info,kubernetes_info \
|
||||
${ADDITIONAL_FLAGS} \
|
||||
--tls_user_agent=kubequery/${KUBEQUERY_VERSION} \
|
||||
--extensions_socket=/opt/uptycs/var/kubequery.em \
|
||||
--extensions_autoload=/opt/uptycs/etc/autoload.exts \
|
||||
--extensions_require=kubequery \
|
||||
--extension_event_tables=kubernetes_events \
|
||||
-D
|
13
infrastructure/kubequery/bin/kubequeryi
Executable file
13
infrastructure/kubequery/bin/kubequeryi
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
/opt/uptycs/bin/basequery \
|
||||
--flagfile=/opt/uptycs/etc/kubequery.flags \
|
||||
--config_path=/opt/uptycs/etc/kubequery.conf \
|
||||
--extensions_socket=/opt/uptycs/var/kubequeryi.em \
|
||||
--extensions_autoload=/opt/uptycs/etc/autoload.exts \
|
||||
--extensions_require=kubequery \
|
||||
--extension_event_tables=kubernetes_events \
|
||||
--disable_database \
|
||||
--disable_events=false \
|
||||
-S \
|
||||
"$@"
|
34
infrastructure/kubequery/charts/kubequery/.helmignore
Normal file
34
infrastructure/kubequery/charts/kubequery/.helmignore
Normal file
@ -0,0 +1,34 @@
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
# Patterns to ignore when building packages.
|
||||
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
16
infrastructure/kubequery/charts/kubequery/Chart.yaml
Normal file
16
infrastructure/kubequery/charts/kubequery/Chart.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
apiVersion: v2
|
||||
|
||||
name: kubequery
|
||||
description: kubequery powered by Osquery
|
||||
|
||||
type: application
|
||||
version: 1.1.1
|
||||
appVersion: 1.1.1
|
||||
icon: https://raw.githubusercontent.com/Uptycs/kubequery/master/docs/kubequery.png
|
@ -0,0 +1,55 @@
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "kubequery.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "kubequery.fullname" -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "kubequery.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "kubequery.labels" -}}
|
||||
helm.sh/chart: {{ include "kubequery.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/part-of: kubequery
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "kubequery.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "kubequery.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-clusterrole
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ .Release.Name }}-clusterrole
|
||||
{{- include "kubequery.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups: ["", "admissionregistration.k8s.io", "apps", "autoscaling", "batch", "events.k8s.io", "networking.k8s.io", "policy", "rbac.authorization.k8s.io", "storage.k8s.io"]
|
||||
resources: ["*"]
|
||||
verbs: ["get", "list", "watch"]
|
@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-clusterrolebinding
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ .Release.Name }}-clusterrolebinding
|
||||
{{- include "kubequery.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: {{ .Release.Name }}-clusterrole
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .Release.Name }}-serviceaccount
|
||||
namespace: {{ .Values.namespace }}
|
@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-configmap
|
||||
namespace: {{ .Values.namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ .Release.Name }}-configmap
|
||||
{{- include "kubequery.labels" . | nindent 4 }}
|
||||
data:
|
||||
{{- range $name, $config := .Values.config }}
|
||||
{{ $name }}: |-
|
||||
{{ tpl $config $ | indent 4 }}
|
||||
{{- end }}
|
@ -0,0 +1,64 @@
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "kubequery.fullname" . }}
|
||||
namespace: {{ .Values.namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ .Release.Name }}-deployment
|
||||
{{- include "kubequery.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "kubequery.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "kubequery.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
hostname: {{ .Values.cluster }}
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
fsGroup: 1000
|
||||
terminationGracePeriodSeconds: 10
|
||||
serviceAccountName: {{ .Release.Name }}-serviceaccount
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
{{- with .Values.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /opt/uptycs/config
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: {{ .Release.Name }}-configmap
|
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: {{ .Values.namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ .Values.namespace }}
|
||||
{{- include "kubequery.labels" . | nindent 4 }}
|
@ -0,0 +1,15 @@
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-serviceaccount
|
||||
namespace: {{ .Values.namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ .Release.Name }}-serviceaccount
|
||||
{{- include "kubequery.labels" . | nindent 4 }}
|
247
infrastructure/kubequery/charts/kubequery/values.yaml
Normal file
247
infrastructure/kubequery/charts/kubequery/values.yaml
Normal file
@ -0,0 +1,247 @@
|
||||
# Copyright (c) 2020-present, The kubequery authors
|
||||
#
|
||||
# This source code is licensed as defined by the LICENSE file found in the
|
||||
# root directory of this source tree.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
|
||||
# Namespace to deploy into
|
||||
namespace: kubequery
|
||||
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
image:
|
||||
repository: uptycs/kubequery
|
||||
pullPolicy: IfNotPresent
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
tag: ""
|
||||
|
||||
# Cluster name
|
||||
cluster: mycluster
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 512Mi
|
||||
|
||||
# kubequery configuration
|
||||
config:
|
||||
# TLS enroll secret
|
||||
enroll.secret: TODO
|
||||
|
||||
# Flags
|
||||
kubequery.flags: |-
|
||||
--schedule_splay_percent=50
|
||||
|
||||
# Config
|
||||
kubequery.conf: |-
|
||||
{
|
||||
"schedule": {
|
||||
"kubernetes_api_resources": {
|
||||
"query": "SELECT * FROM kubernetes_api_resources",
|
||||
"interval": 43200
|
||||
},
|
||||
"kubernetes_cluster_role_policy_rules": {
|
||||
"query": "SELECT * FROM kubernetes_cluster_role_policy_rules",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_cluster_role_binding_subjects": {
|
||||
"query": "SELECT * FROM kubernetes_cluster_role_binding_subjects",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_component_statuses": {
|
||||
"query": "SELECT * FROM kubernetes_component_statuses",
|
||||
"interval": 3600
|
||||
},
|
||||
"kubernetes_config_maps": {
|
||||
"query": "SELECT * FROM kubernetes_config_maps",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_cron_jobs": {
|
||||
"query": "SELECT * FROM kubernetes_cron_jobs",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_csi_drivers": {
|
||||
"query": "SELECT * FROM kubernetes_csi_drivers",
|
||||
"interval": 43200
|
||||
},
|
||||
"kubernetes_csi_node_drivers": {
|
||||
"query": "SELECT * FROM kubernetes_csi_node_drivers",
|
||||
"interval": 43200
|
||||
},
|
||||
"kubernetes_daemon_set_containers": {
|
||||
"query": "SELECT * FROM kubernetes_daemon_set_containers",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_daemon_sets": {
|
||||
"query": "SELECT * FROM kubernetes_daemon_sets",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_daemon_set_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_daemon_set_volumes",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_deployments": {
|
||||
"query": "SELECT * FROM kubernetes_deployments",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_deployments_containers": {
|
||||
"query": "SELECT * FROM kubernetes_deployments_containers",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_deployments_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_deployments_volumes",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_endpoint_subsets": {
|
||||
"query": "SELECT * FROM kubernetes_endpoint_subsets",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_horizontal_pod_autoscalers": {
|
||||
"query": "SELECT * FROM kubernetes_horizontal_pod_autoscalers",
|
||||
"interval": 7200
|
||||
},
|
||||
"kubernetes_info": {
|
||||
"query": "SELECT * FROM kubernetes_info",
|
||||
"interval": 43200
|
||||
},
|
||||
"kubernetes_ingress_classes": {
|
||||
"query": "SELECT * FROM kubernetes_ingress_classes",
|
||||
"interval": 21600
|
||||
},
|
||||
"kubernetes_ingresses": {
|
||||
"query": "SELECT * FROM kubernetes_ingresses",
|
||||
"interval": 21600
|
||||
},
|
||||
"kubernetes_jobs": {
|
||||
"query": "SELECT * FROM kubernetes_jobs",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_limit_ranges": {
|
||||
"query": "SELECT * FROM kubernetes_limit_ranges",
|
||||
"interval": 21600
|
||||
},
|
||||
"kubernetes_mutating_webhooks": {
|
||||
"query": "SELECT * FROM kubernetes_mutating_webhooks",
|
||||
"interval": 7200
|
||||
},
|
||||
"kubernetes_namespaces": {
|
||||
"query": "SELECT * FROM kubernetes_namespaces",
|
||||
"interval": 3600
|
||||
},
|
||||
"kubernetes_network_policies": {
|
||||
"query": "SELECT * FROM kubernetes_network_policies",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_nodes": {
|
||||
"query": "SELECT * FROM kubernetes_nodes",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_persistent_volume_claims": {
|
||||
"query": "SELECT * FROM kubernetes_persistent_volume_claims",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_persistent_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_persistent_volumes",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_pod_containers": {
|
||||
"query": "SELECT * FROM kubernetes_pod_containers",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_pod_disruption_budgets": {
|
||||
"query": "SELECT * FROM kubernetes_pod_disruption_budgets",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_pods": {
|
||||
"query": "SELECT * FROM kubernetes_pods",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_pod_security_policies": {
|
||||
"query": "SELECT * FROM kubernetes_pod_security_policies",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_pod_template_containers": {
|
||||
"query": "SELECT * FROM kubernetes_pod_template_containers",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_pod_templates": {
|
||||
"query": "SELECT * FROM kubernetes_pod_templates",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_pod_templates_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_pod_templates_volumes",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_pod_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_pod_volumes",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_replica_set_containers": {
|
||||
"query": "SELECT * FROM kubernetes_replica_set_containers",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_replica_sets": {
|
||||
"query": "SELECT * FROM kubernetes_replica_sets",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_replica_set_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_replica_set_volumes",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_resource_quotas": {
|
||||
"query": "SELECT * FROM kubernetes_resource_quotas",
|
||||
"interval": 3600
|
||||
},
|
||||
"kubernetes_role_binding_subjects": {
|
||||
"query": "SELECT * FROM kubernetes_role_binding_subjects",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_role_policy_rules": {
|
||||
"query": "SELECT * FROM kubernetes_role_policy_rules",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_secrets": {
|
||||
"query": "SELECT * FROM kubernetes_secrets",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_service_accounts": {
|
||||
"query": "SELECT * FROM kubernetes_service_accounts",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_services": {
|
||||
"query": "SELECT * FROM kubernetes_services",
|
||||
"interval": 900
|
||||
},
|
||||
"kubernetes_stateful_set_containers": {
|
||||
"query": "SELECT * FROM kubernetes_stateful_set_containers",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_stateful_sets": {
|
||||
"query": "SELECT * FROM kubernetes_stateful_sets",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_stateful_set_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_stateful_set_volumes",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_storage_classes": {
|
||||
"query": "SELECT * FROM kubernetes_storage_classes",
|
||||
"interval": 21600
|
||||
},
|
||||
"kubernetes_validating_webhooks": {
|
||||
"query": "SELECT * FROM kubernetes_validating_webhooks",
|
||||
"interval": 7200
|
||||
},
|
||||
"kubernetes_volume_attachments": {
|
||||
"query": "SELECT * FROM kubernetes_volume_attachments",
|
||||
"interval": 3600
|
||||
}
|
||||
},
|
||||
"options":{
|
||||
}
|
||||
}
|
30
infrastructure/kubequery/cmd/genschema/main.go
Normal file
30
infrastructure/kubequery/cmd/genschema/main.go
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Uptycs/kubequery/internal/k8s/tables"
|
||||
)
|
||||
|
||||
func main() {
|
||||
for _, t := range tables.GetTables() {
|
||||
fmt.Printf("CREATE TABLE %s (\n", t.Name)
|
||||
for i, c := range t.Columns {
|
||||
fmt.Printf(" `%s` %s", c.Name, c.Type)
|
||||
if i < len(t.Columns)-1 {
|
||||
fmt.Printf(",")
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Print(");\n\n")
|
||||
}
|
||||
}
|
39
infrastructure/kubequery/cmd/gentables/main.go
Normal file
39
infrastructure/kubequery/cmd/gentables/main.go
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Uptycs/kubequery/internal/k8s/tables"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tbls := tables.GetTables()
|
||||
fmt.Printf("{\n \"tables\": [")
|
||||
for j, t := range tbls {
|
||||
fmt.Printf(" {\n \"name\": \"%s\",\n \"columns\": [\n", t.Name)
|
||||
for i, c := range t.Columns {
|
||||
fmt.Printf(" {\n \"name\": \"%s\",\n \"type\": \"%s\"\n", c.Name, c.Type)
|
||||
if i < len(t.Columns)-1 {
|
||||
fmt.Printf(" },\n")
|
||||
} else {
|
||||
fmt.Printf(" }\n")
|
||||
}
|
||||
}
|
||||
fmt.Printf(" ]\n")
|
||||
if j < len(tbls)-1 {
|
||||
fmt.Printf(" },\n")
|
||||
} else {
|
||||
fmt.Printf(" }\n")
|
||||
}
|
||||
}
|
||||
fmt.Printf(" ]\n}")
|
||||
}
|
98
infrastructure/kubequery/cmd/kubequery/main.go
Normal file
98
infrastructure/kubequery/cmd/kubequery/main.go
Normal file
@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
osquery "github.com/Uptycs/basequery-go"
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
"github.com/Uptycs/kubequery/internal/k8s/event"
|
||||
"github.com/Uptycs/kubequery/internal/k8s/tables"
|
||||
)
|
||||
|
||||
var (
|
||||
// VERSION set by compiler
|
||||
VERSION = "latest"
|
||||
|
||||
//lint:ignore U1000 Argument is required by basequery
|
||||
verbose = flag.Bool("verbose", false, "Whether to enable verbose logging")
|
||||
version = flag.Bool("version", false, "Prints kubequery version")
|
||||
socket = flag.String("socket", "", "Path to the extensions UNIX domain socket")
|
||||
timeout = flag.Int("timeout", 5, "Seconds to wait for autoloaded extensions")
|
||||
interval = flag.Int("interval", 5, "Seconds delay between connectivity checks")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
if *version {
|
||||
fmt.Println("kubequery version:", VERSION)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if *socket == "" {
|
||||
panic("Missing required --socket argument")
|
||||
}
|
||||
|
||||
err := k8s.Init()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Error connecting to kubernetes API server: %s", err))
|
||||
}
|
||||
|
||||
server, err := osquery.NewExtensionManagerServer(
|
||||
"kubequery",
|
||||
*socket,
|
||||
osquery.ServerVersion(VERSION),
|
||||
osquery.ServerTimeout(time.Second*time.Duration(*timeout)),
|
||||
osquery.ServerPingInterval(time.Second*time.Duration(*interval)),
|
||||
)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Error launching kubequery: %s", err))
|
||||
}
|
||||
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, os.Interrupt)
|
||||
|
||||
for _, t := range tables.GetTables() {
|
||||
server.RegisterPlugin(table.NewPlugin(t.Name, t.Columns, t.GenFunc))
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err := server.Run(); err != nil {
|
||||
panic(fmt.Sprintf("Failed to start extension manager server: %s", err))
|
||||
}
|
||||
syscall.Kill(syscall.Getpid(), syscall.SIGINT)
|
||||
}()
|
||||
|
||||
// Wait for the extension manager to start before sending events
|
||||
time.Sleep(time.Second * 5)
|
||||
|
||||
watcher, err := event.CreateEventWatcher(*socket, time.Second*time.Duration(*timeout))
|
||||
if err != nil {
|
||||
fmt.Println("Failed to create kubernetes event watcher: ", err)
|
||||
} else {
|
||||
watcher.Start()
|
||||
}
|
||||
|
||||
<-quit
|
||||
|
||||
if watcher != nil {
|
||||
watcher.Stop()
|
||||
}
|
||||
server.Shutdown(context.Background())
|
||||
}
|
33
infrastructure/kubequery/cmd/uuidgen/main.go
Normal file
33
infrastructure/kubequery/cmd/uuidgen/main.go
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := k8s.Init()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Error connecting to kubernetes API server: %s", err))
|
||||
}
|
||||
|
||||
options := v1.GetOptions{}
|
||||
ks, err := k8s.GetClient().CoreV1().Namespaces().Get(context.Background(), "kube-system", options)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Error getting kube-system namespace: %s", err))
|
||||
}
|
||||
|
||||
fmt.Print(ks.ObjectMeta.UID)
|
||||
}
|
3
infrastructure/kubequery/docs/deployment.svg
Normal file
3
infrastructure/kubequery/docs/deployment.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 38 KiB |
BIN
infrastructure/kubequery/docs/kubequery.png
Normal file
BIN
infrastructure/kubequery/docs/kubequery.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
2083
infrastructure/kubequery/docs/schema.md
Normal file
2083
infrastructure/kubequery/docs/schema.md
Normal file
File diff suppressed because it is too large
Load Diff
7970
infrastructure/kubequery/docs/tables.json
Normal file
7970
infrastructure/kubequery/docs/tables.json
Normal file
File diff suppressed because it is too large
Load Diff
206
infrastructure/kubequery/etc/kubequery.conf
Normal file
206
infrastructure/kubequery/etc/kubequery.conf
Normal file
@ -0,0 +1,206 @@
|
||||
{
|
||||
"schedule": {
|
||||
"kubernetes_api_resources": {
|
||||
"query": "SELECT * FROM kubernetes_api_resources",
|
||||
"interval": 43200
|
||||
},
|
||||
"kubernetes_cluster_role_policy_rules": {
|
||||
"query": "SELECT * FROM kubernetes_cluster_role_policy_rules",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_cluster_role_binding_subjects": {
|
||||
"query": "SELECT * FROM kubernetes_cluster_role_binding_subjects",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_component_statuses": {
|
||||
"query": "SELECT * FROM kubernetes_component_statuses",
|
||||
"interval": 3600
|
||||
},
|
||||
"kubernetes_config_maps": {
|
||||
"query": "SELECT * FROM kubernetes_config_maps",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_cron_jobs": {
|
||||
"query": "SELECT * FROM kubernetes_cron_jobs",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_csi_drivers": {
|
||||
"query": "SELECT * FROM kubernetes_csi_drivers",
|
||||
"interval": 43200
|
||||
},
|
||||
"kubernetes_csi_node_drivers": {
|
||||
"query": "SELECT * FROM kubernetes_csi_node_drivers",
|
||||
"interval": 43200
|
||||
},
|
||||
"kubernetes_daemon_set_containers": {
|
||||
"query": "SELECT * FROM kubernetes_daemon_set_containers",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_daemon_sets": {
|
||||
"query": "SELECT * FROM kubernetes_daemon_sets",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_daemon_set_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_daemon_set_volumes",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_deployments": {
|
||||
"query": "SELECT * FROM kubernetes_deployments",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_deployments_containers": {
|
||||
"query": "SELECT * FROM kubernetes_deployments_containers",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_deployments_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_deployments_volumes",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_endpoint_subsets": {
|
||||
"query": "SELECT * FROM kubernetes_endpoint_subsets",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_horizontal_pod_autoscalers": {
|
||||
"query": "SELECT * FROM kubernetes_horizontal_pod_autoscalers",
|
||||
"interval": 7200
|
||||
},
|
||||
"kubernetes_info": {
|
||||
"query": "SELECT * FROM kubernetes_info",
|
||||
"interval": 43200
|
||||
},
|
||||
"kubernetes_ingress_classes": {
|
||||
"query": "SELECT * FROM kubernetes_ingress_classes",
|
||||
"interval": 21600
|
||||
},
|
||||
"kubernetes_ingresses": {
|
||||
"query": "SELECT * FROM kubernetes_ingresses",
|
||||
"interval": 21600
|
||||
},
|
||||
"kubernetes_jobs": {
|
||||
"query": "SELECT * FROM kubernetes_jobs",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_limit_ranges": {
|
||||
"query": "SELECT * FROM kubernetes_limit_ranges",
|
||||
"interval": 21600
|
||||
},
|
||||
"kubernetes_mutating_webhooks": {
|
||||
"query": "SELECT * FROM kubernetes_mutating_webhooks",
|
||||
"interval": 7200
|
||||
},
|
||||
"kubernetes_namespaces": {
|
||||
"query": "SELECT * FROM kubernetes_namespaces",
|
||||
"interval": 3600
|
||||
},
|
||||
"kubernetes_network_policies": {
|
||||
"query": "SELECT * FROM kubernetes_network_policies",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_nodes": {
|
||||
"query": "SELECT * FROM kubernetes_nodes",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_persistent_volume_claims": {
|
||||
"query": "SELECT * FROM kubernetes_persistent_volume_claims",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_persistent_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_persistent_volumes",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_pod_containers": {
|
||||
"query": "SELECT * FROM kubernetes_pod_containers",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_pod_disruption_budgets": {
|
||||
"query": "SELECT * FROM kubernetes_pod_disruption_budgets",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_pods": {
|
||||
"query": "SELECT * FROM kubernetes_pods",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_pod_security_policies": {
|
||||
"query": "SELECT * FROM kubernetes_pod_security_policies",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_pod_template_containers": {
|
||||
"query": "SELECT * FROM kubernetes_pod_template_containers",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_pod_templates": {
|
||||
"query": "SELECT * FROM kubernetes_pod_templates",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_pod_templates_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_pod_templates_volumes",
|
||||
"interval": 1800
|
||||
},
|
||||
"kubernetes_pod_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_pod_volumes",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_replica_set_containers": {
|
||||
"query": "SELECT * FROM kubernetes_replica_set_containers",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_replica_sets": {
|
||||
"query": "SELECT * FROM kubernetes_replica_sets",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_replica_set_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_replica_set_volumes",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_resource_quotas": {
|
||||
"query": "SELECT * FROM kubernetes_resource_quotas",
|
||||
"interval": 3600
|
||||
},
|
||||
"kubernetes_role_binding_subjects": {
|
||||
"query": "SELECT * FROM kubernetes_role_binding_subjects",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_role_policy_rules": {
|
||||
"query": "SELECT * FROM kubernetes_role_policy_rules",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_secrets": {
|
||||
"query": "SELECT * FROM kubernetes_secrets",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_service_accounts": {
|
||||
"query": "SELECT * FROM kubernetes_service_accounts",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_services": {
|
||||
"query": "SELECT * FROM kubernetes_services",
|
||||
"interval": 900
|
||||
},
|
||||
"kubernetes_stateful_set_containers": {
|
||||
"query": "SELECT * FROM kubernetes_stateful_set_containers",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_stateful_sets": {
|
||||
"query": "SELECT * FROM kubernetes_stateful_sets",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_stateful_set_volumes": {
|
||||
"query": "SELECT * FROM kubernetes_stateful_set_volumes",
|
||||
"interval": 600
|
||||
},
|
||||
"kubernetes_storage_classes": {
|
||||
"query": "SELECT * FROM kubernetes_storage_classes",
|
||||
"interval": 21600
|
||||
},
|
||||
"kubernetes_validating_webhooks": {
|
||||
"query": "SELECT * FROM kubernetes_validating_webhooks",
|
||||
"interval": 7200
|
||||
},
|
||||
"kubernetes_volume_attachments": {
|
||||
"query": "SELECT * FROM kubernetes_volume_attachments",
|
||||
"interval": 3600
|
||||
}
|
||||
},
|
||||
"options":{
|
||||
}
|
||||
}
|
2
infrastructure/kubequery/etc/kubequery.flags
Normal file
2
infrastructure/kubequery/etc/kubequery.flags
Normal file
@ -0,0 +1,2 @@
|
||||
--disable_events_staging=true
|
||||
--schedule_splay_percent=50
|
9
infrastructure/kubequery/etc/kubequery.flags.tls
Normal file
9
infrastructure/kubequery/etc/kubequery.flags.tls
Normal file
@ -0,0 +1,9 @@
|
||||
--schedule_splay_percent=50
|
||||
--disable_watchdog=true
|
||||
--tls_hostname=z6c0b1jca0.execute-api.us-west-2.amazonaws.com
|
||||
--tls_server_certs=/opt/uptycs/etc/certs.pem
|
||||
--enroll_secret_path=/opt/uptycs/config/enroll.secret
|
||||
--enroll_tls_endpoint=/default/enroll
|
||||
--logger_plugin=tls
|
||||
--logger_tls_endpoint=/default/log
|
||||
--logger_tls_compress=true
|
58
infrastructure/kubequery/go.mod
Normal file
58
infrastructure/kubequery/go.mod
Normal file
@ -0,0 +1,58 @@
|
||||
module github.com/Uptycs/kubequery
|
||||
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/Uptycs/basequery-go v0.8.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/iancoleman/strcase v0.2.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616
|
||||
k8s.io/api v0.22.4
|
||||
k8s.io/apimachinery v0.22.4
|
||||
k8s.io/client-go v0.22.4
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.5.1 // indirect
|
||||
github.com/apache/thrift v0.15.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible // indirect
|
||||
github.com/go-logr/logr v1.2.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.11.0 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.32.1 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
golang.org/x/net v0.0.0-20211205041911-012df41ee64c // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect
|
||||
golang.org/x/tools v0.1.7 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
k8s.io/klog/v2 v2.30.0 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c // indirect
|
||||
k8s.io/utils v0.0.0-20211203121628-587287796c64 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.0 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
647
infrastructure/kubequery/go.sum
Normal file
647
infrastructure/kubequery/go.sum
Normal file
@ -0,0 +1,647 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
|
||||
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Uptycs/basequery-go v0.8.0 h1:a1g1ikKKOCnHGzqxfiXsvquUJU5hNcZkjtfTJXcEKcg=
|
||||
github.com/Uptycs/basequery-go v0.8.0/go.mod h1:U46Bme4Zi+bKG+wYVw2XFfk3bHs0WWzpWQ2R+ivgEd4=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/apache/thrift v0.14.2/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.15.0 h1:aGvdaR0v1t9XLgjtBYwxcBvBOTMqClzwE26CHOgjW1Y=
|
||||
github.com/apache/thrift v0.15.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.1 h1:DX7uPQ4WgAWfoh+NGGlbJQswnYIVvz0SRlLS3rPZQDA=
|
||||
github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
|
||||
github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=
|
||||
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
|
||||
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
|
||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211205041911-012df41ee64c h1:7SfqwP5fxEtl/P02w5IhKc86ziJ+A25yFrkVgoy2FT8=
|
||||
golang.org/x/net v0.0.0-20211205041911-012df41ee64c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E=
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 h1:GZokNIeuVkl3aZHJchRrr13WCsols02MLUcz1U9is6M=
|
||||
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.22.4 h1:UvyHW0ezB2oIgHAxlYoo6UJQObYXU7awuNarwoHEOjw=
|
||||
k8s.io/api v0.22.4/go.mod h1:Rgs+9gIGYC5laXQSZZ9JqT5NevNgoGiOdVWi1BAB3qk=
|
||||
k8s.io/apimachinery v0.22.4 h1:9uwcvPpukBw/Ri0EUmWz+49cnFtaoiyEhQTK+xOe7Ck=
|
||||
k8s.io/apimachinery v0.22.4/go.mod h1:yU6oA6Gnax9RrxGzVvPFFJ+mpnW6PBSqp0sx0I0HHW0=
|
||||
k8s.io/client-go v0.22.4 h1:aAQ1Wk+I3bjCNk35YWUqbaueqrIonkfDPJSPDDe8Kfg=
|
||||
k8s.io/client-go v0.22.4/go.mod h1:Yzw4e5e7h1LNHA4uqnMVrpEpUs1hJOiuBsJKIlRCHDA=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw=
|
||||
k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c h1:jvamsI1tn9V0S8jicyX82qaFC0H/NKxv2e5mbqsgR80=
|
||||
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
|
||||
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20211203121628-587287796c64 h1:EzpFOlqWaj9Qbd/q4TqWSSpaQ/3p30lV1hGvcMYKLWc=
|
||||
k8s.io/utils v0.0.0-20211203121628-587287796c64/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.0 h1:kDvPBbnPk+qYmkHmSo8vKGp438IASWofnbbUKDE/bv0=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.0/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
94
infrastructure/kubequery/integration/index.js
Normal file
94
infrastructure/kubequery/integration/index.js
Normal file
@ -0,0 +1,94 @@
|
||||
'use strict';
|
||||
|
||||
const util = require('util');
|
||||
const execFile = util.promisify(require('child_process').execFile);
|
||||
|
||||
const EXEC_OPTIONS = { timeout: 10000, maxBuffer: 10 * 1024 * 1024 };
|
||||
|
||||
const TABLES = [
|
||||
'api_resources',
|
||||
'cluster_role_binding_subjects',
|
||||
'cluster_role_policy_rules',
|
||||
'component_statuses',
|
||||
'config_maps',
|
||||
'cron_jobs',
|
||||
'csi_drivers',
|
||||
'csi_node_drivers',
|
||||
'daemon_set_containers',
|
||||
'daemon_set_volumes',
|
||||
'daemon_sets',
|
||||
'deployments',
|
||||
'deployments_containers',
|
||||
'deployments_volumes',
|
||||
'endpoint_subsets',
|
||||
'events',
|
||||
'horizontal_pod_autoscalers',
|
||||
'info',
|
||||
'ingress_classes',
|
||||
'ingresses',
|
||||
'jobs',
|
||||
'limit_ranges',
|
||||
'mutating_webhooks',
|
||||
'namespaces',
|
||||
'network_policies',
|
||||
'nodes',
|
||||
'persistent_volume_claims',
|
||||
'persistent_volumes',
|
||||
'pod_containers',
|
||||
'pod_disruption_budgets',
|
||||
'pod_security_policies',
|
||||
'pod_template_containers',
|
||||
'pod_templates',
|
||||
'pod_templates_volumes',
|
||||
'pod_volumes',
|
||||
'pods',
|
||||
'replica_set_containers',
|
||||
'replica_set_volumes',
|
||||
'replica_sets',
|
||||
'resource_quotas',
|
||||
'role_binding_subjects',
|
||||
'role_policy_rules',
|
||||
'secrets',
|
||||
'service_accounts',
|
||||
'services',
|
||||
'stateful_set_containers',
|
||||
'stateful_set_volumes',
|
||||
'stateful_sets',
|
||||
'storage_classes',
|
||||
'validating_webhooks',
|
||||
'volume_attachments'
|
||||
];
|
||||
|
||||
async function getPodName() {
|
||||
const { stdout, stderr } = await execFile('kubectl', ['get', 'pods', '-n', 'kubequery', '-o', "jsonpath={.items[0].metadata.name}"], EXEC_OPTIONS);
|
||||
if (stdout) {
|
||||
return stdout;
|
||||
}
|
||||
throw new Error('Failed to get kubequery pod name');
|
||||
}
|
||||
|
||||
async function executeSQL(podName, sql) {
|
||||
const { stdout, stderr } = await execFile('kubectl', ['exec', '-it', podName, '-n', 'kubequery', '--', 'sh', '-c', `kubequeryi --json '${sql}'`], EXEC_OPTIONS);
|
||||
if (stdout) {
|
||||
return stdout;
|
||||
}
|
||||
throw new Error('Failed to execute SQL: ' + sql + '. Error: ' + stderr);
|
||||
}
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const podName = await getPodName();
|
||||
for (const table of TABLES) {
|
||||
const output = await executeSQL(podName, 'SELECT * FROM kubernetes_' + table);
|
||||
console.assert(output !== '', 'Invalid output for table: ' + table);
|
||||
|
||||
const json = JSON.parse(output);
|
||||
console.assert(Array.isArray(json), 'Table output is not an array: ' + table);
|
||||
|
||||
console.info(table + ': ' + json.length);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package admissionregistration
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/admissionregistration/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
type mutatingWebhook struct {
|
||||
ClusterName string
|
||||
ClusterUID types.UID
|
||||
v1.MutatingWebhook
|
||||
}
|
||||
|
||||
// MutatingWebhookColumns returns kubernetes mutating webhook fields as Osquery table columns.
|
||||
func MutatingWebhookColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&mutatingWebhook{})
|
||||
}
|
||||
|
||||
// MutatingWebhooksGenerate generates the mutating webhook Osquery table data.
|
||||
func MutatingWebhooksGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
mwcs, err := k8s.GetClient().AdmissionregistrationV1().MutatingWebhookConfigurations().List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, mwc := range mwcs.Items {
|
||||
for _, mw := range mwc.Webhooks {
|
||||
item := &mutatingWebhook{
|
||||
ClusterName: k8s.GetClusterName(),
|
||||
ClusterUID: k8s.GetClusterUID(),
|
||||
MutatingWebhook: mw,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if mwcs.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = mwcs.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package admissionregistration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/admissionregistration/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
|
||||
func TestMutatingWebhooksGenerate(t *testing.T) {
|
||||
i32 := int32(123)
|
||||
url := string("https://www.google.com")
|
||||
k8s.SetClient(fake.NewSimpleClientset(&v1.MutatingWebhookConfiguration{
|
||||
Webhooks: []v1.MutatingWebhook{
|
||||
{
|
||||
Name: "mw1",
|
||||
TimeoutSeconds: &i32,
|
||||
ClientConfig: v1.WebhookClientConfig{URL: &url},
|
||||
},
|
||||
{
|
||||
Name: "mw2",
|
||||
TimeoutSeconds: &i32,
|
||||
ClientConfig: v1.WebhookClientConfig{URL: &url},
|
||||
},
|
||||
},
|
||||
}), types.UID(""), "")
|
||||
|
||||
mws, err := MutatingWebhooksGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"name": "mw1",
|
||||
"timeout_seconds": "123",
|
||||
"client_config": "{\"url\":\"https://www.google.com\"}",
|
||||
},
|
||||
{
|
||||
"name": "mw2",
|
||||
"timeout_seconds": "123",
|
||||
"client_config": "{\"url\":\"https://www.google.com\"}",
|
||||
},
|
||||
}, mws)
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package admissionregistration
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/admissionregistration/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
type validatingWebhook struct {
|
||||
ClusterName string
|
||||
ClusterUID types.UID
|
||||
v1.ValidatingWebhook
|
||||
}
|
||||
|
||||
// ValidatingWebhookColumns returns kubernetes validating webhook fields as Osquery table columns.
|
||||
func ValidatingWebhookColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&validatingWebhook{})
|
||||
}
|
||||
|
||||
// ValidatingWebhooksGenerate generates the kubernetes validating webhooks as Osquery table data.
|
||||
func ValidatingWebhooksGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
vwcs, err := k8s.GetClient().AdmissionregistrationV1().ValidatingWebhookConfigurations().List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, vwc := range vwcs.Items {
|
||||
for _, vw := range vwc.Webhooks {
|
||||
item := &validatingWebhook{
|
||||
ClusterName: k8s.GetClusterName(),
|
||||
ClusterUID: k8s.GetClusterUID(),
|
||||
ValidatingWebhook: vw,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if vwcs.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = vwcs.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package admissionregistration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/admissionregistration/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
|
||||
func TestValidatingWebhooksGenerate(t *testing.T) {
|
||||
i32 := int32(123)
|
||||
url := string("https://www.google.com")
|
||||
k8s.SetClient(fake.NewSimpleClientset(&v1.ValidatingWebhookConfiguration{
|
||||
Webhooks: []v1.ValidatingWebhook{
|
||||
{
|
||||
Name: "vw1",
|
||||
TimeoutSeconds: &i32,
|
||||
ClientConfig: v1.WebhookClientConfig{URL: &url},
|
||||
},
|
||||
{
|
||||
Name: "vw2",
|
||||
TimeoutSeconds: &i32,
|
||||
ClientConfig: v1.WebhookClientConfig{URL: &url},
|
||||
},
|
||||
},
|
||||
}), types.UID(""), "")
|
||||
|
||||
mws, err := ValidatingWebhooksGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"name": "vw1",
|
||||
"timeout_seconds": "123",
|
||||
"client_config": "{\"url\":\"https://www.google.com\"}",
|
||||
},
|
||||
{
|
||||
"name": "vw2",
|
||||
"timeout_seconds": "123",
|
||||
"client_config": "{\"url\":\"https://www.google.com\"}",
|
||||
},
|
||||
}, mws)
|
||||
}
|
175
infrastructure/kubequery/internal/k8s/apps/daemon_set.go
Normal file
175
infrastructure/kubequery/internal/k8s/apps/daemon_set.go
Normal file
@ -0,0 +1,175 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package apps
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type daemonSet struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonPodFields
|
||||
v1.DaemonSetStatus
|
||||
Selector *metav1.LabelSelector
|
||||
UpdateStrategy v1.DaemonSetUpdateStrategy
|
||||
MinReadySeconds int32
|
||||
RevisionHistoryLimit *int32
|
||||
}
|
||||
|
||||
// DaemonSetColumns returns kubernetes daemon set fields as Osquery table columns.
|
||||
func DaemonSetColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&daemonSet{})
|
||||
}
|
||||
|
||||
// DaemonSetsGenerate generates the kubernetes daemon sets as Osquery table data.
|
||||
func DaemonSetsGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
dss, err := k8s.GetClient().AppsV1().DaemonSets(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, ds := range dss.Items {
|
||||
item := &daemonSet{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(ds.ObjectMeta),
|
||||
CommonPodFields: k8s.GetCommonPodFields(ds.Spec.Template.Spec),
|
||||
DaemonSetStatus: ds.Status,
|
||||
Selector: ds.Spec.Selector,
|
||||
UpdateStrategy: ds.Spec.UpdateStrategy,
|
||||
MinReadySeconds: ds.Spec.MinReadySeconds,
|
||||
RevisionHistoryLimit: ds.Spec.RevisionHistoryLimit,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if dss.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = dss.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type daemonSetContainer struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonContainerFields
|
||||
DaemonSetName string
|
||||
ContainerType string
|
||||
}
|
||||
|
||||
// DaemonSetContainerColumns returns kubernetes daemon set container fields as Osquery table columns.
|
||||
func DaemonSetContainerColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&daemonSetContainer{})
|
||||
}
|
||||
|
||||
// DaemonSetContainersGenerate generates the kubernetes daemon set containers as Osquery table data.
|
||||
func DaemonSetContainersGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
dss, err := k8s.GetClient().AppsV1().DaemonSets(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, ds := range dss.Items {
|
||||
for _, c := range ds.Spec.Template.Spec.InitContainers {
|
||||
item := &daemonSetContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(ds.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonContainerFields(c),
|
||||
DaemonSetName: ds.Name,
|
||||
ContainerType: "init",
|
||||
}
|
||||
item.Name = c.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
for _, c := range ds.Spec.Template.Spec.Containers {
|
||||
item := &daemonSetContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(ds.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonContainerFields(c),
|
||||
DaemonSetName: ds.Name,
|
||||
ContainerType: "container",
|
||||
}
|
||||
item.Name = c.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
for _, c := range ds.Spec.Template.Spec.EphemeralContainers {
|
||||
item := &daemonSetContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(ds.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonEphemeralContainerFields(c),
|
||||
DaemonSetName: ds.Name,
|
||||
ContainerType: "ephemeral",
|
||||
}
|
||||
item.Name = c.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if dss.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = dss.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type daemonSetVolume struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonVolumeFields
|
||||
DaemonSetName string
|
||||
}
|
||||
|
||||
// DaemonSetVolumeColumns returns kubernetes daemon set volume fields as Osquery table columns.
|
||||
func DaemonSetVolumeColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&daemonSetVolume{})
|
||||
}
|
||||
|
||||
// DaemonSetVolumesGenerate generates the kubernetes daemon set volumes as Osquery table data.
|
||||
func DaemonSetVolumesGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
dss, err := k8s.GetClient().AppsV1().DaemonSets(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, ds := range dss.Items {
|
||||
for _, v := range ds.Spec.Template.Spec.Volumes {
|
||||
item := &daemonSetVolume{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(ds.ObjectMeta),
|
||||
CommonVolumeFields: k8s.GetCommonVolumeFields(v),
|
||||
DaemonSetName: ds.Name,
|
||||
}
|
||||
item.Name = v.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if dss.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = dss.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
324
infrastructure/kubequery/internal/k8s/apps/daemon_set_test.go
Normal file
324
infrastructure/kubequery/internal/k8s/apps/daemon_set_test.go
Normal file
@ -0,0 +1,324 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package apps
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDaemonSetsGenerate(t *testing.T) {
|
||||
dss, err := DaemonSetsGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "1610476216",
|
||||
"current_number_scheduled": "1",
|
||||
"desired_number_scheduled": "1",
|
||||
"dns_policy": "ClusterFirst",
|
||||
"host_ipc": "0",
|
||||
"host_network": "1",
|
||||
"host_pid": "0",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"min_ready_seconds": "0",
|
||||
"name": "calico-node",
|
||||
"namespace": "kube-system",
|
||||
"node_selector": "{\"kubernetes.io/os\":\"linux\"}",
|
||||
"number_available": "1",
|
||||
"number_misscheduled": "0",
|
||||
"number_ready": "1",
|
||||
"number_unavailable": "0",
|
||||
"observed_generation": "1",
|
||||
"priority_class_name": "system-node-critical",
|
||||
"restart_policy": "Always",
|
||||
"revision_history_limit": "10",
|
||||
"scheduler_name": "default-scheduler",
|
||||
"selector": "{\"matchLabels\":{\"k8s-app\":\"calico-node\"}}",
|
||||
"service_account_name": "calico-node",
|
||||
"termination_grace_period_seconds": "0",
|
||||
"tolerations": "[{\"operator\":\"Exists\",\"effect\":\"NoSchedule\"},{\"key\":\"CriticalAddonsOnly\",\"operator\":\"Exists\"},{\"operator\":\"Exists\",\"effect\":\"NoExecute\"}]",
|
||||
"uid": "e6fed7f0-f79a-464f-a3d2-b63247a1f590",
|
||||
"update_strategy": "{\"type\":\"RollingUpdate\",\"rollingUpdate\":{\"maxUnavailable\":1}}",
|
||||
"updated_number_scheduled": "1",
|
||||
},
|
||||
}, dss)
|
||||
}
|
||||
|
||||
func TestDaemonSetContainersGenerate(t *testing.T) {
|
||||
dss, err := DaemonSetContainersGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"cluster_uid": "blah",
|
||||
"command": "[\"/opt/cni/bin/calico-ipam\",\"-upgrade\"]",
|
||||
"container_type": "init",
|
||||
"creation_timestamp": "1610476216",
|
||||
"daemon_set_name": "calico-node",
|
||||
"env": "[{\"name\":\"KUBERNETES_NODE_NAME\",\"valueFrom\":{\"fieldRef\":{\"apiVersion\":\"v1\",\"fieldPath\":\"spec.nodeName\"}}},{\"name\":\"CALICO_NETWORKING_BACKEND\",\"valueFrom\":{\"configMapKeyRef\":{\"name\":\"calico-config\",\"key\":\"calico_backend\"}}}]",
|
||||
"image": "calico/cni:v3.13.2",
|
||||
"image_pull_policy": "IfNotPresent",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"name": "upgrade-ipam",
|
||||
"namespace": "kube-system",
|
||||
"privileged": "1",
|
||||
"stdin": "0",
|
||||
"stdin_once": "0",
|
||||
"termination_message_path": "/dev/termination-log",
|
||||
"termination_message_policy": "File",
|
||||
"tty": "0",
|
||||
"uid": "8b0b4bb2-1703-551e-9e14-af10886a5eec",
|
||||
"volume_mounts": "[{\"name\":\"host-local-net-dir\",\"mountPath\":\"/var/lib/cni/networks\"},{\"name\":\"cni-bin-dir\",\"mountPath\":\"/host/opt/cni/bin\"}]",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"cluster_uid": "blah",
|
||||
"command": "[\"/install-cni.sh\"]",
|
||||
"container_type": "init",
|
||||
"creation_timestamp": "1610476216",
|
||||
"daemon_set_name": "calico-node",
|
||||
"env": "[{\"name\":\"CNI_CONF_NAME\",\"value\":\"10-calico.conflist\"},{\"name\":\"CNI_NETWORK_CONFIG\",\"valueFrom\":{\"configMapKeyRef\":{\"name\":\"calico-config\",\"key\":\"cni_network_config\"}}},{\"name\":\"KUBERNETES_NODE_NAME\",\"valueFrom\":{\"fieldRef\":{\"apiVersion\":\"v1\",\"fieldPath\":\"spec.nodeName\"}}},{\"name\":\"CNI_MTU\",\"valueFrom\":{\"configMapKeyRef\":{\"name\":\"calico-config\",\"key\":\"veth_mtu\"}}},{\"name\":\"SLEEP\",\"value\":\"false\"},{\"name\":\"CNI_NET_DIR\",\"value\":\"/var/snap/microk8s/current/args/cni-network\"}]",
|
||||
"image": "calico/cni:v3.13.2",
|
||||
"image_pull_policy": "IfNotPresent",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"name": "install-cni",
|
||||
"namespace": "kube-system",
|
||||
"privileged": "1",
|
||||
"stdin": "0",
|
||||
"stdin_once": "0",
|
||||
"termination_message_path": "/dev/termination-log",
|
||||
"termination_message_policy": "File",
|
||||
"tty": "0",
|
||||
"uid": "e773308e-cb75-5c58-9d85-0b71c92f8a24",
|
||||
"volume_mounts": "[{\"name\":\"cni-bin-dir\",\"mountPath\":\"/host/opt/cni/bin\"},{\"name\":\"cni-net-dir\",\"mountPath\":\"/host/etc/cni/net.d\"}]",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"cluster_uid": "blah",
|
||||
"container_type": "init",
|
||||
"creation_timestamp": "1610476216",
|
||||
"daemon_set_name": "calico-node",
|
||||
"image": "calico/pod2daemon-flexvol:v3.13.2",
|
||||
"image_pull_policy": "IfNotPresent",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"name": "flexvol-driver",
|
||||
"namespace": "kube-system",
|
||||
"privileged": "1",
|
||||
"stdin": "0",
|
||||
"stdin_once": "0",
|
||||
"termination_message_path": "/dev/termination-log",
|
||||
"termination_message_policy": "File",
|
||||
"tty": "0",
|
||||
"uid": "8122bba4-1bdc-562f-9a01-96345dbc3e4c",
|
||||
"volume_mounts": "[{\"name\":\"flexvol-driver-host\",\"mountPath\":\"/host/driver\"}]",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"cluster_uid": "blah",
|
||||
"container_type": "container",
|
||||
"creation_timestamp": "1610476216",
|
||||
"daemon_set_name": "calico-node",
|
||||
"env": "[{\"name\":\"DATASTORE_TYPE\",\"value\":\"kubernetes\"},{\"name\":\"WAIT_FOR_DATASTORE\",\"value\":\"true\"},{\"name\":\"NODENAME\",\"valueFrom\":{\"fieldRef\":{\"apiVersion\":\"v1\",\"fieldPath\":\"spec.nodeName\"}}},{\"name\":\"CALICO_NETWORKING_BACKEND\",\"valueFrom\":{\"configMapKeyRef\":{\"name\":\"calico-config\",\"key\":\"calico_backend\"}}},{\"name\":\"CLUSTER_TYPE\",\"value\":\"k8s,bgp\"},{\"name\":\"IP\",\"value\":\"autodetect\"},{\"name\":\"IP_AUTODETECTION_METHOD\",\"value\":\"first-found\"},{\"name\":\"CALICO_IPV4POOL_VXLAN\",\"value\":\"Always\"},{\"name\":\"FELIX_IPINIPMTU\",\"valueFrom\":{\"configMapKeyRef\":{\"name\":\"calico-config\",\"key\":\"veth_mtu\"}}},{\"name\":\"CALICO_IPV4POOL_CIDR\",\"value\":\"10.1.0.0/16\"},{\"name\":\"CALICO_DISABLE_FILE_LOGGING\",\"value\":\"true\"},{\"name\":\"FELIX_DEFAULTENDPOINTTOHOSTACTION\",\"value\":\"ACCEPT\"},{\"name\":\"FELIX_IPV6SUPPORT\",\"value\":\"false\"},{\"name\":\"FELIX_LOGSEVERITYSCREEN\",\"value\":\"error\"},{\"name\":\"FELIX_HEALTHENABLED\",\"value\":\"true\"}]",
|
||||
"image": "calico/node:v3.13.2",
|
||||
"image_pull_policy": "IfNotPresent",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"liveness_probe": "{\"exec\":{\"command\":[\"/bin/calico-node\",\"-felix-live\"]},\"initialDelaySeconds\":10,\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":6}",
|
||||
"name": "calico-node",
|
||||
"namespace": "kube-system",
|
||||
"privileged": "1",
|
||||
"readiness_probe": "{\"exec\":{\"command\":[\"/bin/calico-node\",\"-felix-ready\"]},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}",
|
||||
"resource_requests": "{\"cpu\":\"250m\"}",
|
||||
"stdin": "0",
|
||||
"stdin_once": "0",
|
||||
"termination_message_path": "/dev/termination-log",
|
||||
"termination_message_policy": "File",
|
||||
"tty": "0",
|
||||
"uid": "7f7da4e6-2c04-5e4e-aedb-bd1e9e8e5469",
|
||||
"volume_mounts": "[{\"name\":\"lib-modules\",\"readOnly\":true,\"mountPath\":\"/lib/modules\"},{\"name\":\"xtables-lock\",\"mountPath\":\"/run/xtables.lock\"},{\"name\":\"var-run-calico\",\"mountPath\":\"/var/run/calico\"},{\"name\":\"var-lib-calico\",\"mountPath\":\"/var/lib/calico\"},{\"name\":\"policysync\",\"mountPath\":\"/var/run/nodeagent\"}]",
|
||||
},
|
||||
}, dss)
|
||||
}
|
||||
|
||||
func TestDaemonSetVolumesGenerate(t *testing.T) {
|
||||
dss, err := DaemonSetVolumesGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"aws_elastic_block_store_partition": "0",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "1610476216",
|
||||
"daemon_set_name": "calico-node",
|
||||
"gce_persistent_disk_partition": "0",
|
||||
"host_path_path": "/lib/modules",
|
||||
"iscsi_discovery_chap_auth": "0",
|
||||
"iscsi_lun": "0",
|
||||
"iscsi_session_chap_auth": "0",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"name": "lib-modules",
|
||||
"namespace": "kube-system",
|
||||
"scale_iossl_enabled": "0",
|
||||
"uid": "e6fed7f0-f79a-464f-a3d2-b63247a1f590",
|
||||
"volume_type": "host_path",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"aws_elastic_block_store_partition": "0",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "1610476216",
|
||||
"daemon_set_name": "calico-node",
|
||||
"gce_persistent_disk_partition": "0",
|
||||
"host_path_path": "/var/snap/microk8s/current/var/run/calico",
|
||||
"iscsi_discovery_chap_auth": "0",
|
||||
"iscsi_lun": "0",
|
||||
"iscsi_session_chap_auth": "0",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"name": "var-run-calico",
|
||||
"namespace": "kube-system",
|
||||
"scale_iossl_enabled": "0",
|
||||
"uid": "e6fed7f0-f79a-464f-a3d2-b63247a1f590",
|
||||
"volume_type": "host_path",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"aws_elastic_block_store_partition": "0",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "1610476216",
|
||||
"daemon_set_name": "calico-node",
|
||||
"gce_persistent_disk_partition": "0",
|
||||
"host_path_path": "/var/snap/microk8s/current/var/lib/calico",
|
||||
"iscsi_discovery_chap_auth": "0",
|
||||
"iscsi_lun": "0",
|
||||
"iscsi_session_chap_auth": "0",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"name": "var-lib-calico",
|
||||
"namespace": "kube-system",
|
||||
"scale_iossl_enabled": "0",
|
||||
"uid": "e6fed7f0-f79a-464f-a3d2-b63247a1f590",
|
||||
"volume_type": "host_path",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"aws_elastic_block_store_partition": "0",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "1610476216",
|
||||
"daemon_set_name": "calico-node",
|
||||
"gce_persistent_disk_partition": "0",
|
||||
"host_path_path": "/run/xtables.lock",
|
||||
"host_path_type": "FileOrCreate",
|
||||
"iscsi_discovery_chap_auth": "0",
|
||||
"iscsi_lun": "0",
|
||||
"iscsi_session_chap_auth": "0",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"name": "xtables-lock",
|
||||
"namespace": "kube-system",
|
||||
"scale_iossl_enabled": "0",
|
||||
"uid": "e6fed7f0-f79a-464f-a3d2-b63247a1f590",
|
||||
"volume_type": "host_path",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"aws_elastic_block_store_partition": "0",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "1610476216",
|
||||
"daemon_set_name": "calico-node",
|
||||
"gce_persistent_disk_partition": "0",
|
||||
"host_path_path": "/var/snap/microk8s/current/opt/cni/bin",
|
||||
"iscsi_discovery_chap_auth": "0",
|
||||
"iscsi_lun": "0",
|
||||
"iscsi_session_chap_auth": "0",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"name": "cni-bin-dir",
|
||||
"namespace": "kube-system",
|
||||
"scale_iossl_enabled": "0",
|
||||
"uid": "e6fed7f0-f79a-464f-a3d2-b63247a1f590",
|
||||
"volume_type": "host_path",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"aws_elastic_block_store_partition": "0",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "1610476216",
|
||||
"daemon_set_name": "calico-node",
|
||||
"gce_persistent_disk_partition": "0",
|
||||
"host_path_path": "/var/snap/microk8s/current/args/cni-network",
|
||||
"iscsi_discovery_chap_auth": "0",
|
||||
"iscsi_lun": "0",
|
||||
"iscsi_session_chap_auth": "0",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"name": "cni-net-dir",
|
||||
"namespace": "kube-system",
|
||||
"scale_iossl_enabled": "0",
|
||||
"uid": "e6fed7f0-f79a-464f-a3d2-b63247a1f590",
|
||||
"volume_type": "host_path",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"aws_elastic_block_store_partition": "0",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "1610476216",
|
||||
"daemon_set_name": "calico-node",
|
||||
"gce_persistent_disk_partition": "0",
|
||||
"host_path_path": "/var/snap/microk8s/current/var/lib/cni/networks",
|
||||
"iscsi_discovery_chap_auth": "0",
|
||||
"iscsi_lun": "0",
|
||||
"iscsi_session_chap_auth": "0",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"name": "host-local-net-dir",
|
||||
"namespace": "kube-system",
|
||||
"scale_iossl_enabled": "0",
|
||||
"uid": "e6fed7f0-f79a-464f-a3d2-b63247a1f590",
|
||||
"volume_type": "host_path",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"aws_elastic_block_store_partition": "0",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "1610476216",
|
||||
"daemon_set_name": "calico-node",
|
||||
"gce_persistent_disk_partition": "0",
|
||||
"host_path_path": "/var/snap/microk8s/current/var/run/nodeagent",
|
||||
"host_path_type": "DirectoryOrCreate",
|
||||
"iscsi_discovery_chap_auth": "0",
|
||||
"iscsi_lun": "0",
|
||||
"iscsi_session_chap_auth": "0",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"name": "policysync",
|
||||
"namespace": "kube-system",
|
||||
"scale_iossl_enabled": "0",
|
||||
"uid": "e6fed7f0-f79a-464f-a3d2-b63247a1f590",
|
||||
"volume_type": "host_path",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"deprecated.daemonset.template.generation\":\"1\"}",
|
||||
"aws_elastic_block_store_partition": "0",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "1610476216",
|
||||
"daemon_set_name": "calico-node",
|
||||
"gce_persistent_disk_partition": "0",
|
||||
"host_path_path": "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/nodeagent~uds",
|
||||
"host_path_type": "DirectoryOrCreate",
|
||||
"iscsi_discovery_chap_auth": "0",
|
||||
"iscsi_lun": "0",
|
||||
"iscsi_session_chap_auth": "0",
|
||||
"labels": "{\"k8s-app\":\"calico-node\"}",
|
||||
"name": "flexvol-driver-host",
|
||||
"namespace": "kube-system",
|
||||
"scale_iossl_enabled": "0",
|
||||
"uid": "e6fed7f0-f79a-464f-a3d2-b63247a1f590",
|
||||
"volume_type": "host_path",
|
||||
},
|
||||
}, dss)
|
||||
}
|
181
infrastructure/kubequery/internal/k8s/apps/deployment.go
Normal file
181
infrastructure/kubequery/internal/k8s/apps/deployment.go
Normal file
@ -0,0 +1,181 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package apps
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type deployment struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonPodFields
|
||||
v1.DeploymentStatus
|
||||
DeploymentReplicas *int32
|
||||
Selector *metav1.LabelSelector
|
||||
Strategy v1.DeploymentStrategy
|
||||
MinReadySeconds int32
|
||||
RevisionHistoryLimit *int32
|
||||
Paused bool
|
||||
ProgressDeadlineSeconds *int32
|
||||
}
|
||||
|
||||
// DeploymentColumns returns kubernetes deployment fields as Osquery table columns.
|
||||
func DeploymentColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&deployment{})
|
||||
}
|
||||
|
||||
// DeploymentsGenerate generates the kubernetes deployments as Osquery table data.
|
||||
func DeploymentsGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
ds, err := k8s.GetClient().AppsV1().Deployments(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, d := range ds.Items {
|
||||
item := &deployment{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(d.ObjectMeta),
|
||||
CommonPodFields: k8s.GetCommonPodFields(d.Spec.Template.Spec),
|
||||
DeploymentReplicas: d.Spec.Replicas,
|
||||
Selector: d.Spec.Selector,
|
||||
Strategy: d.Spec.Strategy,
|
||||
MinReadySeconds: d.Spec.MinReadySeconds,
|
||||
RevisionHistoryLimit: d.Spec.RevisionHistoryLimit,
|
||||
Paused: d.Spec.Paused,
|
||||
ProgressDeadlineSeconds: d.Spec.ProgressDeadlineSeconds,
|
||||
DeploymentStatus: d.Status,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if ds.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = ds.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type deploymentContainer struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonContainerFields
|
||||
DeploymentName string
|
||||
ContainerType string
|
||||
}
|
||||
|
||||
// DeploymentContainerColumns returns kubernetes deployment container fields as Osquery table columns.
|
||||
func DeploymentContainerColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&deploymentContainer{})
|
||||
}
|
||||
|
||||
// DeploymentContainersGenerate generates the kubernetes deployment containers as Osquery table data.
|
||||
func DeploymentContainersGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
ds, err := k8s.GetClient().AppsV1().Deployments(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, d := range ds.Items {
|
||||
for _, c := range d.Spec.Template.Spec.InitContainers {
|
||||
item := &deploymentContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(d.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonContainerFields(c),
|
||||
DeploymentName: d.Name,
|
||||
ContainerType: "init",
|
||||
}
|
||||
item.Name = c.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
for _, c := range d.Spec.Template.Spec.Containers {
|
||||
item := &deploymentContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(d.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonContainerFields(c),
|
||||
DeploymentName: d.Name,
|
||||
ContainerType: "container",
|
||||
}
|
||||
item.Name = c.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
for _, c := range d.Spec.Template.Spec.EphemeralContainers {
|
||||
item := &deploymentContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(d.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonEphemeralContainerFields(c),
|
||||
DeploymentName: d.Name,
|
||||
ContainerType: "ephemeral",
|
||||
}
|
||||
item.Name = c.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if ds.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = ds.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type deploymentVolume struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonVolumeFields
|
||||
DeploymentName string
|
||||
}
|
||||
|
||||
// DeploymentVolumeColumns returns kubernetes deployment volume fields as Osquery table columns.
|
||||
func DeploymentVolumeColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&deploymentVolume{})
|
||||
}
|
||||
|
||||
// DeploymentVolumesGenerate generates the kubernetes deployment volumes as Osquery table data.
|
||||
func DeploymentVolumesGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
ds, err := k8s.GetClient().AppsV1().Deployments(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, d := range ds.Items {
|
||||
for _, v := range d.Spec.Template.Spec.Volumes {
|
||||
item := &deploymentVolume{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(d.ObjectMeta),
|
||||
CommonVolumeFields: k8s.GetCommonVolumeFields(v),
|
||||
DeploymentName: d.Name,
|
||||
}
|
||||
item.Name = v.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if ds.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = ds.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package apps
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDeploymentsGenerate(t *testing.T) {
|
||||
ds, err := DeploymentsGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"available_replicas": "0",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "0",
|
||||
"host_ipc": "0",
|
||||
"host_network": "0",
|
||||
"host_pid": "0",
|
||||
"min_ready_seconds": "0",
|
||||
"observed_generation": "0",
|
||||
"paused": "0",
|
||||
"ready_replicas": "0",
|
||||
"replicas": "0",
|
||||
"strategy": "{}",
|
||||
"unavailable_replicas": "0",
|
||||
"updated_replicas": "0",
|
||||
},
|
||||
}, ds)
|
||||
}
|
||||
|
||||
func TestDeploymentContainersGenerate(t *testing.T) {
|
||||
ds, err := DeploymentContainersGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{}, ds)
|
||||
}
|
||||
|
||||
func TestDeploymentVolumesGenerate(t *testing.T) {
|
||||
ds, err := DeploymentVolumesGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{}, ds)
|
||||
}
|
47
infrastructure/kubequery/internal/k8s/apps/init_test.go
Normal file
47
infrastructure/kubequery/internal/k8s/apps/init_test.go
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package apps
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
|
||||
func loadTestResource(name string, v interface{}) {
|
||||
path := filepath.Join("testdata", name)
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
ds := &v1.DaemonSet{}
|
||||
loadTestResource("daemon_set_test.json", ds)
|
||||
d := &v1.Deployment{}
|
||||
loadTestResource("deployment_test.json", d)
|
||||
rs := &v1.ReplicaSet{}
|
||||
loadTestResource("replica_set_test.json", rs)
|
||||
ss := &v1.StatefulSet{}
|
||||
loadTestResource("stateful_set_test.json", ss)
|
||||
|
||||
k8s.SetClient(fake.NewSimpleClientset(ds, d, rs, ss), types.UID("blah"), "")
|
||||
}
|
173
infrastructure/kubequery/internal/k8s/apps/replica_set.go
Normal file
173
infrastructure/kubequery/internal/k8s/apps/replica_set.go
Normal file
@ -0,0 +1,173 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package apps
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type replicaSet struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonPodFields
|
||||
v1.ReplicaSetStatus
|
||||
ReplicaSetReplicas *int32
|
||||
MinReadySeconds int32
|
||||
Selector *metav1.LabelSelector
|
||||
}
|
||||
|
||||
// ReplicaSetColumns returns kubernetes replica set fields as Osquery table columns.
|
||||
func ReplicaSetColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&replicaSet{})
|
||||
}
|
||||
|
||||
// ReplicaSetsGenerate generates the kubernetes replica sets as Osquery table data.
|
||||
func ReplicaSetsGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
rss, err := k8s.GetClient().AppsV1().ReplicaSets(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, rs := range rss.Items {
|
||||
item := &replicaSet{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(rs.ObjectMeta),
|
||||
CommonPodFields: k8s.GetCommonPodFields(rs.Spec.Template.Spec),
|
||||
ReplicaSetStatus: rs.Status,
|
||||
ReplicaSetReplicas: rs.Spec.Replicas,
|
||||
MinReadySeconds: rs.Spec.MinReadySeconds,
|
||||
Selector: rs.Spec.Selector,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if rss.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = rss.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type replicaSetContainer struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonContainerFields
|
||||
ReplicaSetName string
|
||||
ContainerType string
|
||||
}
|
||||
|
||||
// ReplicaSetContainerColumns returns kubernetes replica set container fields as Osquery table columns.
|
||||
func ReplicaSetContainerColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&replicaSetContainer{})
|
||||
}
|
||||
|
||||
// ReplicaSetContainersGenerate generates the kubernetes replica set containers as Osquery table data.
|
||||
func ReplicaSetContainersGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
rss, err := k8s.GetClient().AppsV1().ReplicaSets(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, rs := range rss.Items {
|
||||
for _, c := range rs.Spec.Template.Spec.InitContainers {
|
||||
item := &replicaSetContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(rs.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonContainerFields(c),
|
||||
ReplicaSetName: rs.Name,
|
||||
ContainerType: "init",
|
||||
}
|
||||
item.Name = c.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
for _, c := range rs.Spec.Template.Spec.Containers {
|
||||
item := &replicaSetContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(rs.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonContainerFields(c),
|
||||
ReplicaSetName: rs.Name,
|
||||
ContainerType: "container",
|
||||
}
|
||||
item.Name = c.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
for _, c := range rs.Spec.Template.Spec.EphemeralContainers {
|
||||
item := &replicaSetContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(rs.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonEphemeralContainerFields(c),
|
||||
ReplicaSetName: rs.Name,
|
||||
ContainerType: "ephemeral",
|
||||
}
|
||||
item.Name = c.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if rss.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = rss.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type replicaSetVolume struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonVolumeFields
|
||||
ReplicaSetName string
|
||||
}
|
||||
|
||||
// ReplicaSetVolumeColumns returns kubernetes replica set volume fields as Osquery table columns.
|
||||
func ReplicaSetVolumeColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&replicaSetVolume{})
|
||||
}
|
||||
|
||||
// ReplicaSetVolumesGenerate generates the kubernetes replica set volumes as Osquery table data.
|
||||
func ReplicaSetVolumesGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
rss, err := k8s.GetClient().AppsV1().ReplicaSets(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, rs := range rss.Items {
|
||||
for _, v := range rs.Spec.Template.Spec.Volumes {
|
||||
item := &replicaSetVolume{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(rs.ObjectMeta),
|
||||
CommonVolumeFields: k8s.GetCommonVolumeFields(v),
|
||||
ReplicaSetName: rs.Name,
|
||||
}
|
||||
item.Name = v.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if rss.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = rss.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package apps
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestReplicaSetsGenerate(t *testing.T) {
|
||||
rss, err := ReplicaSetsGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"annotations": "{\"deployment.kubernetes.io/desired-replicas\":\"1\",\"deployment.kubernetes.io/max-replicas\":\"2\",\"deployment.kubernetes.io/revision\":\"1\"}",
|
||||
"available_replicas": "1",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "1611191304",
|
||||
"dns_policy": "ClusterFirst",
|
||||
"fully_labeled_replicas": "1",
|
||||
"host_ipc": "0",
|
||||
"host_network": "0",
|
||||
"host_pid": "0",
|
||||
"labels": "{\"name\":\"jaeger-operator\",\"pod-template-hash\":\"5db4f9d996\"}",
|
||||
"min_ready_seconds": "0",
|
||||
"name": "jaeger-operator-5db4f9d996",
|
||||
"namespace": "default",
|
||||
"observed_generation": "1",
|
||||
"ready_replicas": "1",
|
||||
"replica_set_replicas": "1",
|
||||
"replicas": "1",
|
||||
"restart_policy": "Always",
|
||||
"scheduler_name": "default-scheduler",
|
||||
"selector": "{\"matchLabels\":{\"name\":\"jaeger-operator\",\"pod-template-hash\":\"5db4f9d996\"}}",
|
||||
"service_account_name": "jaeger-operator",
|
||||
"termination_grace_period_seconds": "30",
|
||||
"uid": "2efeb411-ff99-434b-a5a2-4e06c2b0afaa",
|
||||
},
|
||||
}, rss)
|
||||
}
|
||||
|
||||
func TestReplicaSetContainersGenerate(t *testing.T) {
|
||||
rss, err := ReplicaSetContainersGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"annotations": "{\"deployment.kubernetes.io/desired-replicas\":\"1\",\"deployment.kubernetes.io/max-replicas\":\"2\",\"deployment.kubernetes.io/revision\":\"1\"}",
|
||||
"args": "[\"start\"]",
|
||||
"cluster_uid": "blah",
|
||||
"container_type": "container",
|
||||
"creation_timestamp": "1611191304",
|
||||
"env": "[{\"name\":\"WATCH_NAMESPACE\"},{\"name\":\"POD_NAME\",\"valueFrom\":{\"fieldRef\":{\"apiVersion\":\"v1\",\"fieldPath\":\"metadata.name\"}}},{\"name\":\"POD_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"apiVersion\":\"v1\",\"fieldPath\":\"metadata.namespace\"}}},{\"name\":\"OPERATOR_NAME\",\"value\":\"jaeger-operator\"}]",
|
||||
"image": "jaegertracing/jaeger-operator:1.14.0",
|
||||
"image_pull_policy": "Always",
|
||||
"labels": "{\"name\":\"jaeger-operator\",\"pod-template-hash\":\"5db4f9d996\"}",
|
||||
"name": "jaeger-operator",
|
||||
"namespace": "default",
|
||||
"ports": "[{\"name\":\"metrics\",\"containerPort\":8383,\"protocol\":\"TCP\"}]",
|
||||
"replica_set_name": "jaeger-operator-5db4f9d996",
|
||||
"stdin": "0",
|
||||
"stdin_once": "0",
|
||||
"termination_message_path": "/dev/termination-log",
|
||||
"termination_message_policy": "File",
|
||||
"tty": "0",
|
||||
"uid": "a9c84883-3d97-5b99-8b20-9fcd5e626a02",
|
||||
},
|
||||
}, rss)
|
||||
}
|
||||
|
||||
func TestReplicaSetVolumesGenerate(t *testing.T) {
|
||||
rss, err := ReplicaSetVolumesGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{}, rss)
|
||||
}
|
182
infrastructure/kubequery/internal/k8s/apps/stateful_set.go
Normal file
182
infrastructure/kubequery/internal/k8s/apps/stateful_set.go
Normal file
@ -0,0 +1,182 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authoss
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package apps
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type statefulSet struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonPodFields
|
||||
v1.StatefulSetStatus
|
||||
StatefulSetReplicas *int32
|
||||
Selector *metav1.LabelSelector
|
||||
VolumeClaimTemplates []corev1.PersistentVolumeClaim
|
||||
ServiceName string
|
||||
PodManagementPolicy v1.PodManagementPolicyType
|
||||
UpdateStrategy v1.StatefulSetUpdateStrategy
|
||||
RevisionHistoryLimit *int32
|
||||
}
|
||||
|
||||
// StatefulSetColumns returns kubernetes stateful set fields as Osquery table columns.
|
||||
func StatefulSetColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&statefulSet{})
|
||||
}
|
||||
|
||||
// StatefulSetsGenerate generates the kubernetes stateful sets as Osquery table data.
|
||||
func StatefulSetsGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
sss, err := k8s.GetClient().AppsV1().StatefulSets(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, ss := range sss.Items {
|
||||
item := &statefulSet{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(ss.ObjectMeta),
|
||||
CommonPodFields: k8s.GetCommonPodFields(ss.Spec.Template.Spec),
|
||||
StatefulSetStatus: ss.Status,
|
||||
StatefulSetReplicas: ss.Spec.Replicas,
|
||||
Selector: ss.Spec.Selector,
|
||||
VolumeClaimTemplates: ss.Spec.VolumeClaimTemplates,
|
||||
ServiceName: ss.Spec.ServiceName,
|
||||
PodManagementPolicy: ss.Spec.PodManagementPolicy,
|
||||
UpdateStrategy: ss.Spec.UpdateStrategy,
|
||||
RevisionHistoryLimit: ss.Spec.RevisionHistoryLimit,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if sss.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = sss.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type statefulSetContainer struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonContainerFields
|
||||
StatefulSetName string
|
||||
ContainerType string
|
||||
}
|
||||
|
||||
// StatefulSetContainerColumns returns kubernetes stateful set container fields as Osquery table columns.
|
||||
func StatefulSetContainerColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&statefulSetContainer{})
|
||||
}
|
||||
|
||||
// StatefulSetContainersGenerate generates the kubernetes stateful set containers as Osquery table data.
|
||||
func StatefulSetContainersGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
sss, err := k8s.GetClient().AppsV1().StatefulSets(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, ss := range sss.Items {
|
||||
for _, c := range ss.Spec.Template.Spec.InitContainers {
|
||||
item := &statefulSetContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(ss.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonContainerFields(c),
|
||||
StatefulSetName: ss.Name,
|
||||
ContainerType: "init",
|
||||
}
|
||||
item.Name = c.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
for _, c := range ss.Spec.Template.Spec.Containers {
|
||||
item := &statefulSetContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(ss.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonContainerFields(c),
|
||||
StatefulSetName: ss.Name,
|
||||
ContainerType: "container",
|
||||
}
|
||||
item.Name = c.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
for _, c := range ss.Spec.Template.Spec.EphemeralContainers {
|
||||
item := &statefulSetContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(ss.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonEphemeralContainerFields(c),
|
||||
StatefulSetName: ss.Name,
|
||||
ContainerType: "ephemeral",
|
||||
}
|
||||
item.Name = c.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if sss.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = sss.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type statefulSetVolume struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonVolumeFields
|
||||
StatefulSetName string
|
||||
}
|
||||
|
||||
// StatefulSetVolumeColumns returns kubernetes stateful set volume fields as Osquery table columns.
|
||||
func StatefulSetVolumeColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&statefulSetVolume{})
|
||||
}
|
||||
|
||||
// StatefulSetVolumesGenerate generates the kubernetes stateful set volumes as Osquery table data.
|
||||
func StatefulSetVolumesGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
sss, err := k8s.GetClient().AppsV1().StatefulSets(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, ss := range sss.Items {
|
||||
for _, v := range ss.Spec.Template.Spec.Volumes {
|
||||
item := &statefulSetVolume{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(ss.ObjectMeta),
|
||||
CommonVolumeFields: k8s.GetCommonVolumeFields(v),
|
||||
StatefulSetName: ss.Name,
|
||||
}
|
||||
item.Name = v.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if sss.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = sss.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
153
infrastructure/kubequery/internal/k8s/apps/stateful_set_test.go
Normal file
153
infrastructure/kubequery/internal/k8s/apps/stateful_set_test.go
Normal file
@ -0,0 +1,153 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package apps
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestStatefulSetsGenerate(t *testing.T) {
|
||||
sss, err := StatefulSetsGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"available_replicas": "0",
|
||||
"cluster_uid": "blah",
|
||||
"collision_count": "0",
|
||||
"creation_timestamp": "1611191592",
|
||||
"current_replicas": "1",
|
||||
"current_revision": "alertmanager-main-6674894c9d",
|
||||
"dns_policy": "ClusterFirst",
|
||||
"fs_group": "2000",
|
||||
"host_ipc": "0",
|
||||
"host_network": "0",
|
||||
"host_pid": "0",
|
||||
"labels": "{\"alertmanager\":\"main\"}",
|
||||
"name": "alertmanager-main",
|
||||
"namespace": "monitoring",
|
||||
"node_selector": "{\"kubernetes.io/os\":\"linux\"}",
|
||||
"observed_generation": "1",
|
||||
"pod_management_policy": "Parallel",
|
||||
"ready_replicas": "1",
|
||||
"replicas": "1",
|
||||
"restart_policy": "Always",
|
||||
"revision_history_limit": "10",
|
||||
"run_as_non_root": "1",
|
||||
"run_as_user": "1000",
|
||||
"scheduler_name": "default-scheduler",
|
||||
"selector": "{\"matchLabels\":{\"alertmanager\":\"main\",\"app\":\"alertmanager\"}}",
|
||||
"service_account_name": "alertmanager-main",
|
||||
"service_name": "alertmanager-operated",
|
||||
"stateful_set_replicas": "1",
|
||||
"termination_grace_period_seconds": "120",
|
||||
"uid": "3c488e7e-420c-4515-b377-5dc3ee082744",
|
||||
"update_revision": "alertmanager-main-6674894c9d",
|
||||
"update_strategy": "{\"type\":\"RollingUpdate\"}",
|
||||
"updated_replicas": "1",
|
||||
},
|
||||
}, sss)
|
||||
}
|
||||
|
||||
func TestStatefulSetContainersGenerate(t *testing.T) {
|
||||
sss, err := StatefulSetContainersGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"args": "[\"--config.file=/etc/alertmanager/config/alertmanager.yaml\",\"--storage.path=/alertmanager\",\"--data.retention=120h\",\"--cluster.listen-address=\",\"--web.listen-address=:9093\",\"--web.route-prefix=/\",\"--cluster.peer=alertmanager-main-0.alertmanager-operated:9094\"]",
|
||||
"cluster_uid": "blah",
|
||||
"container_type": "container",
|
||||
"creation_timestamp": "1611191592",
|
||||
"env": "[{\"name\":\"POD_IP\",\"valueFrom\":{\"fieldRef\":{\"apiVersion\":\"v1\",\"fieldPath\":\"status.podIP\"}}}]",
|
||||
"image": "quay.io/prometheus/alertmanager:v0.21.0",
|
||||
"image_pull_policy": "IfNotPresent",
|
||||
"labels": "{\"alertmanager\":\"main\"}",
|
||||
"liveness_probe": "{\"httpGet\":{\"path\":\"/-/healthy\",\"port\":\"web\",\"scheme\":\"HTTP\"},\"timeoutSeconds\":3,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":10}",
|
||||
"name": "alertmanager",
|
||||
"namespace": "monitoring",
|
||||
"ports": "[{\"name\":\"web\",\"containerPort\":9093,\"protocol\":\"TCP\"},{\"name\":\"mesh-tcp\",\"containerPort\":9094,\"protocol\":\"TCP\"},{\"name\":\"mesh-udp\",\"containerPort\":9094,\"protocol\":\"UDP\"}]",
|
||||
"readiness_probe": "{\"httpGet\":{\"path\":\"/-/ready\",\"port\":\"web\",\"scheme\":\"HTTP\"},\"initialDelaySeconds\":3,\"timeoutSeconds\":3,\"periodSeconds\":5,\"successThreshold\":1,\"failureThreshold\":10}",
|
||||
"resource_requests": "{\"memory\":\"200Mi\"}",
|
||||
"stateful_set_name": "alertmanager-main",
|
||||
"stdin": "0",
|
||||
"stdin_once": "0",
|
||||
"termination_message_path": "/dev/termination-log",
|
||||
"termination_message_policy": "FallbackToLogsOnError",
|
||||
"tty": "0",
|
||||
"uid": "da9bb224-1bf1-5960-a83c-b77a73ea6e79",
|
||||
"volume_mounts": "[{\"name\":\"config-volume\",\"mountPath\":\"/etc/alertmanager/config\"},{\"name\":\"alertmanager-main-db\",\"mountPath\":\"/alertmanager\"}]",
|
||||
},
|
||||
{
|
||||
"args": "[\"-webhook-url=http://localhost:9093/-/reload\",\"-volume-dir=/etc/alertmanager/config\"]",
|
||||
"cluster_uid": "blah",
|
||||
"container_type": "container",
|
||||
"creation_timestamp": "1611191592",
|
||||
"image": "jimmidyson/configmap-reload:v0.3.0",
|
||||
"image_pull_policy": "IfNotPresent",
|
||||
"labels": "{\"alertmanager\":\"main\"}",
|
||||
"name": "config-reloader",
|
||||
"namespace": "monitoring",
|
||||
"resource_limits": "{\"cpu\":\"100m\",\"memory\":\"25Mi\"}",
|
||||
"stateful_set_name": "alertmanager-main",
|
||||
"stdin": "0",
|
||||
"stdin_once": "0",
|
||||
"termination_message_path": "/dev/termination-log",
|
||||
"termination_message_policy": "FallbackToLogsOnError",
|
||||
"tty": "0",
|
||||
"uid": "69afdc5a-a3de-59b5-8151-4103b933f2cf",
|
||||
"volume_mounts": "[{\"name\":\"config-volume\",\"readOnly\":true,\"mountPath\":\"/etc/alertmanager/config\"}]",
|
||||
},
|
||||
}, sss)
|
||||
}
|
||||
|
||||
func TestStatefulSetVolumesGenerate(t *testing.T) {
|
||||
sss, err := StatefulSetVolumesGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"aws_elastic_block_store_partition": "0",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "1611191592",
|
||||
"gce_persistent_disk_partition": "0",
|
||||
"iscsi_discovery_chap_auth": "0",
|
||||
"iscsi_lun": "0",
|
||||
"iscsi_session_chap_auth": "0",
|
||||
"labels": "{\"alertmanager\":\"main\"}",
|
||||
"name": "config-volume",
|
||||
"namespace": "monitoring",
|
||||
"scale_iossl_enabled": "0",
|
||||
"secret_default_mode": "420",
|
||||
"secret_name": "alertmanager-main",
|
||||
"stateful_set_name": "alertmanager-main",
|
||||
"uid": "3c488e7e-420c-4515-b377-5dc3ee082744",
|
||||
"volume_type": "secret",
|
||||
},
|
||||
{
|
||||
"aws_elastic_block_store_partition": "0",
|
||||
"cluster_uid": "blah",
|
||||
"creation_timestamp": "1611191592",
|
||||
"empty_dir_size_limit": "<nil>",
|
||||
"gce_persistent_disk_partition": "0",
|
||||
"iscsi_discovery_chap_auth": "0",
|
||||
"iscsi_lun": "0",
|
||||
"iscsi_session_chap_auth": "0",
|
||||
"labels": "{\"alertmanager\":\"main\"}",
|
||||
"name": "alertmanager-main-db",
|
||||
"namespace": "monitoring",
|
||||
"scale_iossl_enabled": "0",
|
||||
"stateful_set_name": "alertmanager-main",
|
||||
"uid": "3c488e7e-420c-4515-b377-5dc3ee082744",
|
||||
"volume_type": "empty_dir",
|
||||
},
|
||||
}, sss)
|
||||
}
|
910
infrastructure/kubequery/internal/k8s/apps/testdata/daemon_set_test.json
vendored
Normal file
910
infrastructure/kubequery/internal/k8s/apps/testdata/daemon_set_test.json
vendored
Normal file
@ -0,0 +1,910 @@
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "DaemonSet",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"deprecated.daemonset.template.generation": "1"
|
||||
},
|
||||
"creationTimestamp": "2021-01-12T18:30:16Z",
|
||||
"generation": 1,
|
||||
"labels": {
|
||||
"k8s-app": "calico-node"
|
||||
},
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:deprecated.daemonset.template.generation": {},
|
||||
"f:kubectl.kubernetes.io/last-applied-configuration": {}
|
||||
},
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:k8s-app": {}
|
||||
}
|
||||
},
|
||||
"f:spec": {
|
||||
"f:revisionHistoryLimit": {},
|
||||
"f:selector": {},
|
||||
"f:template": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:scheduler.alpha.kubernetes.io/critical-pod": {}
|
||||
},
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:k8s-app": {}
|
||||
}
|
||||
},
|
||||
"f:spec": {
|
||||
"f:containers": {
|
||||
"k:{\"name\":\"calico-node\"}": {
|
||||
".": {},
|
||||
"f:env": {
|
||||
".": {},
|
||||
"k:{\"name\":\"CALICO_DISABLE_FILE_LOGGING\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"CALICO_IPV4POOL_CIDR\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"CALICO_IPV4POOL_VXLAN\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"CALICO_NETWORKING_BACKEND\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:configMapKeyRef": {
|
||||
".": {},
|
||||
"f:key": {},
|
||||
"f:name": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"CLUSTER_TYPE\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"DATASTORE_TYPE\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"FELIX_DEFAULTENDPOINTTOHOSTACTION\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"FELIX_HEALTHENABLED\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"FELIX_IPINIPMTU\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:configMapKeyRef": {
|
||||
".": {},
|
||||
"f:key": {},
|
||||
"f:name": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"FELIX_IPV6SUPPORT\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"FELIX_LOGSEVERITYSCREEN\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"IP\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"IP_AUTODETECTION_METHOD\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"NODENAME\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:fieldRef": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:fieldPath": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"WAIT_FOR_DATASTORE\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
}
|
||||
},
|
||||
"f:image": {},
|
||||
"f:imagePullPolicy": {},
|
||||
"f:livenessProbe": {
|
||||
".": {},
|
||||
"f:exec": {
|
||||
".": {},
|
||||
"f:command": {}
|
||||
},
|
||||
"f:failureThreshold": {},
|
||||
"f:initialDelaySeconds": {},
|
||||
"f:periodSeconds": {},
|
||||
"f:successThreshold": {},
|
||||
"f:timeoutSeconds": {}
|
||||
},
|
||||
"f:name": {},
|
||||
"f:readinessProbe": {
|
||||
".": {},
|
||||
"f:exec": {
|
||||
".": {},
|
||||
"f:command": {}
|
||||
},
|
||||
"f:failureThreshold": {},
|
||||
"f:periodSeconds": {},
|
||||
"f:successThreshold": {},
|
||||
"f:timeoutSeconds": {}
|
||||
},
|
||||
"f:resources": {
|
||||
".": {},
|
||||
"f:requests": {
|
||||
".": {},
|
||||
"f:cpu": {}
|
||||
}
|
||||
},
|
||||
"f:securityContext": {
|
||||
".": {},
|
||||
"f:privileged": {}
|
||||
},
|
||||
"f:terminationMessagePath": {},
|
||||
"f:terminationMessagePolicy": {},
|
||||
"f:volumeMounts": {
|
||||
".": {},
|
||||
"k:{\"mountPath\":\"/lib/modules\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {},
|
||||
"f:readOnly": {}
|
||||
},
|
||||
"k:{\"mountPath\":\"/run/xtables.lock\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"mountPath\":\"/var/lib/calico\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"mountPath\":\"/var/run/calico\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"mountPath\":\"/var/run/nodeagent\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:dnsPolicy": {},
|
||||
"f:hostNetwork": {},
|
||||
"f:initContainers": {
|
||||
".": {},
|
||||
"k:{\"name\":\"flexvol-driver\"}": {
|
||||
".": {},
|
||||
"f:image": {},
|
||||
"f:imagePullPolicy": {},
|
||||
"f:name": {},
|
||||
"f:resources": {},
|
||||
"f:securityContext": {
|
||||
".": {},
|
||||
"f:privileged": {}
|
||||
},
|
||||
"f:terminationMessagePath": {},
|
||||
"f:terminationMessagePolicy": {},
|
||||
"f:volumeMounts": {
|
||||
".": {},
|
||||
"k:{\"mountPath\":\"/host/driver\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"install-cni\"}": {
|
||||
".": {},
|
||||
"f:command": {},
|
||||
"f:env": {
|
||||
".": {},
|
||||
"k:{\"name\":\"CNI_CONF_NAME\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"CNI_MTU\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:configMapKeyRef": {
|
||||
".": {},
|
||||
"f:key": {},
|
||||
"f:name": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"CNI_NETWORK_CONFIG\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:configMapKeyRef": {
|
||||
".": {},
|
||||
"f:key": {},
|
||||
"f:name": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"CNI_NET_DIR\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"KUBERNETES_NODE_NAME\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:fieldRef": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:fieldPath": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"SLEEP\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
}
|
||||
},
|
||||
"f:image": {},
|
||||
"f:imagePullPolicy": {},
|
||||
"f:name": {},
|
||||
"f:resources": {},
|
||||
"f:securityContext": {
|
||||
".": {},
|
||||
"f:privileged": {}
|
||||
},
|
||||
"f:terminationMessagePath": {},
|
||||
"f:terminationMessagePolicy": {},
|
||||
"f:volumeMounts": {
|
||||
".": {},
|
||||
"k:{\"mountPath\":\"/host/etc/cni/net.d\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"mountPath\":\"/host/opt/cni/bin\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"upgrade-ipam\"}": {
|
||||
".": {},
|
||||
"f:command": {},
|
||||
"f:env": {
|
||||
".": {},
|
||||
"k:{\"name\":\"CALICO_NETWORKING_BACKEND\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:configMapKeyRef": {
|
||||
".": {},
|
||||
"f:key": {},
|
||||
"f:name": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"KUBERNETES_NODE_NAME\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:fieldRef": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:fieldPath": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:image": {},
|
||||
"f:imagePullPolicy": {},
|
||||
"f:name": {},
|
||||
"f:resources": {},
|
||||
"f:securityContext": {
|
||||
".": {},
|
||||
"f:privileged": {}
|
||||
},
|
||||
"f:terminationMessagePath": {},
|
||||
"f:terminationMessagePolicy": {},
|
||||
"f:volumeMounts": {
|
||||
".": {},
|
||||
"k:{\"mountPath\":\"/host/opt/cni/bin\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"mountPath\":\"/var/lib/cni/networks\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:nodeSelector": {
|
||||
".": {},
|
||||
"f:kubernetes.io/os": {}
|
||||
},
|
||||
"f:priorityClassName": {},
|
||||
"f:restartPolicy": {},
|
||||
"f:schedulerName": {},
|
||||
"f:securityContext": {},
|
||||
"f:serviceAccount": {},
|
||||
"f:serviceAccountName": {},
|
||||
"f:terminationGracePeriodSeconds": {},
|
||||
"f:tolerations": {},
|
||||
"f:volumes": {
|
||||
".": {},
|
||||
"k:{\"name\":\"cni-bin-dir\"}": {
|
||||
".": {},
|
||||
"f:hostPath": {
|
||||
".": {},
|
||||
"f:path": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"name\":\"cni-net-dir\"}": {
|
||||
".": {},
|
||||
"f:hostPath": {
|
||||
".": {},
|
||||
"f:path": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"name\":\"flexvol-driver-host\"}": {
|
||||
".": {},
|
||||
"f:hostPath": {
|
||||
".": {},
|
||||
"f:path": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"name\":\"host-local-net-dir\"}": {
|
||||
".": {},
|
||||
"f:hostPath": {
|
||||
".": {},
|
||||
"f:path": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"name\":\"lib-modules\"}": {
|
||||
".": {},
|
||||
"f:hostPath": {
|
||||
".": {},
|
||||
"f:path": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"name\":\"policysync\"}": {
|
||||
".": {},
|
||||
"f:hostPath": {
|
||||
".": {},
|
||||
"f:path": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"name\":\"var-lib-calico\"}": {
|
||||
".": {},
|
||||
"f:hostPath": {
|
||||
".": {},
|
||||
"f:path": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"name\":\"var-run-calico\"}": {
|
||||
".": {},
|
||||
"f:hostPath": {
|
||||
".": {},
|
||||
"f:path": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"name\":\"xtables-lock\"}": {
|
||||
".": {},
|
||||
"f:hostPath": {
|
||||
".": {},
|
||||
"f:path": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"f:name": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:updateStrategy": {
|
||||
"f:rollingUpdate": {
|
||||
".": {},
|
||||
"f:maxUnavailable": {}
|
||||
},
|
||||
"f:type": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"manager": "kubectl-client-side-apply",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-12T18:30:16Z"
|
||||
},
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:status": {
|
||||
"f:currentNumberScheduled": {},
|
||||
"f:desiredNumberScheduled": {},
|
||||
"f:numberAvailable": {},
|
||||
"f:numberReady": {},
|
||||
"f:observedGeneration": {},
|
||||
"f:updatedNumberScheduled": {}
|
||||
}
|
||||
},
|
||||
"manager": "kube-controller-manager",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:05:37Z"
|
||||
}
|
||||
],
|
||||
"name": "calico-node",
|
||||
"namespace": "kube-system",
|
||||
"resourceVersion": "450274",
|
||||
"selfLink": "/apis/apps/v1/namespaces/kube-system/daemonsets/calico-node",
|
||||
"uid": "e6fed7f0-f79a-464f-a3d2-b63247a1f590"
|
||||
},
|
||||
"spec": {
|
||||
"revisionHistoryLimit": 10,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"k8s-app": "calico-node"
|
||||
}
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"scheduler.alpha.kubernetes.io/critical-pod": ""
|
||||
},
|
||||
"creationTimestamp": null,
|
||||
"labels": {
|
||||
"k8s-app": "calico-node"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"env": [
|
||||
{
|
||||
"name": "DATASTORE_TYPE",
|
||||
"value": "kubernetes"
|
||||
},
|
||||
{
|
||||
"name": "WAIT_FOR_DATASTORE",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"name": "NODENAME",
|
||||
"valueFrom": {
|
||||
"fieldRef": {
|
||||
"apiVersion": "v1",
|
||||
"fieldPath": "spec.nodeName"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CALICO_NETWORKING_BACKEND",
|
||||
"valueFrom": {
|
||||
"configMapKeyRef": {
|
||||
"key": "calico_backend",
|
||||
"name": "calico-config"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CLUSTER_TYPE",
|
||||
"value": "k8s,bgp"
|
||||
},
|
||||
{
|
||||
"name": "IP",
|
||||
"value": "autodetect"
|
||||
},
|
||||
{
|
||||
"name": "IP_AUTODETECTION_METHOD",
|
||||
"value": "first-found"
|
||||
},
|
||||
{
|
||||
"name": "CALICO_IPV4POOL_VXLAN",
|
||||
"value": "Always"
|
||||
},
|
||||
{
|
||||
"name": "FELIX_IPINIPMTU",
|
||||
"valueFrom": {
|
||||
"configMapKeyRef": {
|
||||
"key": "veth_mtu",
|
||||
"name": "calico-config"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CALICO_IPV4POOL_CIDR",
|
||||
"value": "10.1.0.0/16"
|
||||
},
|
||||
{
|
||||
"name": "CALICO_DISABLE_FILE_LOGGING",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"name": "FELIX_DEFAULTENDPOINTTOHOSTACTION",
|
||||
"value": "ACCEPT"
|
||||
},
|
||||
{
|
||||
"name": "FELIX_IPV6SUPPORT",
|
||||
"value": "false"
|
||||
},
|
||||
{
|
||||
"name": "FELIX_LOGSEVERITYSCREEN",
|
||||
"value": "error"
|
||||
},
|
||||
{
|
||||
"name": "FELIX_HEALTHENABLED",
|
||||
"value": "true"
|
||||
}
|
||||
],
|
||||
"image": "calico/node:v3.13.2",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"livenessProbe": {
|
||||
"exec": {
|
||||
"command": [
|
||||
"/bin/calico-node",
|
||||
"-felix-live"
|
||||
]
|
||||
},
|
||||
"failureThreshold": 6,
|
||||
"initialDelaySeconds": 10,
|
||||
"periodSeconds": 10,
|
||||
"successThreshold": 1,
|
||||
"timeoutSeconds": 1
|
||||
},
|
||||
"name": "calico-node",
|
||||
"readinessProbe": {
|
||||
"exec": {
|
||||
"command": [
|
||||
"/bin/calico-node",
|
||||
"-felix-ready"
|
||||
]
|
||||
},
|
||||
"failureThreshold": 3,
|
||||
"periodSeconds": 10,
|
||||
"successThreshold": 1,
|
||||
"timeoutSeconds": 1
|
||||
},
|
||||
"resources": {
|
||||
"requests": {
|
||||
"cpu": "250m"
|
||||
}
|
||||
},
|
||||
"securityContext": {
|
||||
"privileged": true
|
||||
},
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"terminationMessagePolicy": "File",
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/lib/modules",
|
||||
"name": "lib-modules",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/run/xtables.lock",
|
||||
"name": "xtables-lock"
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/calico",
|
||||
"name": "var-run-calico"
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/lib/calico",
|
||||
"name": "var-lib-calico"
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/nodeagent",
|
||||
"name": "policysync"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"dnsPolicy": "ClusterFirst",
|
||||
"hostNetwork": true,
|
||||
"initContainers": [
|
||||
{
|
||||
"command": [
|
||||
"/opt/cni/bin/calico-ipam",
|
||||
"-upgrade"
|
||||
],
|
||||
"env": [
|
||||
{
|
||||
"name": "KUBERNETES_NODE_NAME",
|
||||
"valueFrom": {
|
||||
"fieldRef": {
|
||||
"apiVersion": "v1",
|
||||
"fieldPath": "spec.nodeName"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CALICO_NETWORKING_BACKEND",
|
||||
"valueFrom": {
|
||||
"configMapKeyRef": {
|
||||
"key": "calico_backend",
|
||||
"name": "calico-config"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"image": "calico/cni:v3.13.2",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"name": "upgrade-ipam",
|
||||
"resources": {},
|
||||
"securityContext": {
|
||||
"privileged": true
|
||||
},
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"terminationMessagePolicy": "File",
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/var/lib/cni/networks",
|
||||
"name": "host-local-net-dir"
|
||||
},
|
||||
{
|
||||
"mountPath": "/host/opt/cni/bin",
|
||||
"name": "cni-bin-dir"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"command": [
|
||||
"/install-cni.sh"
|
||||
],
|
||||
"env": [
|
||||
{
|
||||
"name": "CNI_CONF_NAME",
|
||||
"value": "10-calico.conflist"
|
||||
},
|
||||
{
|
||||
"name": "CNI_NETWORK_CONFIG",
|
||||
"valueFrom": {
|
||||
"configMapKeyRef": {
|
||||
"key": "cni_network_config",
|
||||
"name": "calico-config"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "KUBERNETES_NODE_NAME",
|
||||
"valueFrom": {
|
||||
"fieldRef": {
|
||||
"apiVersion": "v1",
|
||||
"fieldPath": "spec.nodeName"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CNI_MTU",
|
||||
"valueFrom": {
|
||||
"configMapKeyRef": {
|
||||
"key": "veth_mtu",
|
||||
"name": "calico-config"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "SLEEP",
|
||||
"value": "false"
|
||||
},
|
||||
{
|
||||
"name": "CNI_NET_DIR",
|
||||
"value": "/var/snap/microk8s/current/args/cni-network"
|
||||
}
|
||||
],
|
||||
"image": "calico/cni:v3.13.2",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"name": "install-cni",
|
||||
"resources": {},
|
||||
"securityContext": {
|
||||
"privileged": true
|
||||
},
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"terminationMessagePolicy": "File",
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/host/opt/cni/bin",
|
||||
"name": "cni-bin-dir"
|
||||
},
|
||||
{
|
||||
"mountPath": "/host/etc/cni/net.d",
|
||||
"name": "cni-net-dir"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"image": "calico/pod2daemon-flexvol:v3.13.2",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"name": "flexvol-driver",
|
||||
"resources": {},
|
||||
"securityContext": {
|
||||
"privileged": true
|
||||
},
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"terminationMessagePolicy": "File",
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/host/driver",
|
||||
"name": "flexvol-driver-host"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodeSelector": {
|
||||
"kubernetes.io/os": "linux"
|
||||
},
|
||||
"priorityClassName": "system-node-critical",
|
||||
"restartPolicy": "Always",
|
||||
"schedulerName": "default-scheduler",
|
||||
"securityContext": {},
|
||||
"serviceAccount": "calico-node",
|
||||
"serviceAccountName": "calico-node",
|
||||
"terminationGracePeriodSeconds": 0,
|
||||
"tolerations": [
|
||||
{
|
||||
"effect": "NoSchedule",
|
||||
"operator": "Exists"
|
||||
},
|
||||
{
|
||||
"key": "CriticalAddonsOnly",
|
||||
"operator": "Exists"
|
||||
},
|
||||
{
|
||||
"effect": "NoExecute",
|
||||
"operator": "Exists"
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"hostPath": {
|
||||
"path": "/lib/modules",
|
||||
"type": ""
|
||||
},
|
||||
"name": "lib-modules"
|
||||
},
|
||||
{
|
||||
"hostPath": {
|
||||
"path": "/var/snap/microk8s/current/var/run/calico",
|
||||
"type": ""
|
||||
},
|
||||
"name": "var-run-calico"
|
||||
},
|
||||
{
|
||||
"hostPath": {
|
||||
"path": "/var/snap/microk8s/current/var/lib/calico",
|
||||
"type": ""
|
||||
},
|
||||
"name": "var-lib-calico"
|
||||
},
|
||||
{
|
||||
"hostPath": {
|
||||
"path": "/run/xtables.lock",
|
||||
"type": "FileOrCreate"
|
||||
},
|
||||
"name": "xtables-lock"
|
||||
},
|
||||
{
|
||||
"hostPath": {
|
||||
"path": "/var/snap/microk8s/current/opt/cni/bin",
|
||||
"type": ""
|
||||
},
|
||||
"name": "cni-bin-dir"
|
||||
},
|
||||
{
|
||||
"hostPath": {
|
||||
"path": "/var/snap/microk8s/current/args/cni-network",
|
||||
"type": ""
|
||||
},
|
||||
"name": "cni-net-dir"
|
||||
},
|
||||
{
|
||||
"hostPath": {
|
||||
"path": "/var/snap/microk8s/current/var/lib/cni/networks",
|
||||
"type": ""
|
||||
},
|
||||
"name": "host-local-net-dir"
|
||||
},
|
||||
{
|
||||
"hostPath": {
|
||||
"path": "/var/snap/microk8s/current/var/run/nodeagent",
|
||||
"type": "DirectoryOrCreate"
|
||||
},
|
||||
"name": "policysync"
|
||||
},
|
||||
{
|
||||
"hostPath": {
|
||||
"path": "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/nodeagent~uds",
|
||||
"type": "DirectoryOrCreate"
|
||||
},
|
||||
"name": "flexvol-driver-host"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"updateStrategy": {
|
||||
"rollingUpdate": {
|
||||
"maxUnavailable": 1
|
||||
},
|
||||
"type": "RollingUpdate"
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"currentNumberScheduled": 1,
|
||||
"desiredNumberScheduled": 1,
|
||||
"numberAvailable": 1,
|
||||
"numberMisscheduled": 0,
|
||||
"numberReady": 1,
|
||||
"observedGeneration": 1,
|
||||
"updatedNumberScheduled": 1
|
||||
}
|
||||
}
|
739
infrastructure/kubequery/internal/k8s/apps/testdata/deployment_test.json
vendored
Normal file
739
infrastructure/kubequery/internal/k8s/apps/testdata/deployment_test.json
vendored
Normal file
@ -0,0 +1,739 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"items": [
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"deployment.kubernetes.io/revision": "1",
|
||||
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{},\"name\":\"jaeger-operator\",\"namespace\":\"default\"},\"spec\":{\"replicas\":1,\"selector\":{\"matchLabels\":{\"name\":\"jaeger-operator\"}},\"template\":{\"metadata\":{\"labels\":{\"name\":\"jaeger-operator\"}},\"spec\":{\"containers\":[{\"args\":[\"start\"],\"env\":[{\"name\":\"WATCH_NAMESPACE\",\"value\":\"\"},{\"name\":\"POD_NAME\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.name\"}}},{\"name\":\"POD_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"fieldPath\":\"metadata.namespace\"}}},{\"name\":\"OPERATOR_NAME\",\"value\":\"jaeger-operator\"}],\"image\":\"jaegertracing/jaeger-operator:1.14.0\",\"imagePullPolicy\":\"Always\",\"name\":\"jaeger-operator\",\"ports\":[{\"containerPort\":8383,\"name\":\"metrics\"}]}],\"serviceAccountName\":\"jaeger-operator\"}}}}\n"
|
||||
},
|
||||
"creationTimestamp": "2021-01-21T01:08:24Z",
|
||||
"generation": 1,
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:kubectl.kubernetes.io/last-applied-configuration": {}
|
||||
}
|
||||
},
|
||||
"f:spec": {
|
||||
"f:progressDeadlineSeconds": {},
|
||||
"f:replicas": {},
|
||||
"f:revisionHistoryLimit": {},
|
||||
"f:selector": {},
|
||||
"f:strategy": {
|
||||
"f:rollingUpdate": {
|
||||
".": {},
|
||||
"f:maxSurge": {},
|
||||
"f:maxUnavailable": {}
|
||||
},
|
||||
"f:type": {}
|
||||
},
|
||||
"f:template": {
|
||||
"f:metadata": {
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:name": {}
|
||||
}
|
||||
},
|
||||
"f:spec": {
|
||||
"f:containers": {
|
||||
"k:{\"name\":\"jaeger-operator\"}": {
|
||||
".": {},
|
||||
"f:args": {},
|
||||
"f:env": {
|
||||
".": {},
|
||||
"k:{\"name\":\"OPERATOR_NAME\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"POD_NAME\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:fieldRef": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:fieldPath": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"POD_NAMESPACE\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:fieldRef": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:fieldPath": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"WATCH_NAMESPACE\"}": {
|
||||
".": {},
|
||||
"f:name": {}
|
||||
}
|
||||
},
|
||||
"f:image": {},
|
||||
"f:imagePullPolicy": {},
|
||||
"f:name": {},
|
||||
"f:ports": {
|
||||
".": {},
|
||||
"k:{\"containerPort\":8383,\"protocol\":\"TCP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
}
|
||||
},
|
||||
"f:resources": {},
|
||||
"f:terminationMessagePath": {},
|
||||
"f:terminationMessagePolicy": {}
|
||||
}
|
||||
},
|
||||
"f:dnsPolicy": {},
|
||||
"f:restartPolicy": {},
|
||||
"f:schedulerName": {},
|
||||
"f:securityContext": {},
|
||||
"f:serviceAccount": {},
|
||||
"f:serviceAccountName": {},
|
||||
"f:terminationGracePeriodSeconds": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"manager": "kubectl-client-side-apply",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:08:24Z"
|
||||
},
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
"f:deployment.kubernetes.io/revision": {}
|
||||
}
|
||||
},
|
||||
"f:status": {
|
||||
"f:availableReplicas": {},
|
||||
"f:conditions": {
|
||||
".": {},
|
||||
"k:{\"type\":\"Available\"}": {
|
||||
".": {},
|
||||
"f:lastTransitionTime": {},
|
||||
"f:lastUpdateTime": {},
|
||||
"f:message": {},
|
||||
"f:reason": {},
|
||||
"f:status": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"k:{\"type\":\"Progressing\"}": {
|
||||
".": {},
|
||||
"f:lastTransitionTime": {},
|
||||
"f:lastUpdateTime": {},
|
||||
"f:message": {},
|
||||
"f:reason": {},
|
||||
"f:status": {},
|
||||
"f:type": {}
|
||||
}
|
||||
},
|
||||
"f:observedGeneration": {},
|
||||
"f:readyReplicas": {},
|
||||
"f:replicas": {},
|
||||
"f:updatedReplicas": {}
|
||||
}
|
||||
},
|
||||
"manager": "kube-controller-manager",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:08:52Z"
|
||||
}
|
||||
],
|
||||
"name": "jaeger-operator",
|
||||
"namespace": "default",
|
||||
"resourceVersion": "451812",
|
||||
"selfLink": "/apis/apps/v1/namespaces/default/deployments/jaeger-operator",
|
||||
"uid": "baa856ea-2d04-4bbb-b9be-aa5b89c58087"
|
||||
},
|
||||
"spec": {
|
||||
"progressDeadlineSeconds": 600,
|
||||
"replicas": 1,
|
||||
"revisionHistoryLimit": 10,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"name": "jaeger-operator"
|
||||
}
|
||||
},
|
||||
"strategy": {
|
||||
"rollingUpdate": {
|
||||
"maxSurge": "25%",
|
||||
"maxUnavailable": "25%"
|
||||
},
|
||||
"type": "RollingUpdate"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"creationTimestamp": null,
|
||||
"labels": {
|
||||
"name": "jaeger-operator"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"args": [
|
||||
"start"
|
||||
],
|
||||
"env": [
|
||||
{
|
||||
"name": "WATCH_NAMESPACE"
|
||||
},
|
||||
{
|
||||
"name": "POD_NAME",
|
||||
"valueFrom": {
|
||||
"fieldRef": {
|
||||
"apiVersion": "v1",
|
||||
"fieldPath": "metadata.name"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "POD_NAMESPACE",
|
||||
"valueFrom": {
|
||||
"fieldRef": {
|
||||
"apiVersion": "v1",
|
||||
"fieldPath": "metadata.namespace"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OPERATOR_NAME",
|
||||
"value": "jaeger-operator"
|
||||
}
|
||||
],
|
||||
"image": "jaegertracing/jaeger-operator:1.14.0",
|
||||
"imagePullPolicy": "Always",
|
||||
"name": "jaeger-operator",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 8383,
|
||||
"name": "metrics",
|
||||
"protocol": "TCP"
|
||||
}
|
||||
],
|
||||
"resources": {},
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"terminationMessagePolicy": "File"
|
||||
}
|
||||
],
|
||||
"dnsPolicy": "ClusterFirst",
|
||||
"restartPolicy": "Always",
|
||||
"schedulerName": "default-scheduler",
|
||||
"securityContext": {},
|
||||
"serviceAccount": "jaeger-operator",
|
||||
"serviceAccountName": "jaeger-operator",
|
||||
"terminationGracePeriodSeconds": 30
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"availableReplicas": 1,
|
||||
"conditions": [
|
||||
{
|
||||
"lastTransitionTime": "2021-01-21T01:08:52Z",
|
||||
"lastUpdateTime": "2021-01-21T01:08:52Z",
|
||||
"message": "Deployment has minimum availability.",
|
||||
"reason": "MinimumReplicasAvailable",
|
||||
"status": "True",
|
||||
"type": "Available"
|
||||
},
|
||||
{
|
||||
"lastTransitionTime": "2021-01-21T01:08:24Z",
|
||||
"lastUpdateTime": "2021-01-21T01:08:52Z",
|
||||
"message": "ReplicaSet \"jaeger-operator-5db4f9d996\" has successfully progressed.",
|
||||
"reason": "NewReplicaSetAvailable",
|
||||
"status": "True",
|
||||
"type": "Progressing"
|
||||
}
|
||||
],
|
||||
"observedGeneration": 1,
|
||||
"readyReplicas": 1,
|
||||
"replicas": 1,
|
||||
"updatedReplicas": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"deployment.kubernetes.io/revision": "1",
|
||||
"linkerd.io/inject": "disabled",
|
||||
"prometheus.io/port": "14269",
|
||||
"prometheus.io/scrape": "true",
|
||||
"sidecar.istio.io/inject": "false"
|
||||
},
|
||||
"creationTimestamp": "2021-01-21T01:08:53Z",
|
||||
"generation": 1,
|
||||
"labels": {
|
||||
"app": "jaeger",
|
||||
"app.kubernetes.io/component": "all-in-one",
|
||||
"app.kubernetes.io/instance": "simplest",
|
||||
"app.kubernetes.io/managed-by": "jaeger-operator",
|
||||
"app.kubernetes.io/name": "simplest",
|
||||
"app.kubernetes.io/part-of": "jaeger"
|
||||
},
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:linkerd.io/inject": {},
|
||||
"f:prometheus.io/port": {},
|
||||
"f:prometheus.io/scrape": {},
|
||||
"f:sidecar.istio.io/inject": {}
|
||||
},
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:app": {},
|
||||
"f:app.kubernetes.io/component": {},
|
||||
"f:app.kubernetes.io/instance": {},
|
||||
"f:app.kubernetes.io/managed-by": {},
|
||||
"f:app.kubernetes.io/name": {},
|
||||
"f:app.kubernetes.io/part-of": {}
|
||||
},
|
||||
"f:ownerReferences": {
|
||||
".": {},
|
||||
"k:{\"uid\":\"95d303e8-d347-4f8f-b008-a4da3e44b847\"}": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:controller": {},
|
||||
"f:kind": {},
|
||||
"f:name": {},
|
||||
"f:uid": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:spec": {
|
||||
"f:progressDeadlineSeconds": {},
|
||||
"f:replicas": {},
|
||||
"f:revisionHistoryLimit": {},
|
||||
"f:selector": {},
|
||||
"f:strategy": {
|
||||
"f:rollingUpdate": {
|
||||
".": {},
|
||||
"f:maxSurge": {},
|
||||
"f:maxUnavailable": {}
|
||||
},
|
||||
"f:type": {}
|
||||
},
|
||||
"f:template": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:linkerd.io/inject": {},
|
||||
"f:prometheus.io/port": {},
|
||||
"f:prometheus.io/scrape": {},
|
||||
"f:sidecar.istio.io/inject": {}
|
||||
},
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:app": {},
|
||||
"f:app.kubernetes.io/component": {},
|
||||
"f:app.kubernetes.io/instance": {},
|
||||
"f:app.kubernetes.io/managed-by": {},
|
||||
"f:app.kubernetes.io/name": {},
|
||||
"f:app.kubernetes.io/part-of": {}
|
||||
}
|
||||
},
|
||||
"f:spec": {
|
||||
"f:containers": {
|
||||
"k:{\"name\":\"jaeger\"}": {
|
||||
".": {},
|
||||
"f:args": {},
|
||||
"f:env": {
|
||||
".": {},
|
||||
"k:{\"name\":\"COLLECTOR_ZIPKIN_HTTP_PORT\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"SPAN_STORAGE_TYPE\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
}
|
||||
},
|
||||
"f:image": {},
|
||||
"f:imagePullPolicy": {},
|
||||
"f:name": {},
|
||||
"f:ports": {
|
||||
".": {},
|
||||
"k:{\"containerPort\":14267,\"protocol\":\"TCP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
},
|
||||
"k:{\"containerPort\":14268,\"protocol\":\"TCP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
},
|
||||
"k:{\"containerPort\":14269,\"protocol\":\"TCP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
},
|
||||
"k:{\"containerPort\":16686,\"protocol\":\"TCP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
},
|
||||
"k:{\"containerPort\":5775,\"protocol\":\"UDP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
},
|
||||
"k:{\"containerPort\":5778,\"protocol\":\"TCP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
},
|
||||
"k:{\"containerPort\":6831,\"protocol\":\"UDP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
},
|
||||
"k:{\"containerPort\":6832,\"protocol\":\"UDP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
},
|
||||
"k:{\"containerPort\":9411,\"protocol\":\"TCP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
}
|
||||
},
|
||||
"f:readinessProbe": {
|
||||
".": {},
|
||||
"f:failureThreshold": {},
|
||||
"f:httpGet": {
|
||||
".": {},
|
||||
"f:path": {},
|
||||
"f:port": {},
|
||||
"f:scheme": {}
|
||||
},
|
||||
"f:initialDelaySeconds": {},
|
||||
"f:periodSeconds": {},
|
||||
"f:successThreshold": {},
|
||||
"f:timeoutSeconds": {}
|
||||
},
|
||||
"f:resources": {},
|
||||
"f:terminationMessagePath": {},
|
||||
"f:terminationMessagePolicy": {},
|
||||
"f:volumeMounts": {
|
||||
".": {},
|
||||
"k:{\"mountPath\":\"/etc/jaeger/sampling\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {},
|
||||
"f:readOnly": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:dnsPolicy": {},
|
||||
"f:restartPolicy": {},
|
||||
"f:schedulerName": {},
|
||||
"f:securityContext": {},
|
||||
"f:serviceAccount": {},
|
||||
"f:serviceAccountName": {},
|
||||
"f:terminationGracePeriodSeconds": {},
|
||||
"f:volumes": {
|
||||
".": {},
|
||||
"k:{\"name\":\"simplest-sampling-configuration-volume\"}": {
|
||||
".": {},
|
||||
"f:configMap": {
|
||||
".": {},
|
||||
"f:defaultMode": {},
|
||||
"f:items": {},
|
||||
"f:name": {}
|
||||
},
|
||||
"f:name": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"manager": "jaeger-operator",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:08:53Z"
|
||||
},
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
"f:deployment.kubernetes.io/revision": {}
|
||||
}
|
||||
},
|
||||
"f:status": {
|
||||
"f:availableReplicas": {},
|
||||
"f:conditions": {
|
||||
".": {},
|
||||
"k:{\"type\":\"Available\"}": {
|
||||
".": {},
|
||||
"f:lastTransitionTime": {},
|
||||
"f:lastUpdateTime": {},
|
||||
"f:message": {},
|
||||
"f:reason": {},
|
||||
"f:status": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"k:{\"type\":\"Progressing\"}": {
|
||||
".": {},
|
||||
"f:lastTransitionTime": {},
|
||||
"f:lastUpdateTime": {},
|
||||
"f:message": {},
|
||||
"f:reason": {},
|
||||
"f:status": {},
|
||||
"f:type": {}
|
||||
}
|
||||
},
|
||||
"f:observedGeneration": {},
|
||||
"f:readyReplicas": {},
|
||||
"f:replicas": {},
|
||||
"f:updatedReplicas": {}
|
||||
}
|
||||
},
|
||||
"manager": "kube-controller-manager",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:09:04Z"
|
||||
}
|
||||
],
|
||||
"name": "simplest",
|
||||
"namespace": "default",
|
||||
"ownerReferences": [
|
||||
{
|
||||
"apiVersion": "jaegertracing.io/v1",
|
||||
"controller": true,
|
||||
"kind": "Jaeger",
|
||||
"name": "simplest",
|
||||
"uid": "95d303e8-d347-4f8f-b008-a4da3e44b847"
|
||||
}
|
||||
],
|
||||
"resourceVersion": "451923",
|
||||
"selfLink": "/apis/apps/v1/namespaces/default/deployments/simplest",
|
||||
"uid": "ef190adf-c268-409d-8684-3775e59385bf"
|
||||
},
|
||||
"spec": {
|
||||
"progressDeadlineSeconds": 600,
|
||||
"replicas": 1,
|
||||
"revisionHistoryLimit": 10,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"app": "jaeger",
|
||||
"app.kubernetes.io/component": "all-in-one",
|
||||
"app.kubernetes.io/instance": "simplest",
|
||||
"app.kubernetes.io/managed-by": "jaeger-operator",
|
||||
"app.kubernetes.io/name": "simplest",
|
||||
"app.kubernetes.io/part-of": "jaeger"
|
||||
}
|
||||
},
|
||||
"strategy": {
|
||||
"rollingUpdate": {
|
||||
"maxSurge": "25%",
|
||||
"maxUnavailable": "25%"
|
||||
},
|
||||
"type": "RollingUpdate"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"linkerd.io/inject": "disabled",
|
||||
"prometheus.io/port": "14269",
|
||||
"prometheus.io/scrape": "true",
|
||||
"sidecar.istio.io/inject": "false"
|
||||
},
|
||||
"creationTimestamp": null,
|
||||
"labels": {
|
||||
"app": "jaeger",
|
||||
"app.kubernetes.io/component": "all-in-one",
|
||||
"app.kubernetes.io/instance": "simplest",
|
||||
"app.kubernetes.io/managed-by": "jaeger-operator",
|
||||
"app.kubernetes.io/name": "simplest",
|
||||
"app.kubernetes.io/part-of": "jaeger"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"args": [
|
||||
"--sampling.strategies-file=/etc/jaeger/sampling/sampling.json"
|
||||
],
|
||||
"env": [
|
||||
{
|
||||
"name": "SPAN_STORAGE_TYPE",
|
||||
"value": "memory"
|
||||
},
|
||||
{
|
||||
"name": "COLLECTOR_ZIPKIN_HTTP_PORT",
|
||||
"value": "9411"
|
||||
}
|
||||
],
|
||||
"image": "jaegertracing/all-in-one:1.14.0",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"name": "jaeger",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 5775,
|
||||
"name": "zk-compact-trft",
|
||||
"protocol": "UDP"
|
||||
},
|
||||
{
|
||||
"containerPort": 5778,
|
||||
"name": "config-rest",
|
||||
"protocol": "TCP"
|
||||
},
|
||||
{
|
||||
"containerPort": 6831,
|
||||
"name": "jg-compact-trft",
|
||||
"protocol": "UDP"
|
||||
},
|
||||
{
|
||||
"containerPort": 6832,
|
||||
"name": "jg-binary-trft",
|
||||
"protocol": "UDP"
|
||||
},
|
||||
{
|
||||
"containerPort": 9411,
|
||||
"name": "zipkin",
|
||||
"protocol": "TCP"
|
||||
},
|
||||
{
|
||||
"containerPort": 14267,
|
||||
"name": "c-tchan-trft",
|
||||
"protocol": "TCP"
|
||||
},
|
||||
{
|
||||
"containerPort": 14268,
|
||||
"name": "c-binary-trft",
|
||||
"protocol": "TCP"
|
||||
},
|
||||
{
|
||||
"containerPort": 16686,
|
||||
"name": "query",
|
||||
"protocol": "TCP"
|
||||
},
|
||||
{
|
||||
"containerPort": 14269,
|
||||
"name": "admin-http",
|
||||
"protocol": "TCP"
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
"failureThreshold": 3,
|
||||
"httpGet": {
|
||||
"path": "/",
|
||||
"port": 14269,
|
||||
"scheme": "HTTP"
|
||||
},
|
||||
"initialDelaySeconds": 1,
|
||||
"periodSeconds": 10,
|
||||
"successThreshold": 1,
|
||||
"timeoutSeconds": 1
|
||||
},
|
||||
"resources": {},
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"terminationMessagePolicy": "File",
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/etc/jaeger/sampling",
|
||||
"name": "simplest-sampling-configuration-volume",
|
||||
"readOnly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"dnsPolicy": "ClusterFirst",
|
||||
"restartPolicy": "Always",
|
||||
"schedulerName": "default-scheduler",
|
||||
"securityContext": {},
|
||||
"serviceAccount": "simplest",
|
||||
"serviceAccountName": "simplest",
|
||||
"terminationGracePeriodSeconds": 30,
|
||||
"volumes": [
|
||||
{
|
||||
"configMap": {
|
||||
"defaultMode": 420,
|
||||
"items": [
|
||||
{
|
||||
"key": "sampling",
|
||||
"path": "sampling.json"
|
||||
}
|
||||
],
|
||||
"name": "simplest-sampling-configuration"
|
||||
},
|
||||
"name": "simplest-sampling-configuration-volume"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"availableReplicas": 1,
|
||||
"conditions": [
|
||||
{
|
||||
"lastTransitionTime": "2021-01-21T01:09:04Z",
|
||||
"lastUpdateTime": "2021-01-21T01:09:04Z",
|
||||
"message": "Deployment has minimum availability.",
|
||||
"reason": "MinimumReplicasAvailable",
|
||||
"status": "True",
|
||||
"type": "Available"
|
||||
},
|
||||
{
|
||||
"lastTransitionTime": "2021-01-21T01:08:53Z",
|
||||
"lastUpdateTime": "2021-01-21T01:09:04Z",
|
||||
"message": "ReplicaSet \"simplest-85d9df868\" has successfully progressed.",
|
||||
"reason": "NewReplicaSetAvailable",
|
||||
"status": "True",
|
||||
"type": "Progressing"
|
||||
}
|
||||
],
|
||||
"observedGeneration": 1,
|
||||
"readyReplicas": 1,
|
||||
"replicas": 1,
|
||||
"updatedReplicas": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "List",
|
||||
"metadata": {
|
||||
"resourceVersion": "",
|
||||
"selfLink": ""
|
||||
}
|
||||
}
|
235
infrastructure/kubequery/internal/k8s/apps/testdata/replica_set_test.json
vendored
Normal file
235
infrastructure/kubequery/internal/k8s/apps/testdata/replica_set_test.json
vendored
Normal file
@ -0,0 +1,235 @@
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "ReplicaSet",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"deployment.kubernetes.io/desired-replicas": "1",
|
||||
"deployment.kubernetes.io/max-replicas": "2",
|
||||
"deployment.kubernetes.io/revision": "1"
|
||||
},
|
||||
"creationTimestamp": "2021-01-21T01:08:24Z",
|
||||
"generation": 1,
|
||||
"labels": {
|
||||
"name": "jaeger-operator",
|
||||
"pod-template-hash": "5db4f9d996"
|
||||
},
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:deployment.kubernetes.io/desired-replicas": {},
|
||||
"f:deployment.kubernetes.io/max-replicas": {},
|
||||
"f:deployment.kubernetes.io/revision": {}
|
||||
},
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:pod-template-hash": {}
|
||||
},
|
||||
"f:ownerReferences": {
|
||||
".": {},
|
||||
"k:{\"uid\":\"baa856ea-2d04-4bbb-b9be-aa5b89c58087\"}": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:blockOwnerDeletion": {},
|
||||
"f:controller": {},
|
||||
"f:kind": {},
|
||||
"f:name": {},
|
||||
"f:uid": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:spec": {
|
||||
"f:replicas": {},
|
||||
"f:selector": {},
|
||||
"f:template": {
|
||||
"f:metadata": {
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:pod-template-hash": {}
|
||||
}
|
||||
},
|
||||
"f:spec": {
|
||||
"f:containers": {
|
||||
"k:{\"name\":\"jaeger-operator\"}": {
|
||||
".": {},
|
||||
"f:args": {},
|
||||
"f:env": {
|
||||
".": {},
|
||||
"k:{\"name\":\"OPERATOR_NAME\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"POD_NAME\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:fieldRef": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:fieldPath": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"POD_NAMESPACE\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:fieldRef": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:fieldPath": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"WATCH_NAMESPACE\"}": {
|
||||
".": {},
|
||||
"f:name": {}
|
||||
}
|
||||
},
|
||||
"f:image": {},
|
||||
"f:imagePullPolicy": {},
|
||||
"f:name": {},
|
||||
"f:ports": {
|
||||
".": {},
|
||||
"k:{\"containerPort\":8383,\"protocol\":\"TCP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
}
|
||||
},
|
||||
"f:resources": {},
|
||||
"f:terminationMessagePath": {},
|
||||
"f:terminationMessagePolicy": {}
|
||||
}
|
||||
},
|
||||
"f:dnsPolicy": {},
|
||||
"f:restartPolicy": {},
|
||||
"f:schedulerName": {},
|
||||
"f:securityContext": {},
|
||||
"f:serviceAccount": {},
|
||||
"f:serviceAccountName": {},
|
||||
"f:terminationGracePeriodSeconds": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:status": {
|
||||
"f:availableReplicas": {},
|
||||
"f:fullyLabeledReplicas": {},
|
||||
"f:observedGeneration": {},
|
||||
"f:readyReplicas": {},
|
||||
"f:replicas": {}
|
||||
}
|
||||
},
|
||||
"manager": "kube-controller-manager",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:08:52Z"
|
||||
}
|
||||
],
|
||||
"name": "jaeger-operator-5db4f9d996",
|
||||
"namespace": "default",
|
||||
"ownerReferences": [
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"blockOwnerDeletion": true,
|
||||
"controller": true,
|
||||
"kind": "Deployment",
|
||||
"name": "jaeger-operator",
|
||||
"uid": "baa856ea-2d04-4bbb-b9be-aa5b89c58087"
|
||||
}
|
||||
],
|
||||
"resourceVersion": "451811",
|
||||
"selfLink": "/apis/apps/v1/namespaces/default/replicasets/jaeger-operator-5db4f9d996",
|
||||
"uid": "2efeb411-ff99-434b-a5a2-4e06c2b0afaa"
|
||||
},
|
||||
"spec": {
|
||||
"replicas": 1,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"name": "jaeger-operator",
|
||||
"pod-template-hash": "5db4f9d996"
|
||||
}
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"creationTimestamp": null,
|
||||
"labels": {
|
||||
"name": "jaeger-operator",
|
||||
"pod-template-hash": "5db4f9d996"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"args": [
|
||||
"start"
|
||||
],
|
||||
"env": [
|
||||
{
|
||||
"name": "WATCH_NAMESPACE"
|
||||
},
|
||||
{
|
||||
"name": "POD_NAME",
|
||||
"valueFrom": {
|
||||
"fieldRef": {
|
||||
"apiVersion": "v1",
|
||||
"fieldPath": "metadata.name"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "POD_NAMESPACE",
|
||||
"valueFrom": {
|
||||
"fieldRef": {
|
||||
"apiVersion": "v1",
|
||||
"fieldPath": "metadata.namespace"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OPERATOR_NAME",
|
||||
"value": "jaeger-operator"
|
||||
}
|
||||
],
|
||||
"image": "jaegertracing/jaeger-operator:1.14.0",
|
||||
"imagePullPolicy": "Always",
|
||||
"name": "jaeger-operator",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 8383,
|
||||
"name": "metrics",
|
||||
"protocol": "TCP"
|
||||
}
|
||||
],
|
||||
"resources": {},
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"terminationMessagePolicy": "File"
|
||||
}
|
||||
],
|
||||
"dnsPolicy": "ClusterFirst",
|
||||
"restartPolicy": "Always",
|
||||
"schedulerName": "default-scheduler",
|
||||
"securityContext": {},
|
||||
"serviceAccount": "jaeger-operator",
|
||||
"serviceAccountName": "jaeger-operator",
|
||||
"terminationGracePeriodSeconds": 30
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"availableReplicas": 1,
|
||||
"fullyLabeledReplicas": 1,
|
||||
"observedGeneration": 1,
|
||||
"readyReplicas": 1,
|
||||
"replicas": 1
|
||||
}
|
||||
}
|
403
infrastructure/kubequery/internal/k8s/apps/testdata/stateful_set_test.json
vendored
Normal file
403
infrastructure/kubequery/internal/k8s/apps/testdata/stateful_set_test.json
vendored
Normal file
@ -0,0 +1,403 @@
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "StatefulSet",
|
||||
"metadata": {
|
||||
"creationTimestamp": "2021-01-21T01:13:12Z",
|
||||
"generation": 1,
|
||||
"labels": {
|
||||
"alertmanager": "main"
|
||||
},
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:alertmanager": {}
|
||||
},
|
||||
"f:ownerReferences": {
|
||||
".": {},
|
||||
"k:{\"uid\":\"e6a6358b-646a-4171-8737-beb6c2b9ffaf\"}": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:blockOwnerDeletion": {},
|
||||
"f:controller": {},
|
||||
"f:kind": {},
|
||||
"f:name": {},
|
||||
"f:uid": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:spec": {
|
||||
"f:podManagementPolicy": {},
|
||||
"f:replicas": {},
|
||||
"f:revisionHistoryLimit": {},
|
||||
"f:selector": {},
|
||||
"f:serviceName": {},
|
||||
"f:template": {
|
||||
"f:metadata": {
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:alertmanager": {},
|
||||
"f:app": {}
|
||||
}
|
||||
},
|
||||
"f:spec": {
|
||||
"f:containers": {
|
||||
"k:{\"name\":\"alertmanager\"}": {
|
||||
".": {},
|
||||
"f:args": {},
|
||||
"f:env": {
|
||||
".": {},
|
||||
"k:{\"name\":\"POD_IP\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:fieldRef": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:fieldPath": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:image": {},
|
||||
"f:imagePullPolicy": {},
|
||||
"f:livenessProbe": {
|
||||
".": {},
|
||||
"f:failureThreshold": {},
|
||||
"f:httpGet": {
|
||||
".": {},
|
||||
"f:path": {},
|
||||
"f:port": {},
|
||||
"f:scheme": {}
|
||||
},
|
||||
"f:periodSeconds": {},
|
||||
"f:successThreshold": {},
|
||||
"f:timeoutSeconds": {}
|
||||
},
|
||||
"f:name": {},
|
||||
"f:ports": {
|
||||
".": {},
|
||||
"k:{\"containerPort\":9093,\"protocol\":\"TCP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
},
|
||||
"k:{\"containerPort\":9094,\"protocol\":\"TCP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
},
|
||||
"k:{\"containerPort\":9094,\"protocol\":\"UDP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
}
|
||||
},
|
||||
"f:readinessProbe": {
|
||||
".": {},
|
||||
"f:failureThreshold": {},
|
||||
"f:httpGet": {
|
||||
".": {},
|
||||
"f:path": {},
|
||||
"f:port": {},
|
||||
"f:scheme": {}
|
||||
},
|
||||
"f:initialDelaySeconds": {},
|
||||
"f:periodSeconds": {},
|
||||
"f:successThreshold": {},
|
||||
"f:timeoutSeconds": {}
|
||||
},
|
||||
"f:resources": {
|
||||
".": {},
|
||||
"f:requests": {
|
||||
".": {},
|
||||
"f:memory": {}
|
||||
}
|
||||
},
|
||||
"f:terminationMessagePath": {},
|
||||
"f:terminationMessagePolicy": {},
|
||||
"f:volumeMounts": {
|
||||
".": {},
|
||||
"k:{\"mountPath\":\"/alertmanager\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"mountPath\":\"/etc/alertmanager/config\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"config-reloader\"}": {
|
||||
".": {},
|
||||
"f:args": {},
|
||||
"f:image": {},
|
||||
"f:imagePullPolicy": {},
|
||||
"f:name": {},
|
||||
"f:resources": {
|
||||
".": {},
|
||||
"f:limits": {
|
||||
".": {},
|
||||
"f:cpu": {},
|
||||
"f:memory": {}
|
||||
}
|
||||
},
|
||||
"f:terminationMessagePath": {},
|
||||
"f:terminationMessagePolicy": {},
|
||||
"f:volumeMounts": {
|
||||
".": {},
|
||||
"k:{\"mountPath\":\"/etc/alertmanager/config\"}": {
|
||||
".": {},
|
||||
"f:mountPath": {},
|
||||
"f:name": {},
|
||||
"f:readOnly": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:dnsPolicy": {},
|
||||
"f:nodeSelector": {
|
||||
".": {},
|
||||
"f:kubernetes.io/os": {}
|
||||
},
|
||||
"f:restartPolicy": {},
|
||||
"f:schedulerName": {},
|
||||
"f:securityContext": {
|
||||
".": {},
|
||||
"f:fsGroup": {},
|
||||
"f:runAsNonRoot": {},
|
||||
"f:runAsUser": {}
|
||||
},
|
||||
"f:serviceAccount": {},
|
||||
"f:serviceAccountName": {},
|
||||
"f:terminationGracePeriodSeconds": {},
|
||||
"f:volumes": {
|
||||
".": {},
|
||||
"k:{\"name\":\"alertmanager-main-db\"}": {
|
||||
".": {},
|
||||
"f:emptyDir": {},
|
||||
"f:name": {}
|
||||
},
|
||||
"k:{\"name\":\"config-volume\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:secret": {
|
||||
".": {},
|
||||
"f:defaultMode": {},
|
||||
"f:secretName": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:updateStrategy": {
|
||||
"f:type": {}
|
||||
}
|
||||
},
|
||||
"f:status": {
|
||||
"f:replicas": {}
|
||||
}
|
||||
},
|
||||
"manager": "operator",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:13:12Z"
|
||||
}
|
||||
],
|
||||
"name": "alertmanager-main",
|
||||
"namespace": "monitoring",
|
||||
"ownerReferences": [
|
||||
{
|
||||
"apiVersion": "monitoring.coreos.com/v1",
|
||||
"blockOwnerDeletion": true,
|
||||
"controller": true,
|
||||
"kind": "Alertmanager",
|
||||
"name": "main",
|
||||
"uid": "e6a6358b-646a-4171-8737-beb6c2b9ffaf"
|
||||
}
|
||||
],
|
||||
"resourceVersion": "452929",
|
||||
"selfLink": "/apis/apps/v1/namespaces/monitoring/statefulsets/alertmanager-main",
|
||||
"uid": "3c488e7e-420c-4515-b377-5dc3ee082744"
|
||||
},
|
||||
"spec": {
|
||||
"podManagementPolicy": "Parallel",
|
||||
"replicas": 1,
|
||||
"revisionHistoryLimit": 10,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"alertmanager": "main",
|
||||
"app": "alertmanager"
|
||||
}
|
||||
},
|
||||
"serviceName": "alertmanager-operated",
|
||||
"template": {
|
||||
"metadata": {
|
||||
"creationTimestamp": null,
|
||||
"labels": {
|
||||
"alertmanager": "main",
|
||||
"app": "alertmanager"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"args": [
|
||||
"--config.file=/etc/alertmanager/config/alertmanager.yaml",
|
||||
"--storage.path=/alertmanager",
|
||||
"--data.retention=120h",
|
||||
"--cluster.listen-address=",
|
||||
"--web.listen-address=:9093",
|
||||
"--web.route-prefix=/",
|
||||
"--cluster.peer=alertmanager-main-0.alertmanager-operated:9094"
|
||||
],
|
||||
"env": [
|
||||
{
|
||||
"name": "POD_IP",
|
||||
"valueFrom": {
|
||||
"fieldRef": {
|
||||
"apiVersion": "v1",
|
||||
"fieldPath": "status.podIP"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"image": "quay.io/prometheus/alertmanager:v0.21.0",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"livenessProbe": {
|
||||
"failureThreshold": 10,
|
||||
"httpGet": {
|
||||
"path": "/-/healthy",
|
||||
"port": "web",
|
||||
"scheme": "HTTP"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"successThreshold": 1,
|
||||
"timeoutSeconds": 3
|
||||
},
|
||||
"name": "alertmanager",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 9093,
|
||||
"name": "web",
|
||||
"protocol": "TCP"
|
||||
},
|
||||
{
|
||||
"containerPort": 9094,
|
||||
"name": "mesh-tcp",
|
||||
"protocol": "TCP"
|
||||
},
|
||||
{
|
||||
"containerPort": 9094,
|
||||
"name": "mesh-udp",
|
||||
"protocol": "UDP"
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
"failureThreshold": 10,
|
||||
"httpGet": {
|
||||
"path": "/-/ready",
|
||||
"port": "web",
|
||||
"scheme": "HTTP"
|
||||
},
|
||||
"initialDelaySeconds": 3,
|
||||
"periodSeconds": 5,
|
||||
"successThreshold": 1,
|
||||
"timeoutSeconds": 3
|
||||
},
|
||||
"resources": {
|
||||
"requests": {
|
||||
"memory": "200Mi"
|
||||
}
|
||||
},
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"terminationMessagePolicy": "FallbackToLogsOnError",
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/etc/alertmanager/config",
|
||||
"name": "config-volume"
|
||||
},
|
||||
{
|
||||
"mountPath": "/alertmanager",
|
||||
"name": "alertmanager-main-db"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"args": [
|
||||
"-webhook-url=http://localhost:9093/-/reload",
|
||||
"-volume-dir=/etc/alertmanager/config"
|
||||
],
|
||||
"image": "jimmidyson/configmap-reload:v0.3.0",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"name": "config-reloader",
|
||||
"resources": {
|
||||
"limits": {
|
||||
"cpu": "100m",
|
||||
"memory": "25Mi"
|
||||
}
|
||||
},
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"terminationMessagePolicy": "FallbackToLogsOnError",
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/etc/alertmanager/config",
|
||||
"name": "config-volume",
|
||||
"readOnly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"dnsPolicy": "ClusterFirst",
|
||||
"nodeSelector": {
|
||||
"kubernetes.io/os": "linux"
|
||||
},
|
||||
"restartPolicy": "Always",
|
||||
"schedulerName": "default-scheduler",
|
||||
"securityContext": {
|
||||
"fsGroup": 2000,
|
||||
"runAsNonRoot": true,
|
||||
"runAsUser": 1000
|
||||
},
|
||||
"serviceAccount": "alertmanager-main",
|
||||
"serviceAccountName": "alertmanager-main",
|
||||
"terminationGracePeriodSeconds": 120,
|
||||
"volumes": [
|
||||
{
|
||||
"name": "config-volume",
|
||||
"secret": {
|
||||
"defaultMode": 420,
|
||||
"secretName": "alertmanager-main"
|
||||
}
|
||||
},
|
||||
{
|
||||
"emptyDir": {},
|
||||
"name": "alertmanager-main-db"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"updateStrategy": {
|
||||
"type": "RollingUpdate"
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"collisionCount": 0,
|
||||
"currentReplicas": 1,
|
||||
"currentRevision": "alertmanager-main-6674894c9d",
|
||||
"observedGeneration": 1,
|
||||
"readyReplicas": 1,
|
||||
"replicas": 1,
|
||||
"updateRevision": "alertmanager-main-6674894c9d",
|
||||
"updatedReplicas": 1
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package autoscaling
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/autoscaling/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type horizontalPodAutoscaler struct {
|
||||
k8s.CommonNamespacedFields
|
||||
v1.HorizontalPodAutoscalerSpec
|
||||
v1.HorizontalPodAutoscalerStatus
|
||||
}
|
||||
|
||||
// HorizontalPodAutoscalersColumns returns kubernetes horizontal pod autoscaler fields as Osquery table columns.
|
||||
func HorizontalPodAutoscalersColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&horizontalPodAutoscaler{})
|
||||
}
|
||||
|
||||
// HorizontalPodAutoscalerGenerate generates the kubernetes horizontal pod autoscalers as Osquery table data.
|
||||
func HorizontalPodAutoscalerGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
hpas, err := k8s.GetClient().AutoscalingV1().HorizontalPodAutoscalers(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, hpa := range hpas.Items {
|
||||
item := &horizontalPodAutoscaler{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(hpa.ObjectMeta),
|
||||
HorizontalPodAutoscalerSpec: hpa.Spec,
|
||||
HorizontalPodAutoscalerStatus: hpa.Status,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if hpas.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = hpas.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package autoscaling
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/autoscaling/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
|
||||
func TestHorizontalPodAutoscalerGenerate(t *testing.T) {
|
||||
i32 := int32(456)
|
||||
i64 := int64(123)
|
||||
k8s.SetClient(fake.NewSimpleClientset(&v1.HorizontalPodAutoscaler{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "hpa1",
|
||||
Namespace: "n123",
|
||||
UID: types.UID("1234"),
|
||||
Labels: map[string]string{"a": "b"},
|
||||
},
|
||||
Spec: v1.HorizontalPodAutoscalerSpec{
|
||||
MinReplicas: &i32,
|
||||
MaxReplicas: i32,
|
||||
TargetCPUUtilizationPercentage: &i32,
|
||||
ScaleTargetRef: v1.CrossVersionObjectReference{
|
||||
Name: "blah",
|
||||
},
|
||||
},
|
||||
Status: v1.HorizontalPodAutoscalerStatus{
|
||||
ObservedGeneration: &i64,
|
||||
LastScaleTime: &metav1.Time{},
|
||||
CurrentReplicas: i32,
|
||||
DesiredReplicas: i32,
|
||||
CurrentCPUUtilizationPercentage: &i32,
|
||||
},
|
||||
}), types.UID("hello"), "")
|
||||
|
||||
hpas, err := HorizontalPodAutoscalerGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"cluster_uid": "hello",
|
||||
"creation_timestamp": "0",
|
||||
"current_cpu_utilization_percentage": "456",
|
||||
"current_replicas": "456",
|
||||
"desired_replicas": "456",
|
||||
"labels": "{\"a\":\"b\"}",
|
||||
"last_scale_time": "0",
|
||||
"max_replicas": "456",
|
||||
"min_replicas": "456",
|
||||
"name": "hpa1",
|
||||
"namespace": "n123",
|
||||
"observed_generation": "123",
|
||||
"scale_target_ref": "{\"kind\":\"\",\"name\":\"blah\"}",
|
||||
"target_cpu_utilization_percentage": "456",
|
||||
"uid": "1234",
|
||||
},
|
||||
}, hpas)
|
||||
}
|
85
infrastructure/kubequery/internal/k8s/batch/cron_job.go
Normal file
85
infrastructure/kubequery/internal/k8s/batch/cron_job.go
Normal file
@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package batch
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/batch/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type cronJob struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonPodFields
|
||||
v1.CronJobStatus
|
||||
Schedule string
|
||||
StartingDeadlineSeconds *int64
|
||||
ConcurrencyPolicy v1.ConcurrencyPolicy
|
||||
Suspend *bool
|
||||
SuccessfulJobsHistoryLimit *int32
|
||||
FailedJobsHistoryLimit *int32
|
||||
Parallelism *int32
|
||||
Completions *int32
|
||||
JobActiveDeadlineSeconds *int64
|
||||
BackoffLimit *int32
|
||||
Selector *metav1.LabelSelector
|
||||
ManualSelector *bool
|
||||
TTLSecondsAfterFinished *int32
|
||||
}
|
||||
|
||||
// CronJobColumns returns kubernetes cron job fields as Osquery table columns.
|
||||
func CronJobColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&cronJob{})
|
||||
}
|
||||
|
||||
// CronJobsGenerate generates the kubernetes cron jobs as Osquery table data.
|
||||
func CronJobsGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
cjs, err := k8s.GetClient().BatchV1().CronJobs(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, cj := range cjs.Items {
|
||||
item := &cronJob{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(cj.ObjectMeta),
|
||||
CommonPodFields: k8s.GetCommonPodFields(cj.Spec.JobTemplate.Spec.Template.Spec),
|
||||
CronJobStatus: cj.Status,
|
||||
Schedule: cj.Spec.Schedule,
|
||||
StartingDeadlineSeconds: cj.Spec.StartingDeadlineSeconds,
|
||||
ConcurrencyPolicy: cj.Spec.ConcurrencyPolicy,
|
||||
Suspend: cj.Spec.Suspend,
|
||||
SuccessfulJobsHistoryLimit: cj.Spec.SuccessfulJobsHistoryLimit,
|
||||
FailedJobsHistoryLimit: cj.Spec.FailedJobsHistoryLimit,
|
||||
Parallelism: cj.Spec.JobTemplate.Spec.Parallelism,
|
||||
Completions: cj.Spec.JobTemplate.Spec.Completions,
|
||||
JobActiveDeadlineSeconds: cj.Spec.JobTemplate.Spec.ActiveDeadlineSeconds,
|
||||
BackoffLimit: cj.Spec.JobTemplate.Spec.BackoffLimit,
|
||||
Selector: cj.Spec.JobTemplate.Spec.Selector,
|
||||
ManualSelector: cj.Spec.JobTemplate.Spec.ManualSelector,
|
||||
TTLSecondsAfterFinished: cj.Spec.JobTemplate.Spec.TTLSecondsAfterFinished,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if cjs.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = cjs.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
93
infrastructure/kubequery/internal/k8s/batch/cron_job_test.go
Normal file
93
infrastructure/kubequery/internal/k8s/batch/cron_job_test.go
Normal file
@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package batch
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/batch/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
|
||||
func TestCronJobsGenerate(t *testing.T) {
|
||||
i32 := int32(456)
|
||||
i64 := int64(123)
|
||||
b := bool(true)
|
||||
k8s.SetClient(fake.NewSimpleClientset(&v1.CronJob{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "cj1",
|
||||
Namespace: "n123",
|
||||
UID: types.UID("1234"),
|
||||
Labels: map[string]string{"a": "b"},
|
||||
},
|
||||
Spec: v1.CronJobSpec{
|
||||
Schedule: "s1",
|
||||
StartingDeadlineSeconds: &i64,
|
||||
ConcurrencyPolicy: v1.AllowConcurrent,
|
||||
Suspend: &b,
|
||||
SuccessfulJobsHistoryLimit: &i32,
|
||||
FailedJobsHistoryLimit: &i32,
|
||||
JobTemplate: v1.JobTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "job1",
|
||||
Namespace: "n123",
|
||||
UID: types.UID("1234"),
|
||||
Labels: map[string]string{"a": "b"},
|
||||
},
|
||||
Spec: v1.JobSpec{
|
||||
Parallelism: &i32,
|
||||
Completions: &i32,
|
||||
ActiveDeadlineSeconds: &i64,
|
||||
BackoffLimit: &i32,
|
||||
ManualSelector: &b,
|
||||
TTLSecondsAfterFinished: &i32,
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: v1.CronJobStatus{
|
||||
LastScheduleTime: &metav1.Time{},
|
||||
},
|
||||
}), types.UID("hello"), "")
|
||||
|
||||
cjs, err := CronJobsGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"backoff_limit": "456",
|
||||
"cluster_uid": "hello",
|
||||
"completions": "456",
|
||||
"concurrency_policy": "Allow",
|
||||
"creation_timestamp": "0",
|
||||
"failed_jobs_history_limit": "456",
|
||||
"host_ipc": "0",
|
||||
"host_network": "0",
|
||||
"host_pid": "0",
|
||||
"job_active_deadline_seconds": "123",
|
||||
"labels": "{\"a\":\"b\"}",
|
||||
"last_schedule_time": "0",
|
||||
"manual_selector": "1",
|
||||
"name": "cj1",
|
||||
"namespace": "n123",
|
||||
"parallelism": "456",
|
||||
"schedule": "s1",
|
||||
"starting_deadline_seconds": "123",
|
||||
"successful_jobs_history_limit": "456",
|
||||
"suspend": "1",
|
||||
"ttl_seconds_after_finished": "456",
|
||||
"uid": "1234",
|
||||
},
|
||||
}, cjs)
|
||||
}
|
73
infrastructure/kubequery/internal/k8s/batch/job.go
Normal file
73
infrastructure/kubequery/internal/k8s/batch/job.go
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package batch
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/batch/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type job struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonPodFields
|
||||
v1.JobStatus
|
||||
Parallelism *int32
|
||||
Completions *int32
|
||||
JobActiveDeadlineSeconds *int64
|
||||
BackoffLimit *int32
|
||||
Selector *metav1.LabelSelector
|
||||
ManualSelector *bool
|
||||
TTLSecondsAfterFinished *int32
|
||||
}
|
||||
|
||||
// JobColumns returns kubernetes job fields as Osquery table columns.
|
||||
func JobColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&job{})
|
||||
}
|
||||
|
||||
// JobsGenerate generates the kubernetes jobs as Osquery table data.
|
||||
func JobsGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
jobs, err := k8s.GetClient().BatchV1().Jobs(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, j := range jobs.Items {
|
||||
item := &job{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(j.ObjectMeta),
|
||||
CommonPodFields: k8s.GetCommonPodFields(j.Spec.Template.Spec),
|
||||
JobStatus: j.Status,
|
||||
Parallelism: j.Spec.Parallelism,
|
||||
Completions: j.Spec.Completions,
|
||||
JobActiveDeadlineSeconds: j.Spec.ActiveDeadlineSeconds,
|
||||
BackoffLimit: j.Spec.BackoffLimit,
|
||||
Selector: j.Spec.Selector,
|
||||
ManualSelector: j.Spec.ManualSelector,
|
||||
TTLSecondsAfterFinished: j.Spec.TTLSecondsAfterFinished,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if jobs.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = jobs.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
88
infrastructure/kubequery/internal/k8s/batch/job_test.go
Normal file
88
infrastructure/kubequery/internal/k8s/batch/job_test.go
Normal file
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package batch
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/batch/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
|
||||
func TestJobsGenerate(t *testing.T) {
|
||||
i32 := int32(456)
|
||||
i64 := int64(123)
|
||||
b := bool(true)
|
||||
k8s.SetClient(fake.NewSimpleClientset(&v1.Job{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "job1",
|
||||
Namespace: "n123",
|
||||
UID: types.UID("1234"),
|
||||
Labels: map[string]string{"a": "b"},
|
||||
},
|
||||
Spec: v1.JobSpec{
|
||||
Parallelism: &i32,
|
||||
Completions: &i32,
|
||||
ActiveDeadlineSeconds: &i64,
|
||||
BackoffLimit: &i32,
|
||||
ManualSelector: &b,
|
||||
TTLSecondsAfterFinished: &i32,
|
||||
},
|
||||
Status: v1.JobStatus{
|
||||
StartTime: &metav1.Time{},
|
||||
Active: i32,
|
||||
Succeeded: i32,
|
||||
Failed: i32,
|
||||
CompletionTime: nil,
|
||||
Conditions: []v1.JobCondition{
|
||||
{
|
||||
Type: v1.JobComplete,
|
||||
Status: metav1.DryRunAll,
|
||||
LastTransitionTime: metav1.Time{},
|
||||
Reason: "reason",
|
||||
Message: "message",
|
||||
},
|
||||
},
|
||||
},
|
||||
}), types.UID("hello"), "")
|
||||
|
||||
js, err := JobsGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"active": "456",
|
||||
"backoff_limit": "456",
|
||||
"cluster_uid": "hello",
|
||||
"completions": "456",
|
||||
"conditions": "[{\"type\":\"Complete\",\"status\":\"All\",\"lastProbeTime\":null,\"lastTransitionTime\":null,\"reason\":\"reason\",\"message\":\"message\"}]",
|
||||
"creation_timestamp": "0",
|
||||
"failed": "456",
|
||||
"host_ipc": "0",
|
||||
"host_network": "0",
|
||||
"host_pid": "0",
|
||||
"job_active_deadline_seconds": "123",
|
||||
"labels": "{\"a\":\"b\"}",
|
||||
"manual_selector": "1",
|
||||
"name": "job1",
|
||||
"namespace": "n123",
|
||||
"parallelism": "456",
|
||||
"start_time": "0",
|
||||
"succeeded": "456",
|
||||
"ttl_seconds_after_finished": "456",
|
||||
"uid": "1234",
|
||||
},
|
||||
}, js)
|
||||
}
|
125
infrastructure/kubequery/internal/k8s/client.go
Normal file
125
infrastructure/kubequery/internal/k8s/client.go
Normal file
@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/client-go/util/homedir"
|
||||
)
|
||||
|
||||
var (
|
||||
lock sync.Mutex
|
||||
clientset kubernetes.Interface
|
||||
clusterUID types.UID
|
||||
clusterName string
|
||||
)
|
||||
|
||||
func initClientset(config *rest.Config) error {
|
||||
if config == nil {
|
||||
conf, err := rest.InClusterConfig()
|
||||
if err != nil {
|
||||
if home := homedir.HomeDir(); home != "" {
|
||||
content, ferr := ioutil.ReadFile(filepath.Join(home, ".kube", "config"))
|
||||
if content != nil && ferr == nil {
|
||||
conf, err = clientcmd.RESTConfigFromKubeConfig(content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
config = conf
|
||||
}
|
||||
|
||||
// Suppress deprecation warnings
|
||||
config.WarningHandler = rest.NoWarnings{}
|
||||
|
||||
var err error
|
||||
clientset, err = kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func initUID() error {
|
||||
ks, err := GetClient().CoreV1().Namespaces().Get(context.TODO(), "kube-system", v1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clusterUID = ks.UID
|
||||
if ks.ClusterName == "" {
|
||||
clusterName, err = os.Hostname()
|
||||
if err != nil {
|
||||
fmt.Println("Unable to determine hostname: ", err.Error())
|
||||
}
|
||||
} else {
|
||||
clusterName = ks.ClusterName
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Init creates in-cluster kubernetes configuration and a client set using the configuration.
|
||||
// This returns error if KUBERNETES_SERVICE_HOST or KUBERNETES_SERVICE_PORT environment variables are not set.
|
||||
func Init() error {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
err := initClientset(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = initUID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetClient returns kubernetes interface that can be used to communicate with API server.
|
||||
func GetClient() kubernetes.Interface {
|
||||
return clientset
|
||||
}
|
||||
|
||||
// GetClusterUID returns unique identifier for the current kubernetes cluster.
|
||||
// This is same as the kube-system namespace UID.
|
||||
func GetClusterUID() types.UID {
|
||||
return clusterUID
|
||||
}
|
||||
|
||||
// GetClusterName returns cluster name provided by the kubernates API.
|
||||
// If it is empty, it uses the pod hostname which should be set to the cluster name.
|
||||
func GetClusterName() string {
|
||||
return clusterName
|
||||
}
|
||||
|
||||
// SetClient is helper function to override the kubernetes interface with fake one for testing.
|
||||
func SetClient(client kubernetes.Interface, uid types.UID, name string) {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
clientset = client
|
||||
clusterUID = uid
|
||||
clusterName = name
|
||||
}
|
33
infrastructure/kubequery/internal/k8s/client_test.go
Normal file
33
infrastructure/kubequery/internal/k8s/client_test.go
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
|
||||
func TestGetClient(t *testing.T) {
|
||||
SetClient(fake.NewSimpleClientset(), types.UID("uid"), "cluster-name")
|
||||
assert.NotNil(t, GetClient(), "Clientset should be valid")
|
||||
}
|
||||
|
||||
func TestGetClusterUID(t *testing.T) {
|
||||
SetClient(fake.NewSimpleClientset(), types.UID("uid"), "cluster-name")
|
||||
assert.Equal(t, types.UID("uid"), GetClusterUID())
|
||||
}
|
||||
|
||||
func TestGetClusterName(t *testing.T) {
|
||||
SetClient(fake.NewSimpleClientset(), types.UID("uid"), "cluster-name")
|
||||
assert.Equal(t, "cluster-name", GetClusterName())
|
||||
}
|
694
infrastructure/kubequery/internal/k8s/common.go
Normal file
694
infrastructure/kubequery/internal/k8s/common.go
Normal file
@ -0,0 +1,694 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
// CommonFields contains fields common to most tables. Contents are derived from kubernetes ObjectMeta.
|
||||
// This is used for kubernetes resources that are not namespaced.
|
||||
type CommonFields struct {
|
||||
UID types.UID
|
||||
ClusterName string
|
||||
ClusterUID types.UID
|
||||
Name string
|
||||
CreationTimestamp metav1.Time
|
||||
Labels map[string]string
|
||||
Annotations map[string]string
|
||||
}
|
||||
|
||||
// GetCommonFields returns CommonFields struct from the provided kubernetes ObjectMeta.
|
||||
func GetCommonFields(obj metav1.ObjectMeta) CommonFields {
|
||||
return CommonFields{
|
||||
UID: obj.UID,
|
||||
ClusterName: GetClusterName(),
|
||||
ClusterUID: GetClusterUID(),
|
||||
Name: obj.Name,
|
||||
CreationTimestamp: obj.CreationTimestamp,
|
||||
Labels: obj.Labels,
|
||||
Annotations: obj.Annotations,
|
||||
}
|
||||
}
|
||||
|
||||
// CommonNamespacedFields contains fields common to most tables. Contents are derived from kubernetes ObjectMeta.
|
||||
// This is used for kubernetes resources that are namespaced.
|
||||
type CommonNamespacedFields struct {
|
||||
UID types.UID
|
||||
ClusterName string
|
||||
ClusterUID types.UID
|
||||
Name string
|
||||
Namespace string
|
||||
CreationTimestamp metav1.Time
|
||||
Labels map[string]string
|
||||
Annotations map[string]string
|
||||
}
|
||||
|
||||
// GetCommonNamespacedFields returns CommonNamespacedFields struct from the provided kubernetes ObjectMeta.
|
||||
func GetCommonNamespacedFields(obj metav1.ObjectMeta) CommonNamespacedFields {
|
||||
return CommonNamespacedFields{
|
||||
UID: obj.UID,
|
||||
ClusterName: GetClusterName(),
|
||||
ClusterUID: GetClusterUID(),
|
||||
Name: obj.Name,
|
||||
Namespace: obj.Namespace,
|
||||
CreationTimestamp: obj.CreationTimestamp,
|
||||
Labels: obj.Labels,
|
||||
Annotations: obj.Annotations,
|
||||
}
|
||||
}
|
||||
|
||||
// GetParentCommonNamespacedFields returns CommonNamespacedFields struct from the parent ObjectMeta creating a UID using parent UID + provided name.
|
||||
func GetParentCommonNamespacedFields(parent metav1.ObjectMeta, name string) CommonNamespacedFields {
|
||||
uid := uuid.NewSHA1(uuid.NameSpaceDNS, []byte(string(parent.UID)+name)).String()
|
||||
return CommonNamespacedFields{
|
||||
UID: types.UID(uid),
|
||||
ClusterName: GetClusterName(),
|
||||
ClusterUID: GetClusterUID(),
|
||||
Name: name,
|
||||
Namespace: parent.Namespace,
|
||||
CreationTimestamp: parent.CreationTimestamp,
|
||||
Labels: parent.Labels,
|
||||
Annotations: parent.Annotations,
|
||||
}
|
||||
}
|
||||
|
||||
// SELinuxOptionsFields contains SELinux options as a flat structure.
|
||||
type SELinuxOptionsFields struct {
|
||||
SELinuxOptionsUser string
|
||||
SELinuxOptionsRole string
|
||||
SELinuxOptionsType string
|
||||
SELinuxOptionsLevel string
|
||||
}
|
||||
|
||||
// WindowsOptionsFields contains Windows options as a flat structure.
|
||||
type WindowsOptionsFields struct {
|
||||
WindowsOptionsGMSACredentialSpecName *string
|
||||
WindowsOptionsGMSACredentialSpec *string
|
||||
WindowsOptionsRunAsUserName *string
|
||||
}
|
||||
|
||||
// SeccompProfileFields contains Seccomp profile options as a flat structure.
|
||||
type SeccompProfileFields struct {
|
||||
SeccompProfileType v1.SeccompProfileType
|
||||
SeccompProfileLocalhostProfile *string
|
||||
}
|
||||
|
||||
// CommonSecurityContextFields contains all security options common to a pod and container.
|
||||
type CommonSecurityContextFields struct {
|
||||
SELinuxOptionsFields
|
||||
WindowsOptionsFields
|
||||
SeccompProfileFields
|
||||
RunAsUser *int64
|
||||
RunAsGroup *int64
|
||||
RunAsNonRoot *bool
|
||||
}
|
||||
|
||||
// PodSecurityContextFields contains all security options specific to a pod.
|
||||
type PodSecurityContextFields struct {
|
||||
CommonSecurityContextFields
|
||||
SupplementalGroups []int64
|
||||
FSGroup *int64
|
||||
Sysctls []v1.Sysctl
|
||||
FSGroupChangePolicy *v1.PodFSGroupChangePolicy
|
||||
}
|
||||
|
||||
// SecurityContextFields contains all securoty options specific to a container.
|
||||
type SecurityContextFields struct {
|
||||
CommonSecurityContextFields
|
||||
CapabilitiesAdd []v1.Capability
|
||||
CapabilitiesDrop []v1.Capability
|
||||
Privileged *bool
|
||||
ReadOnlyRootFilesystem *bool
|
||||
AllowPrivilegeEscalation *bool
|
||||
ProcMount *v1.ProcMountType
|
||||
}
|
||||
|
||||
// AffinityFields struct holds flat affinity fields.
|
||||
type AffinityFields struct {
|
||||
NodeAffinity *v1.NodeAffinity
|
||||
PodAffinity *v1.PodAffinity
|
||||
PodAntiAffinity *v1.PodAntiAffinity
|
||||
}
|
||||
|
||||
// DNSConfigFields struct holds DNS configuration fields.
|
||||
type DNSConfigFields struct {
|
||||
DNSConfigNameservers []string
|
||||
DNSConfigSearches []string
|
||||
DNSConfigOptions []v1.PodDNSConfigOption
|
||||
}
|
||||
|
||||
// CommonPodFields contains relevant fields from pod specification.
|
||||
// This flattens some of the embedded structures like security context, DNS config etc.
|
||||
type CommonPodFields struct {
|
||||
PodSecurityContextFields
|
||||
AffinityFields
|
||||
DNSConfigFields
|
||||
|
||||
NodeSelector map[string]string
|
||||
RestartPolicy v1.RestartPolicy
|
||||
TerminationGracePeriodSeconds *int64
|
||||
ActiveDeadlineSeconds *int64
|
||||
DNSPolicy v1.DNSPolicy
|
||||
ServiceAccountName string
|
||||
AutomountServiceAccountToken *bool
|
||||
NodeName string
|
||||
HostNetwork bool
|
||||
HostPID bool
|
||||
HostIPC bool
|
||||
ShareProcessNamespace *bool
|
||||
ImagePullSecrets []v1.LocalObjectReference
|
||||
Hostname string
|
||||
Subdomain string
|
||||
SchedulerName string
|
||||
Tolerations []v1.Toleration
|
||||
HostAliases []v1.HostAlias
|
||||
PriorityClassName string
|
||||
Priority *int32
|
||||
ReadinessGates []v1.PodReadinessGate
|
||||
RuntimeClassName *string
|
||||
EnableServiceLinks *bool
|
||||
PreemptionPolicy *v1.PreemptionPolicy
|
||||
Overhead v1.ResourceList
|
||||
TopologySpreadConstraints []v1.TopologySpreadConstraint
|
||||
SetHostnameAsFQDN *bool
|
||||
}
|
||||
|
||||
// GetCommonPodFields converts pod specification to CommonPodFields structure.
|
||||
// This flattens some of the embedded structures like security context, DNS config etc.
|
||||
func GetCommonPodFields(p v1.PodSpec) CommonPodFields {
|
||||
item := CommonPodFields{
|
||||
NodeSelector: p.NodeSelector,
|
||||
RestartPolicy: p.RestartPolicy,
|
||||
TerminationGracePeriodSeconds: p.TerminationGracePeriodSeconds,
|
||||
ActiveDeadlineSeconds: p.ActiveDeadlineSeconds,
|
||||
DNSPolicy: p.DNSPolicy,
|
||||
ServiceAccountName: p.ServiceAccountName,
|
||||
AutomountServiceAccountToken: p.AutomountServiceAccountToken,
|
||||
NodeName: p.NodeName,
|
||||
HostNetwork: p.HostNetwork,
|
||||
HostPID: p.HostPID,
|
||||
HostIPC: p.HostIPC,
|
||||
ShareProcessNamespace: p.ShareProcessNamespace,
|
||||
ImagePullSecrets: p.ImagePullSecrets,
|
||||
Hostname: p.Hostname,
|
||||
Subdomain: p.Subdomain,
|
||||
SchedulerName: p.SchedulerName,
|
||||
Tolerations: p.Tolerations,
|
||||
HostAliases: p.HostAliases,
|
||||
PriorityClassName: p.PriorityClassName,
|
||||
Priority: p.Priority,
|
||||
ReadinessGates: p.ReadinessGates,
|
||||
RuntimeClassName: p.RuntimeClassName,
|
||||
EnableServiceLinks: p.EnableServiceLinks,
|
||||
PreemptionPolicy: p.PreemptionPolicy,
|
||||
Overhead: p.Overhead,
|
||||
TopologySpreadConstraints: p.TopologySpreadConstraints,
|
||||
SetHostnameAsFQDN: p.SetHostnameAsFQDN,
|
||||
}
|
||||
if p.Affinity != nil {
|
||||
item.NodeAffinity = p.Affinity.NodeAffinity
|
||||
item.PodAffinity = p.Affinity.PodAffinity
|
||||
item.PodAntiAffinity = p.Affinity.PodAntiAffinity
|
||||
}
|
||||
if p.DNSConfig != nil {
|
||||
item.DNSConfigNameservers = p.DNSConfig.Nameservers
|
||||
item.DNSConfigSearches = p.DNSConfig.Searches
|
||||
item.DNSConfigOptions = p.DNSConfig.Options
|
||||
}
|
||||
if p.SecurityContext != nil {
|
||||
item.RunAsUser = p.SecurityContext.RunAsUser
|
||||
item.RunAsGroup = p.SecurityContext.RunAsGroup
|
||||
item.RunAsNonRoot = p.SecurityContext.RunAsNonRoot
|
||||
item.SupplementalGroups = p.SecurityContext.SupplementalGroups
|
||||
item.Sysctls = p.SecurityContext.Sysctls
|
||||
item.FSGroup = p.SecurityContext.FSGroup
|
||||
item.FSGroupChangePolicy = p.SecurityContext.FSGroupChangePolicy
|
||||
if p.SecurityContext.SeccompProfile != nil {
|
||||
item.SeccompProfileType = p.SecurityContext.SeccompProfile.Type
|
||||
item.SeccompProfileLocalhostProfile = p.SecurityContext.SeccompProfile.LocalhostProfile
|
||||
}
|
||||
if p.SecurityContext.SELinuxOptions != nil {
|
||||
item.SELinuxOptionsLevel = p.SecurityContext.SELinuxOptions.Level
|
||||
item.SELinuxOptionsRole = p.SecurityContext.SELinuxOptions.Role
|
||||
item.SELinuxOptionsType = p.SecurityContext.SELinuxOptions.Type
|
||||
item.SELinuxOptionsUser = p.SecurityContext.SELinuxOptions.User
|
||||
}
|
||||
if p.SecurityContext.WindowsOptions != nil {
|
||||
item.WindowsOptionsRunAsUserName = p.SecurityContext.WindowsOptions.RunAsUserName
|
||||
item.WindowsOptionsGMSACredentialSpec = p.SecurityContext.WindowsOptions.GMSACredentialSpec
|
||||
item.WindowsOptionsGMSACredentialSpecName = p.SecurityContext.WindowsOptions.GMSACredentialSpecName
|
||||
}
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
// CommonContainerFields contains relevant fields from container specification.
|
||||
// This flattens some of the embedded structures like security context.
|
||||
type CommonContainerFields struct {
|
||||
SecurityContextFields
|
||||
TargetContainerName string
|
||||
Image string
|
||||
Command []string
|
||||
Args []string
|
||||
WorkingDir string
|
||||
Ports []v1.ContainerPort
|
||||
EnvFrom []v1.EnvFromSource
|
||||
Env []v1.EnvVar
|
||||
ResourceLimits v1.ResourceList
|
||||
ResourceRequests v1.ResourceList
|
||||
VolumeMounts []v1.VolumeMount
|
||||
VolumeDevices []v1.VolumeDevice
|
||||
LivenessProbe *v1.Probe
|
||||
ReadinessProbe *v1.Probe
|
||||
StartupProbe *v1.Probe
|
||||
Lifecycle *v1.Lifecycle
|
||||
TerminationMessagePath string
|
||||
TerminationMessagePolicy v1.TerminationMessagePolicy
|
||||
ImagePullPolicy v1.PullPolicy
|
||||
Stdin bool
|
||||
StdinOnce bool
|
||||
TTY bool
|
||||
}
|
||||
|
||||
// GetCommonContainerFields converts container specification to CommonContainerFields structure.
|
||||
// This flattens some of the embedded structures like security context.
|
||||
func GetCommonContainerFields(c v1.Container) CommonContainerFields {
|
||||
item := CommonContainerFields{
|
||||
Image: c.Image,
|
||||
Command: c.Command,
|
||||
Args: c.Args,
|
||||
WorkingDir: c.WorkingDir,
|
||||
Ports: c.Ports,
|
||||
EnvFrom: c.EnvFrom,
|
||||
Env: c.Env,
|
||||
ResourceLimits: c.Resources.Limits,
|
||||
ResourceRequests: c.Resources.Requests,
|
||||
VolumeMounts: c.VolumeMounts,
|
||||
VolumeDevices: c.VolumeDevices,
|
||||
LivenessProbe: c.LivenessProbe,
|
||||
ReadinessProbe: c.ReadinessProbe,
|
||||
StartupProbe: c.StartupProbe,
|
||||
Lifecycle: c.Lifecycle,
|
||||
TerminationMessagePath: c.TerminationMessagePath,
|
||||
TerminationMessagePolicy: c.TerminationMessagePolicy,
|
||||
ImagePullPolicy: c.ImagePullPolicy,
|
||||
Stdin: c.Stdin,
|
||||
StdinOnce: c.StdinOnce,
|
||||
TTY: c.TTY,
|
||||
}
|
||||
copyContainerSecurityContext(&item, c.SecurityContext)
|
||||
return item
|
||||
}
|
||||
|
||||
// GetCommonEphemeralContainerFields converts ephemeral container specification to CommonContainerFields.
|
||||
// This flattens some of the embedded structures like security context.
|
||||
// Ephemeral container contains one additional field (TargetContainerName) on top of container.
|
||||
func GetCommonEphemeralContainerFields(c v1.EphemeralContainer) CommonContainerFields {
|
||||
item := CommonContainerFields{
|
||||
TargetContainerName: c.TargetContainerName,
|
||||
Image: c.Image,
|
||||
Command: c.Command,
|
||||
Args: c.Args,
|
||||
WorkingDir: c.WorkingDir,
|
||||
Ports: c.Ports,
|
||||
EnvFrom: c.EnvFrom,
|
||||
Env: c.Env,
|
||||
ResourceLimits: c.Resources.Limits,
|
||||
ResourceRequests: c.Resources.Requests,
|
||||
VolumeMounts: c.VolumeMounts,
|
||||
VolumeDevices: c.VolumeDevices,
|
||||
LivenessProbe: c.LivenessProbe,
|
||||
ReadinessProbe: c.ReadinessProbe,
|
||||
StartupProbe: c.StartupProbe,
|
||||
Lifecycle: c.Lifecycle,
|
||||
TerminationMessagePath: c.TerminationMessagePath,
|
||||
TerminationMessagePolicy: c.TerminationMessagePolicy,
|
||||
ImagePullPolicy: c.ImagePullPolicy,
|
||||
Stdin: c.Stdin,
|
||||
StdinOnce: c.StdinOnce,
|
||||
TTY: c.TTY,
|
||||
}
|
||||
copyContainerSecurityContext(&item, c.SecurityContext)
|
||||
return item
|
||||
}
|
||||
|
||||
func copyContainerSecurityContext(item *CommonContainerFields, sc *v1.SecurityContext) {
|
||||
if sc != nil {
|
||||
item.Privileged = sc.Privileged
|
||||
item.RunAsUser = sc.RunAsUser
|
||||
item.RunAsGroup = sc.RunAsGroup
|
||||
item.RunAsNonRoot = sc.RunAsNonRoot
|
||||
item.ReadOnlyRootFilesystem = sc.ReadOnlyRootFilesystem
|
||||
item.AllowPrivilegeEscalation = sc.AllowPrivilegeEscalation
|
||||
item.ProcMount = sc.ProcMount
|
||||
|
||||
if sc.Capabilities != nil {
|
||||
item.CapabilitiesAdd = sc.Capabilities.Add
|
||||
item.CapabilitiesDrop = sc.Capabilities.Drop
|
||||
}
|
||||
if sc.SeccompProfile != nil {
|
||||
item.SeccompProfileType = sc.SeccompProfile.Type
|
||||
item.SeccompProfileLocalhostProfile = sc.SeccompProfile.LocalhostProfile
|
||||
}
|
||||
if sc.SELinuxOptions != nil {
|
||||
item.SELinuxOptionsLevel = sc.SELinuxOptions.Level
|
||||
item.SELinuxOptionsRole = sc.SELinuxOptions.Role
|
||||
item.SELinuxOptionsType = sc.SELinuxOptions.Type
|
||||
item.SELinuxOptionsUser = sc.SELinuxOptions.User
|
||||
}
|
||||
if sc.WindowsOptions != nil {
|
||||
item.WindowsOptionsRunAsUserName = sc.WindowsOptions.RunAsUserName
|
||||
item.WindowsOptionsGMSACredentialSpec = sc.WindowsOptions.GMSACredentialSpec
|
||||
item.WindowsOptionsGMSACredentialSpecName = sc.WindowsOptions.GMSACredentialSpecName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CommonVolumeFields contains flattened fields from volume specification.
|
||||
type CommonVolumeFields struct {
|
||||
VolumeType string
|
||||
FSType *string
|
||||
ReadOnly *bool
|
||||
SecretName string
|
||||
HostPathPath string
|
||||
HostPathType *v1.HostPathType
|
||||
EmptyDirMedium v1.StorageMedium
|
||||
EmptyDirSizeLimit string
|
||||
GCEPersistentDiskPDName string
|
||||
GCEPersistentDiskPartition int32
|
||||
AWSElasticBlockStoreVolumeID string
|
||||
AWSElasticBlockStorePartition int32
|
||||
GitRepoRepository string
|
||||
GitRepoRevision string
|
||||
GitRepoDirectory string
|
||||
SecretItems []v1.KeyToPath
|
||||
SecretDefaultMode *int32
|
||||
SecretOptional *bool
|
||||
NFSServer string
|
||||
NFSPath string
|
||||
ISCSITargetPortal string
|
||||
ISCSIIqn string
|
||||
ISCSILun int32
|
||||
ISCSIInterface string
|
||||
ISCSIPortals []string
|
||||
ISCSIDiscoveryCHAPAuth bool
|
||||
ISCSISessionCHAPAuth bool
|
||||
ISCSIInitiatorName *string
|
||||
GlusterfsEndpointsName string
|
||||
GlusterfsPath string
|
||||
PersistentVolumeClaimName string
|
||||
RBDCephMonitors []string
|
||||
RBDImage string
|
||||
RBDPool string
|
||||
RBDRadosUser string
|
||||
RBDKeyring string
|
||||
FlexVolumeDriver string
|
||||
FlexVolumeOptions map[string]string
|
||||
CinderVolumeID string
|
||||
CephFSMonitors []string
|
||||
CephFSPath string
|
||||
CephFSUser string
|
||||
CephFSSecretFile string
|
||||
FlockerDatasetName string
|
||||
FlockerDatasetUUID string
|
||||
DownwardAPIItems []v1.DownwardAPIVolumeFile
|
||||
DownwardAPIDefaultMode *int32
|
||||
FCTargetWWNs []string
|
||||
FCLun *int32
|
||||
FcWWIDs []string
|
||||
AzureFileShareName string
|
||||
ConfigMapName string
|
||||
ConfigMapItems []v1.KeyToPath
|
||||
ConfigMapDefaultMode *int32
|
||||
ConfigMapOptional *bool
|
||||
VsphereVolumeVolumePath string
|
||||
VsphereVolumeStoragePolicyName string
|
||||
VsphereVolumeStoragePolicyID string
|
||||
QuobyteRegistry string
|
||||
QuobyteVolume string
|
||||
QuobyteUser string
|
||||
QuobyteGroup string
|
||||
QuobyteTenant string
|
||||
AzureDiskDiskName string
|
||||
AzureDiskDataDiskURI string
|
||||
AzureDiskCachingMode *v1.AzureDataDiskCachingMode
|
||||
AzureDiskKind *v1.AzureDataDiskKind
|
||||
PhotonPersistentDiskPdID string
|
||||
ProjectedSources []v1.VolumeProjection
|
||||
ProjectedDefaultMode *int32
|
||||
PortworxVolumeID string
|
||||
ScaleIOGateway string
|
||||
ScaleIOSystem string
|
||||
ScaleIOSSLEnabled bool
|
||||
ScaleIOProtectionDomain string
|
||||
ScaleIOStoragePool string
|
||||
ScaleIOStorageMode string
|
||||
ScaleIOVolumeName string
|
||||
StorageOSVolumeName string
|
||||
StorageOSVolumeNamespace string
|
||||
CSIDriver string
|
||||
CSIVolumeAttributes map[string]string
|
||||
EphemeralVolumeClaimTemplate *v1.PersistentVolumeClaimTemplate
|
||||
}
|
||||
|
||||
// GetCommonVolumeFields converts volume specification to CommonVolumeFields.
|
||||
// This flattens most of the embedded structures like AWSElasticBlockStore, AzureDisk, etc.
|
||||
func GetCommonVolumeFields(from v1.Volume) CommonVolumeFields {
|
||||
to := CommonVolumeFields{}
|
||||
if from.AWSElasticBlockStore != nil {
|
||||
to.VolumeType = "aws_elastic_block_store"
|
||||
to.AWSElasticBlockStoreVolumeID = from.AWSElasticBlockStore.VolumeID
|
||||
to.AWSElasticBlockStorePartition = from.AWSElasticBlockStore.Partition
|
||||
to.FSType = &from.AWSElasticBlockStore.FSType
|
||||
to.ReadOnly = &from.AWSElasticBlockStore.ReadOnly
|
||||
}
|
||||
if from.AzureDisk != nil {
|
||||
to.VolumeType = "azure_disk"
|
||||
to.AzureDiskCachingMode = from.AzureDisk.CachingMode
|
||||
to.AzureDiskDataDiskURI = from.AzureDisk.DataDiskURI
|
||||
to.AzureDiskDiskName = from.AzureDisk.DiskName
|
||||
to.AzureDiskKind = from.AzureDisk.Kind
|
||||
to.FSType = from.AzureDisk.FSType
|
||||
to.ReadOnly = from.AzureDisk.ReadOnly
|
||||
}
|
||||
if from.AzureFile != nil {
|
||||
to.VolumeType = "azure_file"
|
||||
to.AzureFileShareName = from.AzureFile.ShareName
|
||||
to.SecretName = from.AzureFile.SecretName
|
||||
to.ReadOnly = &from.AzureFile.ReadOnly
|
||||
}
|
||||
if from.CSI != nil {
|
||||
to.VolumeType = "csi"
|
||||
to.CSIDriver = from.CSI.Driver
|
||||
to.CSIVolumeAttributes = from.CSI.VolumeAttributes
|
||||
to.FSType = from.CSI.FSType
|
||||
to.ReadOnly = from.CSI.ReadOnly
|
||||
if from.CSI.NodePublishSecretRef != nil {
|
||||
to.SecretName = from.CSI.NodePublishSecretRef.Name
|
||||
}
|
||||
}
|
||||
if from.CephFS != nil {
|
||||
to.VolumeType = "ceph_fs"
|
||||
to.CephFSMonitors = from.CephFS.Monitors
|
||||
to.CephFSPath = from.CephFS.Path
|
||||
to.CephFSSecretFile = from.CephFS.SecretFile
|
||||
to.CephFSUser = from.CephFS.User
|
||||
to.ReadOnly = &from.CephFS.ReadOnly
|
||||
if from.CephFS.SecretRef != nil {
|
||||
to.SecretName = from.CephFS.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if from.Cinder != nil {
|
||||
to.VolumeType = "cinder"
|
||||
to.CinderVolumeID = from.Cinder.VolumeID
|
||||
to.FSType = &from.Cinder.FSType
|
||||
to.ReadOnly = &from.Cinder.ReadOnly
|
||||
if from.Cinder.SecretRef != nil {
|
||||
to.SecretName = from.Cinder.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if from.ConfigMap != nil {
|
||||
to.VolumeType = "config_map"
|
||||
to.ConfigMapDefaultMode = from.ConfigMap.DefaultMode
|
||||
to.ConfigMapItems = from.ConfigMap.Items
|
||||
to.ConfigMapName = from.ConfigMap.Name
|
||||
to.ConfigMapOptional = from.ConfigMap.Optional
|
||||
}
|
||||
if from.DownwardAPI != nil {
|
||||
to.VolumeType = "downward_api"
|
||||
to.DownwardAPIDefaultMode = from.DownwardAPI.DefaultMode
|
||||
to.DownwardAPIItems = from.DownwardAPI.Items
|
||||
}
|
||||
if from.EmptyDir != nil {
|
||||
to.VolumeType = "empty_dir"
|
||||
to.EmptyDirMedium = from.EmptyDir.Medium
|
||||
to.EmptyDirSizeLimit = from.EmptyDir.SizeLimit.String()
|
||||
}
|
||||
if from.Ephemeral != nil {
|
||||
to.VolumeType = "ephemeral"
|
||||
to.EphemeralVolumeClaimTemplate = from.Ephemeral.VolumeClaimTemplate
|
||||
}
|
||||
if from.FC != nil {
|
||||
to.VolumeType = "fc"
|
||||
to.FCLun = from.FC.Lun
|
||||
to.FCTargetWWNs = from.FC.TargetWWNs
|
||||
to.FcWWIDs = from.FC.WWIDs
|
||||
to.FSType = &from.FC.FSType
|
||||
to.ReadOnly = &from.FC.ReadOnly
|
||||
}
|
||||
if from.FlexVolume != nil {
|
||||
to.VolumeType = "flex_volume"
|
||||
to.FlexVolumeDriver = from.FlexVolume.Driver
|
||||
to.FlexVolumeOptions = from.FlexVolume.Options
|
||||
to.FSType = &from.FlexVolume.FSType
|
||||
to.ReadOnly = &from.FlexVolume.ReadOnly
|
||||
if from.FlexVolume.SecretRef != nil {
|
||||
to.SecretName = from.FlexVolume.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if from.Flocker != nil {
|
||||
to.VolumeType = "flocker"
|
||||
to.FlockerDatasetName = from.Flocker.DatasetName
|
||||
to.FlockerDatasetUUID = from.Flocker.DatasetUUID
|
||||
}
|
||||
if from.GCEPersistentDisk != nil {
|
||||
to.VolumeType = "gce_persistent_disk"
|
||||
to.GCEPersistentDiskPDName = from.GCEPersistentDisk.PDName
|
||||
to.GCEPersistentDiskPartition = from.GCEPersistentDisk.Partition
|
||||
to.FSType = &from.GCEPersistentDisk.FSType
|
||||
to.ReadOnly = &from.GCEPersistentDisk.ReadOnly
|
||||
}
|
||||
if from.GitRepo != nil {
|
||||
to.VolumeType = "git_repo"
|
||||
to.GitRepoDirectory = from.GitRepo.Directory
|
||||
to.GitRepoRepository = from.GitRepo.Repository
|
||||
to.GitRepoRevision = from.GitRepo.Revision
|
||||
}
|
||||
if from.Glusterfs != nil {
|
||||
to.VolumeType = "gluster_fs"
|
||||
to.GlusterfsPath = from.Glusterfs.Path
|
||||
to.GlusterfsEndpointsName = from.Glusterfs.EndpointsName
|
||||
to.ReadOnly = &from.Glusterfs.ReadOnly
|
||||
}
|
||||
if from.HostPath != nil {
|
||||
to.VolumeType = "host_path"
|
||||
to.HostPathPath = from.HostPath.Path
|
||||
to.HostPathType = from.HostPath.Type
|
||||
}
|
||||
if from.ISCSI != nil {
|
||||
to.VolumeType = "iscsci"
|
||||
to.ISCSITargetPortal = from.ISCSI.TargetPortal
|
||||
to.ISCSIIqn = from.ISCSI.IQN
|
||||
to.ISCSILun = from.ISCSI.Lun
|
||||
to.ISCSIInterface = from.ISCSI.ISCSIInterface
|
||||
to.ISCSIPortals = from.ISCSI.Portals
|
||||
to.ISCSIDiscoveryCHAPAuth = from.ISCSI.DiscoveryCHAPAuth
|
||||
to.ISCSISessionCHAPAuth = from.ISCSI.SessionCHAPAuth
|
||||
to.ISCSIInitiatorName = from.ISCSI.InitiatorName
|
||||
to.FSType = &from.ISCSI.FSType
|
||||
to.ReadOnly = &from.ISCSI.ReadOnly
|
||||
if from.ISCSI.SecretRef != nil {
|
||||
to.SecretName = from.ISCSI.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if from.NFS != nil {
|
||||
to.VolumeType = "nfs"
|
||||
to.NFSPath = from.NFS.Path
|
||||
to.NFSServer = from.NFS.Server
|
||||
to.ReadOnly = &from.NFS.ReadOnly
|
||||
}
|
||||
if from.PersistentVolumeClaim != nil {
|
||||
to.VolumeType = "persistent_volume_claim"
|
||||
to.PersistentVolumeClaimName = from.PersistentVolumeClaim.ClaimName
|
||||
to.ReadOnly = &from.PersistentVolumeClaim.ReadOnly
|
||||
}
|
||||
if from.PhotonPersistentDisk != nil {
|
||||
to.VolumeType = "photon_persistent_disk"
|
||||
to.PhotonPersistentDiskPdID = from.PhotonPersistentDisk.PdID
|
||||
to.FSType = &from.PhotonPersistentDisk.FSType
|
||||
}
|
||||
if from.PortworxVolume != nil {
|
||||
to.VolumeType = "portworx_volume"
|
||||
to.PortworxVolumeID = from.PortworxVolume.VolumeID
|
||||
to.FSType = &from.PortworxVolume.FSType
|
||||
to.ReadOnly = &from.PortworxVolume.ReadOnly
|
||||
}
|
||||
if from.Projected != nil {
|
||||
to.VolumeType = "projected"
|
||||
to.ProjectedDefaultMode = from.Projected.DefaultMode
|
||||
to.ProjectedSources = from.Projected.Sources
|
||||
}
|
||||
if from.Quobyte != nil {
|
||||
to.VolumeType = "quobyte"
|
||||
to.QuobyteGroup = from.Quobyte.Group
|
||||
to.QuobyteRegistry = from.Quobyte.Registry
|
||||
to.QuobyteTenant = from.Quobyte.Tenant
|
||||
to.QuobyteUser = from.Quobyte.User
|
||||
to.QuobyteVolume = from.Quobyte.Volume
|
||||
to.ReadOnly = &from.Quobyte.ReadOnly
|
||||
}
|
||||
if from.RBD != nil {
|
||||
to.VolumeType = "rbd"
|
||||
to.RBDCephMonitors = from.RBD.CephMonitors
|
||||
to.RBDImage = from.RBD.RBDImage
|
||||
to.RBDPool = from.RBD.RBDPool
|
||||
to.RBDRadosUser = from.RBD.RadosUser
|
||||
to.RBDKeyring = from.RBD.Keyring
|
||||
to.FSType = &from.RBD.FSType
|
||||
to.ReadOnly = &from.RBD.ReadOnly
|
||||
if from.RBD.SecretRef != nil {
|
||||
to.SecretName = from.RBD.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if from.ScaleIO != nil {
|
||||
to.VolumeType = "scaleio"
|
||||
to.ScaleIOGateway = from.ScaleIO.Gateway
|
||||
to.ScaleIOSystem = from.ScaleIO.System
|
||||
to.ScaleIOSSLEnabled = from.ScaleIO.SSLEnabled
|
||||
to.ScaleIOProtectionDomain = from.ScaleIO.ProtectionDomain
|
||||
to.ScaleIOStoragePool = from.ScaleIO.StoragePool
|
||||
to.ScaleIOStorageMode = from.ScaleIO.StorageMode
|
||||
to.ScaleIOVolumeName = from.ScaleIO.VolumeName
|
||||
to.FSType = &from.ScaleIO.FSType
|
||||
to.ReadOnly = &from.ScaleIO.ReadOnly
|
||||
if from.ScaleIO.SecretRef != nil {
|
||||
to.SecretName = from.ScaleIO.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if from.Secret != nil {
|
||||
to.VolumeType = "secret"
|
||||
to.SecretName = from.Secret.SecretName
|
||||
to.SecretItems = from.Secret.Items
|
||||
to.SecretDefaultMode = from.Secret.DefaultMode
|
||||
to.SecretOptional = from.Secret.Optional
|
||||
}
|
||||
if from.StorageOS != nil {
|
||||
to.VolumeType = "storage_os"
|
||||
to.StorageOSVolumeName = from.StorageOS.VolumeName
|
||||
to.StorageOSVolumeNamespace = from.StorageOS.VolumeNamespace
|
||||
to.FSType = &from.StorageOS.FSType
|
||||
to.ReadOnly = &from.StorageOS.ReadOnly
|
||||
if from.StorageOS.SecretRef != nil {
|
||||
to.SecretName = from.StorageOS.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if from.VsphereVolume != nil {
|
||||
to.VolumeType = "vsphere_volume"
|
||||
to.VsphereVolumeStoragePolicyID = from.VsphereVolume.StoragePolicyID
|
||||
to.VsphereVolumeStoragePolicyName = from.VsphereVolume.StoragePolicyName
|
||||
to.VsphereVolumeVolumePath = from.VsphereVolume.VolumePath
|
||||
to.FSType = &from.VsphereVolume.FSType
|
||||
}
|
||||
return to
|
||||
}
|
428
infrastructure/kubequery/internal/k8s/common_test.go
Normal file
428
infrastructure/kubequery/internal/k8s/common_test.go
Normal file
@ -0,0 +1,428 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
func TestGetCommonFields(t *testing.T) {
|
||||
meta := metav1.ObjectMeta{
|
||||
Name: "n123",
|
||||
GenerateName: "g123",
|
||||
Namespace: "kube-system",
|
||||
SelfLink: "/",
|
||||
UID: types.UID("u123"),
|
||||
ResourceVersion: "r123",
|
||||
Generation: 1,
|
||||
CreationTimestamp: metav1.Time{},
|
||||
DeletionGracePeriodSeconds: nil,
|
||||
Labels: map[string]string{"a": "b"},
|
||||
ClusterName: "",
|
||||
}
|
||||
assert.Equal(t, GetCommonFields(meta), CommonFields{
|
||||
UID: meta.UID,
|
||||
Name: meta.Name,
|
||||
ClusterName: "cluster-name",
|
||||
ClusterUID: types.UID("uid"),
|
||||
CreationTimestamp: meta.CreationTimestamp,
|
||||
Labels: meta.Labels,
|
||||
Annotations: meta.Annotations,
|
||||
}, "Common fields should match")
|
||||
}
|
||||
|
||||
func TestGetNamespaceCommonFields(t *testing.T) {
|
||||
meta := metav1.ObjectMeta{
|
||||
Name: "n123",
|
||||
GenerateName: "g123",
|
||||
Namespace: "kube-system",
|
||||
SelfLink: "/",
|
||||
UID: types.UID("u123"),
|
||||
ResourceVersion: "r123",
|
||||
Generation: 1,
|
||||
CreationTimestamp: metav1.Time{},
|
||||
DeletionGracePeriodSeconds: nil,
|
||||
Annotations: map[string]string{"a": "b"},
|
||||
ClusterName: "",
|
||||
}
|
||||
assert.Equal(t, GetCommonNamespacedFields(meta), CommonNamespacedFields{
|
||||
UID: meta.UID,
|
||||
Name: meta.Name,
|
||||
Namespace: meta.Namespace,
|
||||
ClusterName: "cluster-name",
|
||||
ClusterUID: types.UID("uid"),
|
||||
CreationTimestamp: meta.CreationTimestamp,
|
||||
Labels: meta.Labels,
|
||||
Annotations: meta.Annotations,
|
||||
}, "Common namespace fields should match")
|
||||
}
|
||||
|
||||
func TestGetCommonPodFields(t *testing.T) {
|
||||
i32 := int32(456)
|
||||
i64 := int64(123)
|
||||
b := bool(true)
|
||||
s := string("s123")
|
||||
pod := v1.PodSpec{
|
||||
RestartPolicy: v1.RestartPolicyAlways,
|
||||
TerminationGracePeriodSeconds: &i64,
|
||||
ActiveDeadlineSeconds: &i64,
|
||||
DNSPolicy: v1.DNSClusterFirst,
|
||||
ServiceAccountName: "s123",
|
||||
AutomountServiceAccountToken: &b,
|
||||
NodeSelector: make(map[string]string),
|
||||
NodeName: "n123",
|
||||
HostNetwork: true,
|
||||
HostPID: true,
|
||||
HostIPC: true,
|
||||
ShareProcessNamespace: &b,
|
||||
ImagePullSecrets: make([]v1.LocalObjectReference, 3),
|
||||
Hostname: "h123",
|
||||
Subdomain: "sub123",
|
||||
Affinity: &v1.Affinity{NodeAffinity: &v1.NodeAffinity{RequiredDuringSchedulingIgnoredDuringExecution: &v1.NodeSelector{}}},
|
||||
SchedulerName: "sn123",
|
||||
Tolerations: make([]v1.Toleration, 2),
|
||||
HostAliases: make([]v1.HostAlias, 1),
|
||||
PriorityClassName: "p123",
|
||||
Priority: &i32,
|
||||
ReadinessGates: []v1.PodReadinessGate{},
|
||||
RuntimeClassName: &s,
|
||||
EnableServiceLinks: &b,
|
||||
PreemptionPolicy: nil,
|
||||
Overhead: make(v1.ResourceList),
|
||||
TopologySpreadConstraints: make([]v1.TopologySpreadConstraint, 4),
|
||||
SetHostnameAsFQDN: &b,
|
||||
DNSConfig: &v1.PodDNSConfig{
|
||||
Nameservers: make([]string, 1),
|
||||
Searches: make([]string, 2),
|
||||
Options: make([]v1.PodDNSConfigOption, 3),
|
||||
},
|
||||
SecurityContext: &v1.PodSecurityContext{
|
||||
RunAsUser: &i64,
|
||||
RunAsGroup: &i64,
|
||||
RunAsNonRoot: &b,
|
||||
FSGroup: &i64,
|
||||
FSGroupChangePolicy: (*v1.PodFSGroupChangePolicy)(&s),
|
||||
Sysctls: []v1.Sysctl{{Name: "n1", Value: "v1"}},
|
||||
SELinuxOptions: &v1.SELinuxOptions{User: "u123", Role: "r123", Type: "t123", Level: "l123"},
|
||||
SupplementalGroups: make([]int64, 1),
|
||||
SeccompProfile: &v1.SeccompProfile{Type: "t123"},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, GetCommonPodFields(pod), CommonPodFields{
|
||||
PodSecurityContextFields: PodSecurityContextFields{
|
||||
CommonSecurityContextFields: CommonSecurityContextFields{
|
||||
SELinuxOptionsFields: SELinuxOptionsFields{
|
||||
SELinuxOptionsUser: pod.SecurityContext.SELinuxOptions.User,
|
||||
SELinuxOptionsRole: pod.SecurityContext.SELinuxOptions.Role,
|
||||
SELinuxOptionsType: pod.SecurityContext.SELinuxOptions.Type,
|
||||
SELinuxOptionsLevel: pod.SecurityContext.SELinuxOptions.Level,
|
||||
},
|
||||
WindowsOptionsFields: WindowsOptionsFields{
|
||||
WindowsOptionsGMSACredentialSpecName: nil,
|
||||
WindowsOptionsGMSACredentialSpec: nil,
|
||||
WindowsOptionsRunAsUserName: nil,
|
||||
},
|
||||
SeccompProfileFields: SeccompProfileFields{
|
||||
SeccompProfileType: pod.SecurityContext.SeccompProfile.Type,
|
||||
SeccompProfileLocalhostProfile: pod.SecurityContext.SeccompProfile.LocalhostProfile,
|
||||
},
|
||||
RunAsUser: pod.SecurityContext.RunAsUser,
|
||||
RunAsGroup: pod.SecurityContext.RunAsGroup,
|
||||
RunAsNonRoot: pod.SecurityContext.RunAsNonRoot,
|
||||
},
|
||||
SupplementalGroups: pod.SecurityContext.SupplementalGroups,
|
||||
FSGroup: pod.SecurityContext.FSGroup,
|
||||
Sysctls: pod.SecurityContext.Sysctls,
|
||||
FSGroupChangePolicy: pod.SecurityContext.FSGroupChangePolicy,
|
||||
},
|
||||
DNSConfigFields: DNSConfigFields{
|
||||
DNSConfigNameservers: pod.DNSConfig.Nameservers,
|
||||
DNSConfigSearches: pod.DNSConfig.Searches,
|
||||
DNSConfigOptions: pod.DNSConfig.Options,
|
||||
},
|
||||
AffinityFields: AffinityFields{
|
||||
NodeAffinity: pod.Affinity.NodeAffinity,
|
||||
PodAffinity: pod.Affinity.PodAffinity,
|
||||
PodAntiAffinity: pod.Affinity.PodAntiAffinity,
|
||||
},
|
||||
NodeSelector: pod.NodeSelector,
|
||||
RestartPolicy: pod.RestartPolicy,
|
||||
TerminationGracePeriodSeconds: pod.TerminationGracePeriodSeconds,
|
||||
ActiveDeadlineSeconds: pod.ActiveDeadlineSeconds,
|
||||
DNSPolicy: pod.DNSPolicy,
|
||||
ServiceAccountName: pod.ServiceAccountName,
|
||||
AutomountServiceAccountToken: pod.AutomountServiceAccountToken,
|
||||
NodeName: pod.NodeName,
|
||||
HostNetwork: pod.HostNetwork,
|
||||
HostPID: pod.HostPID,
|
||||
HostIPC: pod.HostIPC,
|
||||
ShareProcessNamespace: pod.ShareProcessNamespace,
|
||||
ImagePullSecrets: pod.ImagePullSecrets,
|
||||
Hostname: pod.Hostname,
|
||||
Subdomain: pod.Subdomain,
|
||||
SchedulerName: pod.SchedulerName,
|
||||
Tolerations: pod.Tolerations,
|
||||
HostAliases: pod.HostAliases,
|
||||
PriorityClassName: pod.PriorityClassName,
|
||||
Priority: pod.Priority,
|
||||
ReadinessGates: pod.ReadinessGates,
|
||||
RuntimeClassName: pod.RuntimeClassName,
|
||||
EnableServiceLinks: pod.EnableServiceLinks,
|
||||
PreemptionPolicy: pod.PreemptionPolicy,
|
||||
Overhead: pod.Overhead,
|
||||
TopologySpreadConstraints: pod.TopologySpreadConstraints,
|
||||
SetHostnameAsFQDN: pod.SetHostnameAsFQDN,
|
||||
}, "Common pod fields should match")
|
||||
}
|
||||
|
||||
func TestGetCommonContainerFields(t *testing.T) {
|
||||
i64 := int64(456)
|
||||
b := bool(true)
|
||||
s := string("str123")
|
||||
c := v1.Container{
|
||||
Name: "n123",
|
||||
Image: "i123",
|
||||
Command: []string{"c123"},
|
||||
Args: []string{"a1", "a2"},
|
||||
WorkingDir: "w123",
|
||||
Ports: make([]v1.ContainerPort, 1),
|
||||
EnvFrom: []v1.EnvFromSource{{Prefix: "p123"}},
|
||||
Env: []v1.EnvVar{{Name: "n1", Value: "v1"}},
|
||||
Resources: v1.ResourceRequirements{Limits: v1.ResourceList{}},
|
||||
VolumeMounts: make([]v1.VolumeMount, 2),
|
||||
VolumeDevices: []v1.VolumeDevice{{Name: "vn1"}},
|
||||
LivenessProbe: &v1.Probe{Handler: v1.Handler{Exec: &v1.ExecAction{Command: []string{"curl"}}}},
|
||||
ReadinessProbe: &v1.Probe{},
|
||||
StartupProbe: nil,
|
||||
Lifecycle: &v1.Lifecycle{PostStart: &v1.Handler{Exec: &v1.ExecAction{Command: []string{"curl"}}}},
|
||||
TerminationMessagePath: "t123",
|
||||
TerminationMessagePolicy: v1.TerminationMessageFallbackToLogsOnError,
|
||||
ImagePullPolicy: v1.PullAlways,
|
||||
Stdin: true,
|
||||
StdinOnce: false,
|
||||
TTY: true,
|
||||
SecurityContext: &v1.SecurityContext{
|
||||
Capabilities: &v1.Capabilities{Add: []v1.Capability{"a"}, Drop: []v1.Capability{"b", "c"}},
|
||||
Privileged: &b,
|
||||
RunAsUser: &i64,
|
||||
RunAsGroup: nil,
|
||||
RunAsNonRoot: &b,
|
||||
ReadOnlyRootFilesystem: nil,
|
||||
AllowPrivilegeEscalation: &b,
|
||||
ProcMount: nil,
|
||||
SELinuxOptions: &v1.SELinuxOptions{
|
||||
User: "u123",
|
||||
Role: "r123",
|
||||
Type: "t123",
|
||||
Level: "",
|
||||
},
|
||||
SeccompProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileType("abc"),
|
||||
LocalhostProfile: &s,
|
||||
},
|
||||
WindowsOptions: nil,
|
||||
},
|
||||
}
|
||||
assert.Equal(t, GetCommonContainerFields(c), CommonContainerFields{
|
||||
SecurityContextFields: SecurityContextFields{
|
||||
CommonSecurityContextFields: CommonSecurityContextFields{
|
||||
SELinuxOptionsFields: SELinuxOptionsFields{
|
||||
SELinuxOptionsUser: c.SecurityContext.SELinuxOptions.User,
|
||||
SELinuxOptionsRole: c.SecurityContext.SELinuxOptions.Role,
|
||||
SELinuxOptionsType: c.SecurityContext.SELinuxOptions.Type,
|
||||
SELinuxOptionsLevel: c.SecurityContext.SELinuxOptions.Level,
|
||||
},
|
||||
WindowsOptionsFields: WindowsOptionsFields{
|
||||
WindowsOptionsGMSACredentialSpecName: nil,
|
||||
WindowsOptionsGMSACredentialSpec: nil,
|
||||
WindowsOptionsRunAsUserName: nil,
|
||||
},
|
||||
SeccompProfileFields: SeccompProfileFields{
|
||||
SeccompProfileType: c.SecurityContext.SeccompProfile.Type,
|
||||
SeccompProfileLocalhostProfile: c.SecurityContext.SeccompProfile.LocalhostProfile,
|
||||
},
|
||||
RunAsUser: c.SecurityContext.RunAsUser,
|
||||
RunAsGroup: c.SecurityContext.RunAsGroup,
|
||||
RunAsNonRoot: c.SecurityContext.RunAsNonRoot,
|
||||
},
|
||||
CapabilitiesAdd: c.SecurityContext.Capabilities.Add,
|
||||
CapabilitiesDrop: c.SecurityContext.Capabilities.Drop,
|
||||
Privileged: c.SecurityContext.Privileged,
|
||||
ReadOnlyRootFilesystem: c.SecurityContext.ReadOnlyRootFilesystem,
|
||||
AllowPrivilegeEscalation: c.SecurityContext.AllowPrivilegeEscalation,
|
||||
ProcMount: c.SecurityContext.ProcMount,
|
||||
},
|
||||
TargetContainerName: "",
|
||||
Image: c.Image,
|
||||
Command: c.Command,
|
||||
Args: c.Args,
|
||||
WorkingDir: c.WorkingDir,
|
||||
Ports: c.Ports,
|
||||
EnvFrom: c.EnvFrom,
|
||||
Env: c.Env,
|
||||
ResourceLimits: c.Resources.Limits,
|
||||
ResourceRequests: c.Resources.Requests,
|
||||
VolumeMounts: c.VolumeMounts,
|
||||
VolumeDevices: c.VolumeDevices,
|
||||
LivenessProbe: c.LivenessProbe,
|
||||
ReadinessProbe: c.ReadinessProbe,
|
||||
StartupProbe: c.StartupProbe,
|
||||
Lifecycle: c.Lifecycle,
|
||||
TerminationMessagePath: c.TerminationMessagePath,
|
||||
TerminationMessagePolicy: c.TerminationMessagePolicy,
|
||||
ImagePullPolicy: c.ImagePullPolicy,
|
||||
Stdin: c.Stdin,
|
||||
StdinOnce: c.StdinOnce,
|
||||
TTY: c.TTY,
|
||||
}, "Common container fields should match")
|
||||
}
|
||||
|
||||
func TestGetCommonEphemeralContainerFields(t *testing.T) {
|
||||
i64 := int64(456)
|
||||
b := bool(true)
|
||||
s := string("str123")
|
||||
c := v1.EphemeralContainer{
|
||||
TargetContainerName: "t123",
|
||||
EphemeralContainerCommon: v1.EphemeralContainerCommon{
|
||||
Name: "n123",
|
||||
Image: "i123",
|
||||
Command: []string{"c123"},
|
||||
Args: []string{"a1", "a2"},
|
||||
WorkingDir: "w123",
|
||||
Ports: make([]v1.ContainerPort, 1),
|
||||
EnvFrom: []v1.EnvFromSource{{Prefix: "p123"}},
|
||||
Env: []v1.EnvVar{{Name: "n1", Value: "v1"}},
|
||||
Resources: v1.ResourceRequirements{Limits: v1.ResourceList{}},
|
||||
VolumeMounts: make([]v1.VolumeMount, 2),
|
||||
VolumeDevices: []v1.VolumeDevice{{Name: "vn1"}},
|
||||
LivenessProbe: &v1.Probe{Handler: v1.Handler{Exec: &v1.ExecAction{Command: []string{"curl"}}}},
|
||||
ReadinessProbe: &v1.Probe{},
|
||||
StartupProbe: nil,
|
||||
Lifecycle: &v1.Lifecycle{PostStart: &v1.Handler{Exec: &v1.ExecAction{Command: []string{"curl"}}}},
|
||||
TerminationMessagePath: "t123",
|
||||
TerminationMessagePolicy: v1.TerminationMessageFallbackToLogsOnError,
|
||||
ImagePullPolicy: v1.PullAlways,
|
||||
Stdin: true,
|
||||
StdinOnce: false,
|
||||
TTY: true,
|
||||
SecurityContext: &v1.SecurityContext{
|
||||
Capabilities: &v1.Capabilities{Add: []v1.Capability{"a"}, Drop: []v1.Capability{"b", "c"}},
|
||||
Privileged: &b,
|
||||
RunAsUser: &i64,
|
||||
RunAsGroup: nil,
|
||||
RunAsNonRoot: &b,
|
||||
ReadOnlyRootFilesystem: nil,
|
||||
AllowPrivilegeEscalation: &b,
|
||||
ProcMount: nil,
|
||||
SELinuxOptions: &v1.SELinuxOptions{
|
||||
User: "u123",
|
||||
Role: "r123",
|
||||
Type: "t123",
|
||||
Level: "",
|
||||
},
|
||||
SeccompProfile: &v1.SeccompProfile{
|
||||
Type: v1.SeccompProfileType("abc"),
|
||||
LocalhostProfile: &s,
|
||||
},
|
||||
WindowsOptions: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, GetCommonEphemeralContainerFields(c), CommonContainerFields{
|
||||
SecurityContextFields: SecurityContextFields{
|
||||
CommonSecurityContextFields: CommonSecurityContextFields{
|
||||
SELinuxOptionsFields: SELinuxOptionsFields{
|
||||
SELinuxOptionsUser: c.SecurityContext.SELinuxOptions.User,
|
||||
SELinuxOptionsRole: c.SecurityContext.SELinuxOptions.Role,
|
||||
SELinuxOptionsType: c.SecurityContext.SELinuxOptions.Type,
|
||||
SELinuxOptionsLevel: c.SecurityContext.SELinuxOptions.Level,
|
||||
},
|
||||
WindowsOptionsFields: WindowsOptionsFields{
|
||||
WindowsOptionsGMSACredentialSpecName: nil,
|
||||
WindowsOptionsGMSACredentialSpec: nil,
|
||||
WindowsOptionsRunAsUserName: nil,
|
||||
},
|
||||
SeccompProfileFields: SeccompProfileFields{
|
||||
SeccompProfileType: c.SecurityContext.SeccompProfile.Type,
|
||||
SeccompProfileLocalhostProfile: c.SecurityContext.SeccompProfile.LocalhostProfile,
|
||||
},
|
||||
RunAsUser: c.SecurityContext.RunAsUser,
|
||||
RunAsGroup: c.SecurityContext.RunAsGroup,
|
||||
RunAsNonRoot: c.SecurityContext.RunAsNonRoot,
|
||||
},
|
||||
CapabilitiesAdd: c.SecurityContext.Capabilities.Add,
|
||||
CapabilitiesDrop: c.SecurityContext.Capabilities.Drop,
|
||||
Privileged: c.SecurityContext.Privileged,
|
||||
ReadOnlyRootFilesystem: c.SecurityContext.ReadOnlyRootFilesystem,
|
||||
AllowPrivilegeEscalation: c.SecurityContext.AllowPrivilegeEscalation,
|
||||
ProcMount: c.SecurityContext.ProcMount,
|
||||
},
|
||||
TargetContainerName: c.TargetContainerName,
|
||||
Image: c.Image,
|
||||
Command: c.Command,
|
||||
Args: c.Args,
|
||||
WorkingDir: c.WorkingDir,
|
||||
Ports: c.Ports,
|
||||
EnvFrom: c.EnvFrom,
|
||||
Env: c.Env,
|
||||
ResourceLimits: c.Resources.Limits,
|
||||
ResourceRequests: c.Resources.Requests,
|
||||
VolumeMounts: c.VolumeMounts,
|
||||
VolumeDevices: c.VolumeDevices,
|
||||
LivenessProbe: c.LivenessProbe,
|
||||
ReadinessProbe: c.ReadinessProbe,
|
||||
StartupProbe: c.StartupProbe,
|
||||
Lifecycle: c.Lifecycle,
|
||||
TerminationMessagePath: c.TerminationMessagePath,
|
||||
TerminationMessagePolicy: c.TerminationMessagePolicy,
|
||||
ImagePullPolicy: c.ImagePullPolicy,
|
||||
Stdin: c.Stdin,
|
||||
StdinOnce: c.StdinOnce,
|
||||
TTY: c.TTY,
|
||||
}, "Common ephemeral container fields should match")
|
||||
}
|
||||
|
||||
func TestGetCommonVolumeFields(t *testing.T) {
|
||||
v := v1.Volume{
|
||||
VolumeSource: v1.VolumeSource{
|
||||
HostPath: &v1.HostPathVolumeSource{
|
||||
Path: "p123",
|
||||
Type: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, GetCommonVolumeFields(v), CommonVolumeFields{
|
||||
VolumeType: "host_path",
|
||||
HostPathPath: v.HostPath.Path,
|
||||
HostPathType: v.HostPath.Type,
|
||||
}, "Common volume HostPath fields should match")
|
||||
|
||||
v = v1.Volume{
|
||||
VolumeSource: v1.VolumeSource{
|
||||
GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
|
||||
PDName: "p123",
|
||||
FSType: "gce",
|
||||
Partition: 123,
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, GetCommonVolumeFields(v), CommonVolumeFields{
|
||||
VolumeType: "gce_persistent_disk",
|
||||
FSType: &v.GCEPersistentDisk.FSType,
|
||||
ReadOnly: &v.GCEPersistentDisk.ReadOnly,
|
||||
GCEPersistentDiskPDName: v.GCEPersistentDisk.PDName,
|
||||
GCEPersistentDiskPartition: v.GCEPersistentDisk.Partition,
|
||||
}, "Common volume GCE fields should match")
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
type componentStatus struct {
|
||||
ClusterName string
|
||||
ClusterUID types.UID
|
||||
Name string
|
||||
v1.ComponentCondition
|
||||
}
|
||||
|
||||
// ComponentStatusColumns returns kubernetes component status fields as Osquery table columns.
|
||||
func ComponentStatusColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&componentStatus{})
|
||||
}
|
||||
|
||||
// ComponentStatusesGenerate generates the kubernetes config maps as Osquery table data.
|
||||
func ComponentStatusesGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
css, err := k8s.GetClient().CoreV1().ComponentStatuses().List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, cs := range css.Items {
|
||||
for _, cc := range cs.Conditions {
|
||||
item := &componentStatus{
|
||||
ClusterName: k8s.GetClusterName(),
|
||||
ClusterUID: k8s.GetClusterUID(),
|
||||
Name: cs.ObjectMeta.Name,
|
||||
ComponentCondition: cc,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if css.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = css.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestComponentStatusesGenerate(t *testing.T) {
|
||||
css, err := ComponentStatusesGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"name": "controller-manager",
|
||||
"message": "ok",
|
||||
"status": "True",
|
||||
"type": "Healthy",
|
||||
},
|
||||
{
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"name": "etcd-0",
|
||||
"message": "{\"health\":\"true\"}",
|
||||
"status": "True",
|
||||
"type": "Healthy",
|
||||
},
|
||||
{
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"name": "scheduler",
|
||||
"message": "ok",
|
||||
"status": "True",
|
||||
"type": "Healthy",
|
||||
},
|
||||
}, css)
|
||||
}
|
56
infrastructure/kubequery/internal/k8s/core/config_map.go
Normal file
56
infrastructure/kubequery/internal/k8s/core/config_map.go
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type configmap struct {
|
||||
k8s.CommonNamespacedFields
|
||||
Immutable *bool
|
||||
}
|
||||
|
||||
// ConfigMapColumns returns kubernetes config map fields as Osquery table columns.
|
||||
func ConfigMapColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&configmap{})
|
||||
}
|
||||
|
||||
// ConfigMapsGenerate generates the kubernetes config maps as Osquery table data.
|
||||
func ConfigMapsGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
configmaps, err := k8s.GetClient().CoreV1().ConfigMaps(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, c := range configmaps.Items {
|
||||
item := &configmap{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(c.ObjectMeta),
|
||||
Immutable: c.Immutable,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if configmaps.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = configmaps.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestConfigMapsGenerate(t *testing.T) {
|
||||
cms, err := ConfigMapsGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "1611191331",
|
||||
"name": "jaeger-operator-lock",
|
||||
"namespace": "default",
|
||||
"uid": "eec6944c-5c13-4e30-8326-1a82e1962e4d",
|
||||
},
|
||||
}, cms)
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type endpointSubset struct {
|
||||
k8s.CommonNamespacedFields
|
||||
v1.EndpointSubset
|
||||
}
|
||||
|
||||
// EndpointSubsetColumns returns kubernetes endpoint subset fields as Osquery table columns.
|
||||
func EndpointSubsetColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&endpointSubset{})
|
||||
}
|
||||
|
||||
// EndpointSubsetsGenerate generates the kubernetes endpoint subsets as Osquery table data.
|
||||
func EndpointSubsetsGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
endpoints, err := k8s.GetClient().CoreV1().Endpoints(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, e := range endpoints.Items {
|
||||
for _, s := range e.Subsets {
|
||||
item := &endpointSubset{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(e.ObjectMeta),
|
||||
EndpointSubset: s,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if endpoints.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = endpoints.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEndpointSubsetsGenerate(t *testing.T) {
|
||||
ess, err := EndpointSubsetsGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"addresses": "[{\"ip\":\"10.1.26.50\",\"nodeName\":\"seshu\",\"targetRef\":{\"kind\":\"Pod\",\"namespace\":\"default\",\"name\":\"jaeger-operator-5db4f9d996-pm7ld\",\"uid\":\"2271363b-ffc9-4f00-984c-e0a125ee2d7a\",\"resourceVersion\":\"451808\"}}]",
|
||||
"annotations": "{\"endpoints.kubernetes.io/last-change-trigger-time\":\"2021-01-20T20:08:52-05:00\"}",
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "1611191332",
|
||||
"labels": "{\"name\":\"jaeger-operator\"}",
|
||||
"name": "jaeger-operator",
|
||||
"namespace": "default",
|
||||
"ports": "[{\"name\":\"metrics\",\"port\":8383,\"protocol\":\"TCP\"}]",
|
||||
"uid": "013741da-d7a5-4a2d-8f4b-792ac6a40dd3",
|
||||
},
|
||||
}, ess)
|
||||
}
|
81
infrastructure/kubequery/internal/k8s/core/init_test.go
Normal file
81
infrastructure/kubequery/internal/k8s/core/init_test.go
Normal file
@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
|
||||
func loadTestResource(name string, v interface{}) {
|
||||
path := filepath.Join("testdata", name)
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
lr := &v1.LimitRange{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "lr1",
|
||||
Namespace: "n123",
|
||||
UID: types.UID("1234"),
|
||||
Labels: map[string]string{"a": "b"},
|
||||
},
|
||||
Spec: v1.LimitRangeSpec{
|
||||
Limits: []v1.LimitRangeItem{
|
||||
{
|
||||
Type: v1.LimitTypeContainer,
|
||||
Max: v1.ResourceList{v1.ResourceCPU: resource.MustParse("0")},
|
||||
Min: v1.ResourceList{v1.ResourceCPU: resource.MustParse("4")},
|
||||
Default: v1.ResourceList{v1.ResourceCPU: resource.MustParse("3")},
|
||||
DefaultRequest: v1.ResourceList{v1.ResourceCPU: resource.MustParse("2")},
|
||||
MaxLimitRequestRatio: v1.ResourceList{v1.ResourceCPU: resource.MustParse("1")},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
csl := &v1.ComponentStatusList{}
|
||||
loadTestResource("component_status_test.json", csl)
|
||||
cm := &v1.ConfigMap{}
|
||||
loadTestResource("config_map_test.json", cm)
|
||||
ep := &v1.Endpoints{}
|
||||
loadTestResource("endpoint_subset_test.json", ep)
|
||||
ns := &v1.NamespaceList{}
|
||||
loadTestResource("namespaces_test.json", ns)
|
||||
node := &v1.Node{}
|
||||
loadTestResource("node_test.json", node)
|
||||
pod := &v1.Pod{}
|
||||
loadTestResource("pod_test.json", pod)
|
||||
secret := &v1.Secret{}
|
||||
loadTestResource("secret_test.json", secret)
|
||||
sa := &v1.ServiceAccount{}
|
||||
loadTestResource("service_account_test.json", sa)
|
||||
services := &v1.Service{}
|
||||
loadTestResource("services_test.json", services)
|
||||
|
||||
k8s.SetClient(fake.NewSimpleClientset(lr, csl, cm, ep, ns, node, pod, secret, sa, services),
|
||||
types.UID("d7fd8e77-93de-4742-9037-5db9a01e966a"), "")
|
||||
}
|
59
infrastructure/kubequery/internal/k8s/core/limit_range.go
Normal file
59
infrastructure/kubequery/internal/k8s/core/limit_range.go
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type limitRange struct {
|
||||
k8s.CommonNamespacedFields
|
||||
v1.LimitRangeItem
|
||||
}
|
||||
|
||||
// LimitRangeColumns returns kubernetes limit range fields as Osquery table columns.
|
||||
func LimitRangeColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&limitRange{})
|
||||
}
|
||||
|
||||
// LimitRangesGenerate generates the kubernetes limit ranges as Osquery table data.
|
||||
func LimitRangesGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
ranges, err := k8s.GetClient().CoreV1().LimitRanges(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, r := range ranges.Items {
|
||||
for _, i := range r.Spec.Limits {
|
||||
item := &limitRange{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(r.ObjectMeta),
|
||||
LimitRangeItem: i,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if ranges.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = ranges.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestLimitRangesGenerate(t *testing.T) {
|
||||
js, err := LimitRangesGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "0",
|
||||
"default": "{\"cpu\":\"3\"}",
|
||||
"default_request": "{\"cpu\":\"2\"}",
|
||||
"labels": "{\"a\":\"b\"}",
|
||||
"max": "{\"cpu\":\"0\"}",
|
||||
"max_limit_request_ratio": "{\"cpu\":\"1\"}",
|
||||
"min": "{\"cpu\":\"4\"}",
|
||||
"name": "lr1",
|
||||
"namespace": "n123",
|
||||
"type": "Container",
|
||||
"uid": "1234",
|
||||
},
|
||||
}, js)
|
||||
}
|
57
infrastructure/kubequery/internal/k8s/core/namespace.go
Normal file
57
infrastructure/kubequery/internal/k8s/core/namespace.go
Normal file
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type namespace struct {
|
||||
k8s.CommonFields
|
||||
v1.NamespaceStatus
|
||||
}
|
||||
|
||||
// NamespaceColumns returns kubernetes namespace fields as Osquery table columns.
|
||||
func NamespaceColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&namespace{})
|
||||
}
|
||||
|
||||
// NamespacesGenerate generates the kubernetes namespaces as Osquery table data.
|
||||
func NamespacesGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
namespaces, err := k8s.GetClient().CoreV1().Namespaces().List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, n := range namespaces.Items {
|
||||
item := &namespace{
|
||||
CommonFields: k8s.GetCommonFields(n.ObjectMeta),
|
||||
NamespaceStatus: n.Status,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if namespaces.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = namespaces.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
78
infrastructure/kubequery/internal/k8s/core/namespace_test.go
Normal file
78
infrastructure/kubequery/internal/k8s/core/namespace_test.go
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNamespacesGenerate(t *testing.T) {
|
||||
nss, err := NamespacesGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "1610476216",
|
||||
"name": "default",
|
||||
"phase": "Active",
|
||||
"uid": "7b50dc9c-6149-4cac-a0d0-52bf0fa5356d",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"v1\\\",\\\"kind\\\":\\\"Namespace\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"ingress\\\"}}\\n\"}",
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "1611191047",
|
||||
"name": "ingress",
|
||||
"phase": "Active",
|
||||
"uid": "7653c4b9-3df2-493e-ae28-5e3a777f7e76",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"v1\\\",\\\"kind\\\":\\\"Namespace\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"labels\\\":{\\\"istio-injection\\\":\\\"disabled\\\"},\\\"name\\\":\\\"istio-system\\\"}}\\n\"}",
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "1611191143",
|
||||
"labels": "{\"istio-injection\":\"disabled\"}",
|
||||
"name": "istio-system",
|
||||
"phase": "Active",
|
||||
"uid": "7f931f07-f8d0-4198-bf16-e459914e1866",
|
||||
},
|
||||
{
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "1610476215",
|
||||
"name": "kube-node-lease",
|
||||
"phase": "Active",
|
||||
"uid": "a8f303fd-0074-475f-935a-122cf8b6d1ad",
|
||||
},
|
||||
{
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "1610476215",
|
||||
"name": "kube-public",
|
||||
"phase": "Active",
|
||||
"uid": "6c719dfa-3de8-477b-a650-8bf9e2f12ee0",
|
||||
},
|
||||
{
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "1610476215",
|
||||
"name": "kube-system",
|
||||
"phase": "Active",
|
||||
"uid": "ebca5546-b939-4765-bf3d-869ac644ea0f",
|
||||
},
|
||||
{
|
||||
"annotations": "{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"v1\\\",\\\"kind\\\":\\\"Namespace\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"monitoring\\\"}}\\n\"}",
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "1611191449",
|
||||
"name": "monitoring",
|
||||
"phase": "Active",
|
||||
"uid": "afb98a87-39bb-4c8f-b0dd-8ea3683ba745",
|
||||
},
|
||||
}, nss)
|
||||
}
|
59
infrastructure/kubequery/internal/k8s/core/node.go
Normal file
59
infrastructure/kubequery/internal/k8s/core/node.go
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type node struct {
|
||||
k8s.CommonFields
|
||||
v1.NodeSpec
|
||||
v1.NodeStatus
|
||||
}
|
||||
|
||||
// NodeColumns returns kubernetes node fields as Osquery table columns.
|
||||
func NodeColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&node{})
|
||||
}
|
||||
|
||||
// NodesGenerate generates the kubernetes nodes as Osquery table data.
|
||||
func NodesGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
nodes, err := k8s.GetClient().CoreV1().Nodes().List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, n := range nodes.Items {
|
||||
item := &node{
|
||||
CommonFields: k8s.GetCommonFields(n.ObjectMeta),
|
||||
NodeSpec: n.Spec,
|
||||
NodeStatus: n.Status,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if nodes.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = nodes.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
41
infrastructure/kubequery/internal/k8s/core/node_test.go
Normal file
41
infrastructure/kubequery/internal/k8s/core/node_test.go
Normal file
File diff suppressed because one or more lines are too long
330
infrastructure/kubequery/internal/k8s/core/persistent_volume.go
Normal file
330
infrastructure/kubequery/internal/k8s/core/persistent_volume.go
Normal file
@ -0,0 +1,330 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type persistentVolume struct {
|
||||
k8s.CommonFields
|
||||
|
||||
Capacity v1.ResourceList
|
||||
AccessModes []v1.PersistentVolumeAccessMode
|
||||
ClaimRef *v1.ObjectReference
|
||||
PersistentVolumeReclaimPolicy v1.PersistentVolumeReclaimPolicy
|
||||
StorageClassName string
|
||||
MountOptions []string
|
||||
VolumeMode *v1.PersistentVolumeMode
|
||||
NodeAffinity *v1.VolumeNodeAffinity
|
||||
|
||||
StatusPhase v1.PersistentVolumePhase
|
||||
StatusMessage string
|
||||
StatusReason string
|
||||
|
||||
VolumeType string
|
||||
FSType *string
|
||||
ReadOnly *bool
|
||||
SecretName string
|
||||
HostPathPath string
|
||||
HostPathType *v1.HostPathType
|
||||
GCEPersistentDiskPDName string
|
||||
GCEPersistentDiskPartition int32
|
||||
AWSElasticBlockStoreVolumeID string
|
||||
AWSElasticBlockStorePartition int32
|
||||
NFSServer string
|
||||
NFSPath string
|
||||
ISCSITargetPortal string
|
||||
ISCSIIqn string
|
||||
ISCSILun int32
|
||||
ISCSIInterface string
|
||||
ISCSIPortals []string
|
||||
ISCSIDiscoveryCHAPAuth bool
|
||||
ISCSISessionCHAPAuth bool
|
||||
ISCSIInitiatorName *string
|
||||
LocalPath string
|
||||
GlusterfsEndpointsName string
|
||||
GlusterfsPath string
|
||||
RBDCephMonitors []string
|
||||
RBDImage string
|
||||
RBDPool string
|
||||
RBDRadosUser string
|
||||
RBDKeyring string
|
||||
FlexVolumeDriver string
|
||||
FlexVolumeOptions map[string]string
|
||||
CinderVolumeID string
|
||||
CephFSMonitors []string
|
||||
CephFSPath string
|
||||
CephFSUser string
|
||||
CephFSSecretFile string
|
||||
FlockerDatasetName string
|
||||
FlockerDatasetUUID string
|
||||
FCTargetWWNs []string
|
||||
FCLun *int32
|
||||
FcWWIDs []string
|
||||
AzureFileShareName string
|
||||
VsphereVolumeVolumePath string
|
||||
VsphereVolumeStoragePolicyName string
|
||||
VsphereVolumeStoragePolicyID string
|
||||
QuobyteRegistry string
|
||||
QuobyteVolume string
|
||||
QuobyteUser string
|
||||
QuobyteGroup string
|
||||
QuobyteTenant string
|
||||
AzureDiskDiskName string
|
||||
AzureDiskDataDiskURI string
|
||||
AzureDiskCachingMode *v1.AzureDataDiskCachingMode
|
||||
AzureDiskKind *v1.AzureDataDiskKind
|
||||
PhotonPersistentDiskPdID string
|
||||
PortworxVolumeID string
|
||||
ScaleIOGateway string
|
||||
ScaleIOSystem string
|
||||
ScaleIOSSLEnabled bool
|
||||
ScaleIOProtectionDomain string
|
||||
ScaleIOStoragePool string
|
||||
ScaleIOStorageMode string
|
||||
ScaleIOVolumeName string
|
||||
StorageOSVolumeName string
|
||||
StorageOSVolumeNamespace string
|
||||
CSIDriver string
|
||||
CSIVolumeAttributes map[string]string
|
||||
}
|
||||
|
||||
// PersistentVolumeColumns returns kubernetes persistent volume fields as Osquery table columns.
|
||||
func PersistentVolumeColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&persistentVolume{})
|
||||
}
|
||||
|
||||
// PersistentVolumesGenerate generates the kubernetes persistent volumes as Osquery table data.
|
||||
func PersistentVolumesGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
pvs, err := k8s.GetClient().CoreV1().PersistentVolumes().List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, pv := range pvs.Items {
|
||||
item := &persistentVolume{
|
||||
CommonFields: k8s.GetCommonFields(pv.ObjectMeta),
|
||||
Capacity: pv.Spec.Capacity,
|
||||
AccessModes: pv.Spec.AccessModes,
|
||||
ClaimRef: pv.Spec.ClaimRef,
|
||||
PersistentVolumeReclaimPolicy: pv.Spec.PersistentVolumeReclaimPolicy,
|
||||
StorageClassName: pv.Spec.StorageClassName,
|
||||
MountOptions: pv.Spec.MountOptions,
|
||||
VolumeMode: pv.Spec.VolumeMode,
|
||||
NodeAffinity: pv.Spec.NodeAffinity,
|
||||
StatusPhase: pv.Status.Phase,
|
||||
StatusMessage: pv.Status.Message,
|
||||
StatusReason: pv.Status.Reason,
|
||||
}
|
||||
if pv.Spec.AWSElasticBlockStore != nil {
|
||||
item.VolumeType = "aws_elastic_block_store"
|
||||
item.AWSElasticBlockStoreVolumeID = pv.Spec.AWSElasticBlockStore.VolumeID
|
||||
item.AWSElasticBlockStorePartition = pv.Spec.AWSElasticBlockStore.Partition
|
||||
item.FSType = &pv.Spec.AWSElasticBlockStore.FSType
|
||||
item.ReadOnly = &pv.Spec.AWSElasticBlockStore.ReadOnly
|
||||
}
|
||||
if pv.Spec.AzureDisk != nil {
|
||||
item.VolumeType = "azure_disk"
|
||||
item.AzureDiskCachingMode = pv.Spec.AzureDisk.CachingMode
|
||||
item.AzureDiskDataDiskURI = pv.Spec.AzureDisk.DataDiskURI
|
||||
item.AzureDiskDiskName = pv.Spec.AzureDisk.DiskName
|
||||
item.AzureDiskKind = pv.Spec.AzureDisk.Kind
|
||||
item.FSType = pv.Spec.AzureDisk.FSType
|
||||
item.ReadOnly = pv.Spec.AzureDisk.ReadOnly
|
||||
}
|
||||
if pv.Spec.AzureFile != nil {
|
||||
item.VolumeType = "azure_file"
|
||||
item.AzureFileShareName = pv.Spec.AzureFile.ShareName
|
||||
item.SecretName = pv.Spec.AzureFile.SecretName
|
||||
item.ReadOnly = &pv.Spec.AzureFile.ReadOnly
|
||||
}
|
||||
if pv.Spec.CSI != nil {
|
||||
item.VolumeType = "csi"
|
||||
item.CSIDriver = pv.Spec.CSI.Driver
|
||||
item.CSIVolumeAttributes = pv.Spec.CSI.VolumeAttributes
|
||||
item.FSType = &pv.Spec.CSI.FSType
|
||||
item.ReadOnly = &pv.Spec.CSI.ReadOnly
|
||||
if pv.Spec.CSI.NodePublishSecretRef != nil {
|
||||
item.SecretName = pv.Spec.CSI.NodePublishSecretRef.Name
|
||||
}
|
||||
}
|
||||
if pv.Spec.CephFS != nil {
|
||||
item.VolumeType = "ceph_fs"
|
||||
item.CephFSMonitors = pv.Spec.CephFS.Monitors
|
||||
item.CephFSPath = pv.Spec.CephFS.Path
|
||||
item.CephFSSecretFile = pv.Spec.CephFS.SecretFile
|
||||
item.CephFSUser = pv.Spec.CephFS.User
|
||||
item.ReadOnly = &pv.Spec.CephFS.ReadOnly
|
||||
if pv.Spec.CephFS.SecretRef != nil {
|
||||
item.SecretName = pv.Spec.CephFS.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if pv.Spec.Cinder != nil {
|
||||
item.VolumeType = "cinder"
|
||||
item.CinderVolumeID = pv.Spec.Cinder.VolumeID
|
||||
item.FSType = &pv.Spec.Cinder.FSType
|
||||
item.ReadOnly = &pv.Spec.Cinder.ReadOnly
|
||||
if pv.Spec.Cinder.SecretRef != nil {
|
||||
item.SecretName = pv.Spec.Cinder.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if pv.Spec.FC != nil {
|
||||
item.VolumeType = "fc"
|
||||
item.FCLun = pv.Spec.FC.Lun
|
||||
item.FCTargetWWNs = pv.Spec.FC.TargetWWNs
|
||||
item.FcWWIDs = pv.Spec.FC.WWIDs
|
||||
item.FSType = &pv.Spec.FC.FSType
|
||||
item.ReadOnly = &pv.Spec.FC.ReadOnly
|
||||
}
|
||||
if pv.Spec.FlexVolume != nil {
|
||||
item.VolumeType = "flex_volume"
|
||||
item.FlexVolumeDriver = pv.Spec.FlexVolume.Driver
|
||||
item.FlexVolumeOptions = pv.Spec.FlexVolume.Options
|
||||
item.FSType = &pv.Spec.FlexVolume.FSType
|
||||
item.ReadOnly = &pv.Spec.FlexVolume.ReadOnly
|
||||
if pv.Spec.FlexVolume.SecretRef != nil {
|
||||
item.SecretName = pv.Spec.FlexVolume.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if pv.Spec.Flocker != nil {
|
||||
item.VolumeType = "flocker"
|
||||
item.FlockerDatasetName = pv.Spec.Flocker.DatasetName
|
||||
item.FlockerDatasetUUID = pv.Spec.Flocker.DatasetUUID
|
||||
}
|
||||
if pv.Spec.GCEPersistentDisk != nil {
|
||||
item.VolumeType = "gce_persistent_disk"
|
||||
item.GCEPersistentDiskPDName = pv.Spec.GCEPersistentDisk.PDName
|
||||
item.GCEPersistentDiskPartition = pv.Spec.GCEPersistentDisk.Partition
|
||||
item.FSType = &pv.Spec.GCEPersistentDisk.FSType
|
||||
item.ReadOnly = &pv.Spec.GCEPersistentDisk.ReadOnly
|
||||
}
|
||||
if pv.Spec.Glusterfs != nil {
|
||||
item.VolumeType = "gluster_fs"
|
||||
item.GlusterfsPath = pv.Spec.Glusterfs.Path
|
||||
item.GlusterfsEndpointsName = pv.Spec.Glusterfs.EndpointsName
|
||||
item.ReadOnly = &pv.Spec.Glusterfs.ReadOnly
|
||||
}
|
||||
if pv.Spec.HostPath != nil {
|
||||
item.VolumeType = "host_path"
|
||||
item.HostPathPath = pv.Spec.HostPath.Path
|
||||
item.HostPathType = pv.Spec.HostPath.Type
|
||||
}
|
||||
if pv.Spec.ISCSI != nil {
|
||||
item.VolumeType = "iscsci"
|
||||
item.ISCSITargetPortal = pv.Spec.ISCSI.TargetPortal
|
||||
item.ISCSIIqn = pv.Spec.ISCSI.IQN
|
||||
item.ISCSILun = pv.Spec.ISCSI.Lun
|
||||
item.ISCSIInterface = pv.Spec.ISCSI.ISCSIInterface
|
||||
item.ISCSIPortals = pv.Spec.ISCSI.Portals
|
||||
item.ISCSIDiscoveryCHAPAuth = pv.Spec.ISCSI.DiscoveryCHAPAuth
|
||||
item.ISCSISessionCHAPAuth = pv.Spec.ISCSI.SessionCHAPAuth
|
||||
item.ISCSIInitiatorName = pv.Spec.ISCSI.InitiatorName
|
||||
item.FSType = &pv.Spec.ISCSI.FSType
|
||||
item.ReadOnly = &pv.Spec.ISCSI.ReadOnly
|
||||
if pv.Spec.ISCSI.SecretRef != nil {
|
||||
item.SecretName = pv.Spec.ISCSI.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if pv.Spec.Local != nil {
|
||||
item.LocalPath = pv.Spec.Local.Path
|
||||
item.FSType = pv.Spec.Local.FSType
|
||||
}
|
||||
if pv.Spec.NFS != nil {
|
||||
item.VolumeType = "nfs"
|
||||
item.NFSPath = pv.Spec.NFS.Path
|
||||
item.NFSServer = pv.Spec.NFS.Server
|
||||
item.ReadOnly = &pv.Spec.NFS.ReadOnly
|
||||
}
|
||||
if pv.Spec.PhotonPersistentDisk != nil {
|
||||
item.VolumeType = "photon_persistent_disk"
|
||||
item.PhotonPersistentDiskPdID = pv.Spec.PhotonPersistentDisk.PdID
|
||||
item.FSType = &pv.Spec.PhotonPersistentDisk.FSType
|
||||
}
|
||||
if pv.Spec.PortworxVolume != nil {
|
||||
item.VolumeType = "portworx_volume"
|
||||
item.PortworxVolumeID = pv.Spec.PortworxVolume.VolumeID
|
||||
item.FSType = &pv.Spec.PortworxVolume.FSType
|
||||
item.ReadOnly = &pv.Spec.PortworxVolume.ReadOnly
|
||||
}
|
||||
if pv.Spec.Quobyte != nil {
|
||||
item.VolumeType = "quobyte"
|
||||
item.QuobyteGroup = pv.Spec.Quobyte.Group
|
||||
item.QuobyteRegistry = pv.Spec.Quobyte.Registry
|
||||
item.QuobyteTenant = pv.Spec.Quobyte.Tenant
|
||||
item.QuobyteUser = pv.Spec.Quobyte.User
|
||||
item.QuobyteVolume = pv.Spec.Quobyte.Volume
|
||||
item.ReadOnly = &pv.Spec.Quobyte.ReadOnly
|
||||
}
|
||||
if pv.Spec.RBD != nil {
|
||||
item.VolumeType = "rbd"
|
||||
item.RBDCephMonitors = pv.Spec.RBD.CephMonitors
|
||||
item.RBDImage = pv.Spec.RBD.RBDImage
|
||||
item.RBDPool = pv.Spec.RBD.RBDPool
|
||||
item.RBDRadosUser = pv.Spec.RBD.RadosUser
|
||||
item.RBDKeyring = pv.Spec.RBD.Keyring
|
||||
item.FSType = &pv.Spec.RBD.FSType
|
||||
item.ReadOnly = &pv.Spec.RBD.ReadOnly
|
||||
if pv.Spec.RBD.SecretRef != nil {
|
||||
item.SecretName = pv.Spec.RBD.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if pv.Spec.ScaleIO != nil {
|
||||
item.VolumeType = "scaleio"
|
||||
item.ScaleIOGateway = pv.Spec.ScaleIO.Gateway
|
||||
item.ScaleIOSystem = pv.Spec.ScaleIO.System
|
||||
item.ScaleIOSSLEnabled = pv.Spec.ScaleIO.SSLEnabled
|
||||
item.ScaleIOProtectionDomain = pv.Spec.ScaleIO.ProtectionDomain
|
||||
item.ScaleIOStoragePool = pv.Spec.ScaleIO.StoragePool
|
||||
item.ScaleIOStorageMode = pv.Spec.ScaleIO.StorageMode
|
||||
item.ScaleIOVolumeName = pv.Spec.ScaleIO.VolumeName
|
||||
item.FSType = &pv.Spec.ScaleIO.FSType
|
||||
item.ReadOnly = &pv.Spec.ScaleIO.ReadOnly
|
||||
if pv.Spec.ScaleIO.SecretRef != nil {
|
||||
item.SecretName = pv.Spec.ScaleIO.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if pv.Spec.StorageOS != nil {
|
||||
item.VolumeType = "storage_os"
|
||||
item.StorageOSVolumeName = pv.Spec.StorageOS.VolumeName
|
||||
item.StorageOSVolumeNamespace = pv.Spec.StorageOS.VolumeNamespace
|
||||
item.FSType = &pv.Spec.StorageOS.FSType
|
||||
item.ReadOnly = &pv.Spec.StorageOS.ReadOnly
|
||||
if pv.Spec.StorageOS.SecretRef != nil {
|
||||
item.SecretName = pv.Spec.StorageOS.SecretRef.Name
|
||||
}
|
||||
}
|
||||
if pv.Spec.VsphereVolume != nil {
|
||||
item.VolumeType = "vsphere_volume"
|
||||
item.VsphereVolumeStoragePolicyID = pv.Spec.VsphereVolume.StoragePolicyID
|
||||
item.VsphereVolumeStoragePolicyName = pv.Spec.VsphereVolume.StoragePolicyName
|
||||
item.VsphereVolumeVolumePath = pv.Spec.VsphereVolume.VolumePath
|
||||
item.FSType = &pv.Spec.VsphereVolume.FSType
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if pvs.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = pvs.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type persistentVolumeClaim struct {
|
||||
k8s.CommonFields
|
||||
v1.PersistentVolumeClaimSpec
|
||||
Phase v1.PersistentVolumeClaimPhase
|
||||
Capacity v1.ResourceList
|
||||
Conditions []v1.PersistentVolumeClaimCondition
|
||||
}
|
||||
|
||||
// PersistentVolumeClaimColumns returns kubernetes persistent volume claim fields as Osquery table columns.
|
||||
func PersistentVolumeClaimColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&persistentVolumeClaim{})
|
||||
}
|
||||
|
||||
// PersistentVolumeClaimsGenerate generates the kubernetes persistent volume claims as Osquery table data.
|
||||
func PersistentVolumeClaimsGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
pvcs, err := k8s.GetClient().CoreV1().PersistentVolumeClaims(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, pvc := range pvcs.Items {
|
||||
item := &persistentVolumeClaim{
|
||||
CommonFields: k8s.GetCommonFields(pvc.ObjectMeta),
|
||||
PersistentVolumeClaimSpec: pvc.Spec,
|
||||
Phase: pvc.Status.Phase,
|
||||
Capacity: pvc.Status.Capacity,
|
||||
Conditions: pvc.Status.Conditions,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if pvcs.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = pvcs.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
233
infrastructure/kubequery/internal/k8s/core/pod.go
Normal file
233
infrastructure/kubequery/internal/k8s/core/pod.go
Normal file
@ -0,0 +1,233 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type pod struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonPodFields
|
||||
v1.PodStatus
|
||||
}
|
||||
|
||||
// PodColumns returns kubernetes pod fields as Osquery table columns.
|
||||
func PodColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&pod{})
|
||||
}
|
||||
|
||||
// PodsGenerate generates the kubernetes pods as Osquery table data.
|
||||
func PodsGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
pods, err := k8s.GetClient().CoreV1().Pods(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, p := range pods.Items {
|
||||
item := &pod{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(p.ObjectMeta),
|
||||
CommonPodFields: k8s.GetCommonPodFields(p.Spec),
|
||||
PodStatus: p.Status,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if pods.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = pods.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type podContainer struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonContainerFields
|
||||
PodName string
|
||||
ContainerType string
|
||||
State v1.ContainerState
|
||||
LastTerminationState v1.ContainerState
|
||||
Ready bool
|
||||
RestartCount int32
|
||||
ImageRepo string
|
||||
ImageID string
|
||||
ContainerID string
|
||||
Started *bool
|
||||
}
|
||||
|
||||
// PodContainerColumns returns kubernetes pod container fields as Osquery table columns.
|
||||
func PodContainerColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&podContainer{})
|
||||
}
|
||||
|
||||
func getImageRepo(id string) string {
|
||||
// docker.io/jaegertracing/jaeger-operator@sha256:5a3198179f7972028a29dd7fbf71ac7a21e0dbf46c85e8cc2c37e3b6a5ee26a4
|
||||
index := strings.LastIndex(id, "@")
|
||||
if index < 0 || index == len(id)-1 {
|
||||
return ""
|
||||
}
|
||||
return id[0:index]
|
||||
}
|
||||
|
||||
func cleanID(id string) string {
|
||||
// containerd://4a8e3f149f24fb5d4429f4a38e86097e1aec3b6b174bb382a44c6706ad4406e1
|
||||
// docker.io/jaegertracing/jaeger-operator@sha256:5a3198179f7972028a29dd7fbf71ac7a21e0dbf46c85e8cc2c37e3b6a5ee26a4
|
||||
index := -1
|
||||
for _, s := range []string{"/", ":", "@"} {
|
||||
i := strings.LastIndex(id, s)
|
||||
if i > -1 && i > index {
|
||||
index = i
|
||||
}
|
||||
}
|
||||
|
||||
if index < 0 || index == len(id)-1 {
|
||||
return id
|
||||
}
|
||||
return id[index+1:]
|
||||
}
|
||||
|
||||
func updatePodContainerStatus(pc *podContainer, cs *v1.ContainerStatus) {
|
||||
if cs != nil {
|
||||
pc.State = cs.State
|
||||
pc.LastTerminationState = cs.LastTerminationState
|
||||
pc.Ready = cs.Ready
|
||||
pc.RestartCount = cs.RestartCount
|
||||
pc.ImageRepo = getImageRepo(cs.ImageID)
|
||||
pc.ImageID = cleanID(cs.ImageID)
|
||||
pc.ContainerID = cleanID(cs.ContainerID)
|
||||
pc.Started = cs.Started
|
||||
}
|
||||
}
|
||||
|
||||
func createPodContainer(p v1.Pod, c v1.Container, cs *v1.ContainerStatus, containerType string) *podContainer {
|
||||
item := &podContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(p.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonContainerFields(c),
|
||||
PodName: p.Name,
|
||||
ContainerType: containerType,
|
||||
}
|
||||
item.Name = c.Name
|
||||
updatePodContainerStatus(item, cs)
|
||||
return item
|
||||
}
|
||||
|
||||
func createPodEphemeralContainer(p v1.Pod, c v1.EphemeralContainer, cs *v1.ContainerStatus) *podContainer {
|
||||
item := &podContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(p.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonEphemeralContainerFields(c),
|
||||
PodName: p.Name,
|
||||
ContainerType: "ephemeral",
|
||||
}
|
||||
item.Name = c.Name
|
||||
updatePodContainerStatus(item, cs)
|
||||
return item
|
||||
}
|
||||
|
||||
// PodContainersGenerate generates the kubernetes pod containers as Osquery table data.
|
||||
func PodContainersGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
pods, err := k8s.GetClient().CoreV1().Pods(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, p := range pods.Items {
|
||||
for i, c := range p.Spec.InitContainers {
|
||||
var cs *v1.ContainerStatus = nil
|
||||
if len(p.Status.InitContainerStatuses) > i {
|
||||
cs = &p.Status.InitContainerStatuses[i]
|
||||
}
|
||||
item := createPodContainer(p, c, cs, "init")
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
for i, c := range p.Spec.Containers {
|
||||
var cs *v1.ContainerStatus = nil
|
||||
if len(p.Status.ContainerStatuses) > i {
|
||||
cs = &p.Status.ContainerStatuses[i]
|
||||
}
|
||||
item := createPodContainer(p, c, cs, "container")
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
for i, c := range p.Spec.EphemeralContainers {
|
||||
var cs *v1.ContainerStatus = nil
|
||||
if len(p.Status.EphemeralContainerStatuses) > i {
|
||||
cs = &p.Status.EphemeralContainerStatuses[i]
|
||||
}
|
||||
item := createPodEphemeralContainer(p, c, cs)
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if pods.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = pods.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type podVolume struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonVolumeFields
|
||||
PodName string
|
||||
}
|
||||
|
||||
// PodVolumeColumns returns kubernetes pod volume fields as Osquery table columns.
|
||||
func PodVolumeColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&podVolume{})
|
||||
}
|
||||
|
||||
// PodVolumesGenerate generates the kubernetes pod volumes as Osquery table data.
|
||||
func PodVolumesGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
pods, err := k8s.GetClient().CoreV1().Pods(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, p := range pods.Items {
|
||||
for _, v := range p.Spec.Volumes {
|
||||
item := &podVolume{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(p.ObjectMeta),
|
||||
CommonVolumeFields: k8s.GetCommonVolumeFields(v),
|
||||
PodName: p.Name,
|
||||
}
|
||||
item.Name = v.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if pods.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = pods.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
169
infrastructure/kubequery/internal/k8s/core/pod_template.go
Normal file
169
infrastructure/kubequery/internal/k8s/core/pod_template.go
Normal file
@ -0,0 +1,169 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type podTemplate struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonPodFields
|
||||
}
|
||||
|
||||
// PodTemplateColumns returns kubernetes pod template fields as Osquery table columns.
|
||||
func PodTemplateColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&podTemplate{})
|
||||
}
|
||||
|
||||
// PodTemplatesGenerate generates the kubernetes pod templates as Osquery table data.
|
||||
func PodTemplatesGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
pts, err := k8s.GetClient().CoreV1().PodTemplates(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, pt := range pts.Items {
|
||||
item := &podTemplate{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(pt.ObjectMeta),
|
||||
CommonPodFields: k8s.GetCommonPodFields(pt.Template.Spec),
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if pts.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = pts.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type podTemplateContainer struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonContainerFields
|
||||
PodTemplateName string
|
||||
ContainerType string
|
||||
}
|
||||
|
||||
// PodTemplateContainerColumns returns kubernetes pod template container fields as Osquery table columns.
|
||||
func PodTemplateContainerColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&podTemplateContainer{})
|
||||
}
|
||||
|
||||
func createPodTemplateContainer(pt v1.PodTemplate, c v1.Container, containerType string) *podTemplateContainer {
|
||||
item := &podTemplateContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(pt.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonContainerFields(c),
|
||||
PodTemplateName: pt.Name,
|
||||
ContainerType: containerType,
|
||||
}
|
||||
item.Name = c.Name
|
||||
return item
|
||||
}
|
||||
|
||||
func createPodTemplateEphemeralContainer(pt v1.PodTemplate, c v1.EphemeralContainer) *podTemplateContainer {
|
||||
item := &podTemplateContainer{
|
||||
CommonNamespacedFields: k8s.GetParentCommonNamespacedFields(pt.ObjectMeta, c.Name),
|
||||
CommonContainerFields: k8s.GetCommonEphemeralContainerFields(c),
|
||||
PodTemplateName: pt.Name,
|
||||
ContainerType: "ephemeral",
|
||||
}
|
||||
item.Name = c.Name
|
||||
return item
|
||||
}
|
||||
|
||||
// PodTemplateContainersGenerate generates the kubernetes pod template containers as Osquery table data.
|
||||
func PodTemplateContainersGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
pts, err := k8s.GetClient().CoreV1().PodTemplates(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, pt := range pts.Items {
|
||||
for _, c := range pt.Template.Spec.InitContainers {
|
||||
item := createPodTemplateContainer(pt, c, "init")
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
for _, c := range pt.Template.Spec.Containers {
|
||||
item := createPodTemplateContainer(pt, c, "container")
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
for _, c := range pt.Template.Spec.EphemeralContainers {
|
||||
item := createPodTemplateEphemeralContainer(pt, c)
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if pts.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = pts.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
type podTemplateVolume struct {
|
||||
k8s.CommonNamespacedFields
|
||||
k8s.CommonVolumeFields
|
||||
PodTemplateName string
|
||||
}
|
||||
|
||||
// PodTemplateVolumeColumns returns kubernetes pod template volume fields as Osquery table columns.
|
||||
func PodTemplateVolumeColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&podTemplateVolume{})
|
||||
}
|
||||
|
||||
// PodTemplateVolumesGenerate generates the kubernetes pod template volumes as Osquery table data.
|
||||
func PodTemplateVolumesGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
pts, err := k8s.GetClient().CoreV1().PodTemplates(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, pt := range pts.Items {
|
||||
for _, v := range pt.Template.Spec.Volumes {
|
||||
item := &podTemplateVolume{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(pt.ObjectMeta),
|
||||
CommonVolumeFields: k8s.GetCommonVolumeFields(v),
|
||||
PodTemplateName: pt.Name,
|
||||
}
|
||||
item.Name = v.Name
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
}
|
||||
|
||||
if pts.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = pts.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
118
infrastructure/kubequery/internal/k8s/core/pod_test.go
Normal file
118
infrastructure/kubequery/internal/k8s/core/pod_test.go
Normal file
@ -0,0 +1,118 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPodsGenerate(t *testing.T) {
|
||||
ps, err := PodsGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"annotations": "{\"cni.projectcalico.org/podIP\":\"10.1.26.50/32\",\"cni.projectcalico.org/podIPs\":\"10.1.26.50/32\"}",
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"conditions": "[{\"type\":\"Initialized\",\"status\":\"True\",\"lastProbeTime\":null,\"lastTransitionTime\":\"2021-01-21T01:08:25Z\"},{\"type\":\"Ready\",\"status\":\"True\",\"lastProbeTime\":null,\"lastTransitionTime\":\"2021-01-21T01:08:52Z\"},{\"type\":\"ContainersReady\",\"status\":\"True\",\"lastProbeTime\":null,\"lastTransitionTime\":\"2021-01-21T01:08:52Z\"},{\"type\":\"PodScheduled\",\"status\":\"True\",\"lastProbeTime\":null,\"lastTransitionTime\":\"2021-01-21T01:08:25Z\"}]",
|
||||
"container_statuses": "[{\"name\":\"jaeger-operator\",\"state\":{\"running\":{\"startedAt\":\"2021-01-21T01:08:51Z\"}},\"lastState\":{\"terminated\":{\"exitCode\":1,\"reason\":\"Error\",\"startedAt\":\"2021-01-21T01:08:36Z\",\"finishedAt\":\"2021-01-21T01:08:36Z\",\"containerID\":\"containerd://d4c9607e13f2bd2eec99f5261693557963a1380cfe6aceda23b9e3d3d195962f\"}},\"ready\":true,\"restartCount\":2,\"image\":\"docker.io/jaegertracing/jaeger-operator:1.14.0\",\"imageID\":\"docker.io/jaegertracing/jaeger-operator@sha256:5a3198179f7972028a29dd7fbf71ac7a21e0dbf46c85e8cc2c37e3b6a5ee26a4\",\"containerID\":\"containerd://4a8e3f149f24fb5d4429f4a38e86097e1aec3b6b174bb382a44c6706ad4406e1\",\"started\":true}]",
|
||||
"creation_timestamp": "1611191305",
|
||||
"dns_policy": "ClusterFirst",
|
||||
"enable_service_links": "1",
|
||||
"host_ip": "192.168.0.28",
|
||||
"host_ipc": "0",
|
||||
"host_network": "0",
|
||||
"host_pid": "0",
|
||||
"labels": "{\"name\":\"jaeger-operator\",\"pod-template-hash\":\"5db4f9d996\"}",
|
||||
"name": "jaeger-operator-5db4f9d996-pm7ld",
|
||||
"namespace": "default",
|
||||
"node_name": "seshu",
|
||||
"phase": "Running",
|
||||
"pod_ip": "10.1.26.50",
|
||||
"pod_ips": "[{\"ip\":\"10.1.26.50\"}]",
|
||||
"preemption_policy": "PreemptLowerPriority",
|
||||
"priority": "0",
|
||||
"qos_class": "BestEffort",
|
||||
"restart_policy": "Always",
|
||||
"scheduler_name": "default-scheduler",
|
||||
"service_account_name": "jaeger-operator",
|
||||
"start_time": "1611191305",
|
||||
"termination_grace_period_seconds": "30",
|
||||
"tolerations": "[{\"key\":\"node.kubernetes.io/not-ready\",\"operator\":\"Exists\",\"effect\":\"NoExecute\",\"tolerationSeconds\":300},{\"key\":\"node.kubernetes.io/unreachable\",\"operator\":\"Exists\",\"effect\":\"NoExecute\",\"tolerationSeconds\":300}]",
|
||||
"uid": "2271363b-ffc9-4f00-984c-e0a125ee2d7a",
|
||||
},
|
||||
}, ps)
|
||||
}
|
||||
|
||||
func TestPodContainersGenerate(t *testing.T) {
|
||||
pcs, err := PodContainersGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"annotations": "{\"cni.projectcalico.org/podIP\":\"10.1.26.50/32\",\"cni.projectcalico.org/podIPs\":\"10.1.26.50/32\"}",
|
||||
"args": "[\"start\"]",
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"container_id": "4a8e3f149f24fb5d4429f4a38e86097e1aec3b6b174bb382a44c6706ad4406e1",
|
||||
"container_type": "container",
|
||||
"creation_timestamp": "1611191305",
|
||||
"env": "[{\"name\":\"WATCH_NAMESPACE\"},{\"name\":\"POD_NAME\",\"valueFrom\":{\"fieldRef\":{\"apiVersion\":\"v1\",\"fieldPath\":\"metadata.name\"}}},{\"name\":\"POD_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"apiVersion\":\"v1\",\"fieldPath\":\"metadata.namespace\"}}},{\"name\":\"OPERATOR_NAME\",\"value\":\"jaeger-operator\"}]",
|
||||
"image": "jaegertracing/jaeger-operator:1.14.0",
|
||||
"image_repo": "docker.io/jaegertracing/jaeger-operator",
|
||||
"image_id": "5a3198179f7972028a29dd7fbf71ac7a21e0dbf46c85e8cc2c37e3b6a5ee26a4",
|
||||
"image_pull_policy": "Always",
|
||||
"labels": "{\"name\":\"jaeger-operator\",\"pod-template-hash\":\"5db4f9d996\"}",
|
||||
"last_termination_state": "{\"terminated\":{\"exitCode\":1,\"reason\":\"Error\",\"startedAt\":\"2021-01-21T01:08:36Z\",\"finishedAt\":\"2021-01-21T01:08:36Z\",\"containerID\":\"containerd://d4c9607e13f2bd2eec99f5261693557963a1380cfe6aceda23b9e3d3d195962f\"}}",
|
||||
"name": "jaeger-operator",
|
||||
"namespace": "default",
|
||||
"pod_name": "jaeger-operator-5db4f9d996-pm7ld",
|
||||
"ports": "[{\"name\":\"metrics\",\"containerPort\":8383,\"protocol\":\"TCP\"}]",
|
||||
"ready": "1",
|
||||
"restart_count": "2",
|
||||
"started": "1",
|
||||
"state": "{\"running\":{\"startedAt\":\"2021-01-21T01:08:51Z\"}}",
|
||||
"stdin": "0",
|
||||
"stdin_once": "0",
|
||||
"termination_message_path": "/dev/termination-log",
|
||||
"termination_message_policy": "File",
|
||||
"tty": "0",
|
||||
"uid": "2e7d1ce3-8546-5b73-beb8-46c109f37668",
|
||||
"volume_mounts": "[{\"name\":\"jaeger-operator-token-c94jx\",\"readOnly\":true,\"mountPath\":\"/var/run/secrets/kubernetes.io/serviceaccount\"}]",
|
||||
},
|
||||
}, pcs)
|
||||
}
|
||||
|
||||
func TestPodVolumesGenerate(t *testing.T) {
|
||||
pcs, err := PodVolumesGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"annotations": "{\"cni.projectcalico.org/podIP\":\"10.1.26.50/32\",\"cni.projectcalico.org/podIPs\":\"10.1.26.50/32\"}",
|
||||
"aws_elastic_block_store_partition": "0",
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "1611191305",
|
||||
"gce_persistent_disk_partition": "0",
|
||||
"iscsi_discovery_chap_auth": "0",
|
||||
"iscsi_lun": "0",
|
||||
"iscsi_session_chap_auth": "0",
|
||||
"labels": "{\"name\":\"jaeger-operator\",\"pod-template-hash\":\"5db4f9d996\"}",
|
||||
"name": "jaeger-operator-token-c94jx",
|
||||
"namespace": "default",
|
||||
"pod_name": "jaeger-operator-5db4f9d996-pm7ld",
|
||||
"scale_iossl_enabled": "0",
|
||||
"secret_default_mode": "420",
|
||||
"secret_name": "jaeger-operator-token-c94jx",
|
||||
"uid": "2271363b-ffc9-4f00-984c-e0a125ee2d7a",
|
||||
"volume_type": "secret",
|
||||
},
|
||||
}, pcs)
|
||||
}
|
61
infrastructure/kubequery/internal/k8s/core/resource_quota.go
Normal file
61
infrastructure/kubequery/internal/k8s/core/resource_quota.go
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type resourceQuota struct {
|
||||
k8s.CommonNamespacedFields
|
||||
v1.ResourceQuotaSpec
|
||||
StatusHard v1.ResourceList
|
||||
StatusUsed v1.ResourceList
|
||||
}
|
||||
|
||||
// ResourceQuotaColumns returns kubernetes resource quota fields as Osquery table columns.
|
||||
func ResourceQuotaColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&resourceQuota{})
|
||||
}
|
||||
|
||||
// ResourceQuotasGenerate generates the kubernetes resource quotas as Osquery table data.
|
||||
func ResourceQuotasGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
quotas, err := k8s.GetClient().CoreV1().ResourceQuotas(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, q := range quotas.Items {
|
||||
item := &resourceQuota{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(q.ObjectMeta),
|
||||
ResourceQuotaSpec: q.Spec,
|
||||
StatusHard: q.Status.Hard,
|
||||
StatusUsed: q.Status.Used,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if quotas.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = quotas.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
59
infrastructure/kubequery/internal/k8s/core/secret.go
Normal file
59
infrastructure/kubequery/internal/k8s/core/secret.go
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type secret struct {
|
||||
k8s.CommonNamespacedFields
|
||||
Immutable *bool
|
||||
Type v1.SecretType
|
||||
}
|
||||
|
||||
// SecretColumns returns kubernetes secret fields as Osquery table columns.
|
||||
func SecretColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&secret{})
|
||||
}
|
||||
|
||||
// SecretsGenerate generates the kubernetes secrets as Osquery table data.
|
||||
func SecretsGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
secrets, err := k8s.GetClient().CoreV1().Secrets(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, s := range secrets.Items {
|
||||
item := &secret{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(s.ObjectMeta),
|
||||
Immutable: s.Immutable,
|
||||
Type: s.Type,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if secrets.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = secrets.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
34
infrastructure/kubequery/internal/k8s/core/secret_test.go
Normal file
34
infrastructure/kubequery/internal/k8s/core/secret_test.go
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSecretsGenerate(t *testing.T) {
|
||||
ss, err := SecretsGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"annotations": "{\"istio.io/service-account.name\":\"jaeger-operator\"}",
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "1611191305",
|
||||
"name": "istio.jaeger-operator",
|
||||
"namespace": "default",
|
||||
"type": "istio.io/key-and-cert",
|
||||
"uid": "fb60f655-6b24-4f35-8e2d-17d7ca3ba7d4",
|
||||
},
|
||||
}, ss)
|
||||
}
|
59
infrastructure/kubequery/internal/k8s/core/service.go
Normal file
59
infrastructure/kubequery/internal/k8s/core/service.go
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type service struct {
|
||||
k8s.CommonNamespacedFields
|
||||
v1.ServiceSpec
|
||||
v1.ServiceStatus
|
||||
}
|
||||
|
||||
// ServiceColumns returns kubernetes service fields as Osquery table columns.
|
||||
func ServiceColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&service{})
|
||||
}
|
||||
|
||||
// ServicesGenerate generates the kubernetes services as Osquery table data.
|
||||
func ServicesGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
services, err := k8s.GetClient().CoreV1().Services(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, s := range services.Items {
|
||||
item := &service{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(s.ObjectMeta),
|
||||
ServiceSpec: s.Spec,
|
||||
ServiceStatus: s.Status,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if services.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = services.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/Uptycs/kubequery/internal/k8s"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type serviceAccount struct {
|
||||
k8s.CommonNamespacedFields
|
||||
Secrets []v1.ObjectReference
|
||||
ImagePullSecrets []v1.LocalObjectReference
|
||||
AutomountServiceAccountToken *bool
|
||||
}
|
||||
|
||||
// ServiceAccountColumns returns kubernetes service account fields as Osquery table columns.
|
||||
func ServiceAccountColumns() []table.ColumnDefinition {
|
||||
return k8s.GetSchema(&serviceAccount{})
|
||||
}
|
||||
|
||||
// ServiceAccountsGenerate generates the kubernetes service accounts as Osquery table data.
|
||||
func ServiceAccountsGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
|
||||
options := metav1.ListOptions{}
|
||||
results := make([]map[string]string, 0)
|
||||
|
||||
for {
|
||||
sas, err := k8s.GetClient().CoreV1().ServiceAccounts(metav1.NamespaceAll).List(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, sa := range sas.Items {
|
||||
item := &serviceAccount{
|
||||
CommonNamespacedFields: k8s.GetCommonNamespacedFields(sa.ObjectMeta),
|
||||
Secrets: sa.Secrets,
|
||||
ImagePullSecrets: sa.ImagePullSecrets,
|
||||
AutomountServiceAccountToken: sa.AutomountServiceAccountToken,
|
||||
}
|
||||
results = append(results, k8s.ToMap(item))
|
||||
}
|
||||
|
||||
if sas.Continue == "" {
|
||||
break
|
||||
}
|
||||
options.Continue = sas.Continue
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestServiceAccountsGenerate(t *testing.T) {
|
||||
sas, err := ServiceAccountsGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"annotations": "{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"v1\\\",\\\"kind\\\":\\\"ServiceAccount\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"labels\\\":{\\\"app\\\":\\\"istio-ingressgateway\\\",\\\"chart\\\":\\\"gateways\\\",\\\"heritage\\\":\\\"Tiller\\\",\\\"release\\\":\\\"istio\\\"},\\\"name\\\":\\\"istio-ingressgateway-service-account\\\",\\\"namespace\\\":\\\"istio-system\\\"}}\\n\"}",
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "1611191143",
|
||||
"labels": "{\"app\":\"istio-ingressgateway\",\"chart\":\"gateways\",\"heritage\":\"Tiller\",\"release\":\"istio\"}",
|
||||
"name": "istio-ingressgateway-service-account",
|
||||
"namespace": "istio-system",
|
||||
"secrets": "[{\"name\":\"istio-ingressgateway-service-account-token-zmk8b\"}]",
|
||||
"uid": "de09c78a-ea26-42ff-82d5-2f7d3f24a8d1",
|
||||
},
|
||||
}, sas)
|
||||
}
|
42
infrastructure/kubequery/internal/k8s/core/service_test.go
Normal file
42
infrastructure/kubequery/internal/k8s/core/service_test.go
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2020-present, The kubequery authors
|
||||
*
|
||||
* This source code is licensed as defined by the LICENSE file found in the
|
||||
* root directory of this source tree.
|
||||
*
|
||||
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Uptycs/basequery-go/plugin/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestServicesGenerate(t *testing.T) {
|
||||
ss, err := ServicesGenerate(context.TODO(), table.QueryContext{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []map[string]string{
|
||||
{
|
||||
"cluster_ip": "10.152.183.187",
|
||||
"cluster_ips": "[\"10.152.183.187\"]",
|
||||
"cluster_uid": "d7fd8e77-93de-4742-9037-5db9a01e966a",
|
||||
"creation_timestamp": "1611191332",
|
||||
"health_check_node_port": "0",
|
||||
"labels": "{\"name\":\"jaeger-operator\"}",
|
||||
"load_balancer": "{}",
|
||||
"name": "jaeger-operator",
|
||||
"namespace": "default",
|
||||
"ports": "[{\"name\":\"metrics\",\"protocol\":\"TCP\",\"port\":8383,\"targetPort\":8383}]",
|
||||
"publish_not_ready_addresses": "0",
|
||||
"selector": "{\"name\":\"jaeger-operator\"}",
|
||||
"session_affinity": "None",
|
||||
"type": "ClusterIP",
|
||||
"uid": "d8dfda88-e2c5-479e-bb2d-d0964805a925",
|
||||
},
|
||||
}, ss)
|
||||
}
|
58
infrastructure/kubequery/internal/k8s/core/testdata/component_status_test.json
vendored
Normal file
58
infrastructure/kubequery/internal/k8s/core/testdata/component_status_test.json
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"items": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"conditions": [
|
||||
{
|
||||
"message": "ok",
|
||||
"status": "True",
|
||||
"type": "Healthy"
|
||||
}
|
||||
],
|
||||
"kind": "ComponentStatus",
|
||||
"metadata": {
|
||||
"creationTimestamp": null,
|
||||
"name": "scheduler",
|
||||
"selfLink": "/api/v1/componentstatuses/scheduler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"conditions": [
|
||||
{
|
||||
"message": "ok",
|
||||
"status": "True",
|
||||
"type": "Healthy"
|
||||
}
|
||||
],
|
||||
"kind": "ComponentStatus",
|
||||
"metadata": {
|
||||
"creationTimestamp": null,
|
||||
"name": "controller-manager",
|
||||
"selfLink": "/api/v1/componentstatuses/controller-manager"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"conditions": [
|
||||
{
|
||||
"message": "{\"health\":\"true\"}",
|
||||
"status": "True",
|
||||
"type": "Healthy"
|
||||
}
|
||||
],
|
||||
"kind": "ComponentStatus",
|
||||
"metadata": {
|
||||
"creationTimestamp": null,
|
||||
"name": "etcd-0",
|
||||
"selfLink": "/api/v1/componentstatuses/etcd-0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "List",
|
||||
"metadata": {
|
||||
"resourceVersion": "",
|
||||
"selfLink": ""
|
||||
}
|
||||
}
|
43
infrastructure/kubequery/internal/k8s/core/testdata/config_map_test.json
vendored
Normal file
43
infrastructure/kubequery/internal/k8s/core/testdata/config_map_test.json
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
"metadata": {
|
||||
"creationTimestamp": "2021-01-21T01:08:51Z",
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:ownerReferences": {
|
||||
".": {},
|
||||
"k:{\"uid\":\"2271363b-ffc9-4f00-984c-e0a125ee2d7a\"}": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:kind": {},
|
||||
"f:name": {},
|
||||
"f:uid": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"manager": "jaeger-operator",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:08:51Z"
|
||||
}
|
||||
],
|
||||
"name": "jaeger-operator-lock",
|
||||
"namespace": "default",
|
||||
"ownerReferences": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"name": "jaeger-operator-5db4f9d996-pm7ld",
|
||||
"uid": "2271363b-ffc9-4f00-984c-e0a125ee2d7a"
|
||||
}
|
||||
],
|
||||
"resourceVersion": "451803",
|
||||
"selfLink": "/api/v1/namespaces/default/configmaps/jaeger-operator-lock",
|
||||
"uid": "eec6944c-5c13-4e30-8326-1a82e1962e4d"
|
||||
}
|
||||
}
|
64
infrastructure/kubequery/internal/k8s/core/testdata/endpoint_subset_test.json
vendored
Normal file
64
infrastructure/kubequery/internal/k8s/core/testdata/endpoint_subset_test.json
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Endpoints",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"endpoints.kubernetes.io/last-change-trigger-time": "2021-01-20T20:08:52-05:00"
|
||||
},
|
||||
"creationTimestamp": "2021-01-21T01:08:52Z",
|
||||
"labels": {
|
||||
"name": "jaeger-operator"
|
||||
},
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:endpoints.kubernetes.io/last-change-trigger-time": {}
|
||||
},
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:name": {}
|
||||
}
|
||||
},
|
||||
"f:subsets": {}
|
||||
},
|
||||
"manager": "kube-controller-manager",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:08:52Z"
|
||||
}
|
||||
],
|
||||
"name": "jaeger-operator",
|
||||
"namespace": "default",
|
||||
"resourceVersion": "451810",
|
||||
"selfLink": "/api/v1/namespaces/default/endpoints/jaeger-operator",
|
||||
"uid": "013741da-d7a5-4a2d-8f4b-792ac6a40dd3"
|
||||
},
|
||||
"subsets": [
|
||||
{
|
||||
"addresses": [
|
||||
{
|
||||
"ip": "10.1.26.50",
|
||||
"nodeName": "seshu",
|
||||
"targetRef": {
|
||||
"kind": "Pod",
|
||||
"name": "jaeger-operator-5db4f9d996-pm7ld",
|
||||
"namespace": "default",
|
||||
"resourceVersion": "451808",
|
||||
"uid": "2271363b-ffc9-4f00-984c-e0a125ee2d7a"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"name": "metrics",
|
||||
"port": 8383,
|
||||
"protocol": "TCP"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
275
infrastructure/kubequery/internal/k8s/core/testdata/namespaces_test.json
vendored
Normal file
275
infrastructure/kubequery/internal/k8s/core/testdata/namespaces_test.json
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"items": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Namespace",
|
||||
"metadata": {
|
||||
"creationTimestamp": "2021-01-12T18:30:15Z",
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:status": {
|
||||
"f:phase": {}
|
||||
}
|
||||
},
|
||||
"manager": "kube-apiserver",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-12T18:30:15Z"
|
||||
}
|
||||
],
|
||||
"name": "kube-system",
|
||||
"resourceVersion": "11",
|
||||
"selfLink": "/api/v1/namespaces/kube-system",
|
||||
"uid": "ebca5546-b939-4765-bf3d-869ac644ea0f"
|
||||
},
|
||||
"spec": {
|
||||
"finalizers": [
|
||||
"kubernetes"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"phase": "Active"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Namespace",
|
||||
"metadata": {
|
||||
"creationTimestamp": "2021-01-12T18:30:15Z",
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:status": {
|
||||
"f:phase": {}
|
||||
}
|
||||
},
|
||||
"manager": "kube-apiserver",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-12T18:30:15Z"
|
||||
}
|
||||
],
|
||||
"name": "kube-public",
|
||||
"resourceVersion": "32",
|
||||
"selfLink": "/api/v1/namespaces/kube-public",
|
||||
"uid": "6c719dfa-3de8-477b-a650-8bf9e2f12ee0"
|
||||
},
|
||||
"spec": {
|
||||
"finalizers": [
|
||||
"kubernetes"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"phase": "Active"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Namespace",
|
||||
"metadata": {
|
||||
"creationTimestamp": "2021-01-12T18:30:15Z",
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:status": {
|
||||
"f:phase": {}
|
||||
}
|
||||
},
|
||||
"manager": "kube-apiserver",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-12T18:30:15Z"
|
||||
}
|
||||
],
|
||||
"name": "kube-node-lease",
|
||||
"resourceVersion": "44",
|
||||
"selfLink": "/api/v1/namespaces/kube-node-lease",
|
||||
"uid": "a8f303fd-0074-475f-935a-122cf8b6d1ad"
|
||||
},
|
||||
"spec": {
|
||||
"finalizers": [
|
||||
"kubernetes"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"phase": "Active"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Namespace",
|
||||
"metadata": {
|
||||
"creationTimestamp": "2021-01-12T18:30:16Z",
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:status": {
|
||||
"f:phase": {}
|
||||
}
|
||||
},
|
||||
"manager": "kube-apiserver",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-12T18:30:16Z"
|
||||
}
|
||||
],
|
||||
"name": "default",
|
||||
"resourceVersion": "149",
|
||||
"selfLink": "/api/v1/namespaces/default",
|
||||
"uid": "7b50dc9c-6149-4cac-a0d0-52bf0fa5356d"
|
||||
},
|
||||
"spec": {
|
||||
"finalizers": [
|
||||
"kubernetes"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"phase": "Active"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Namespace",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"name\":\"ingress\"}}\n"
|
||||
},
|
||||
"creationTimestamp": "2021-01-21T01:04:07Z",
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:kubectl.kubernetes.io/last-applied-configuration": {}
|
||||
}
|
||||
},
|
||||
"f:status": {
|
||||
"f:phase": {}
|
||||
}
|
||||
},
|
||||
"manager": "kubectl-client-side-apply",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:04:07Z"
|
||||
}
|
||||
],
|
||||
"name": "ingress",
|
||||
"resourceVersion": "450124",
|
||||
"selfLink": "/api/v1/namespaces/ingress",
|
||||
"uid": "7653c4b9-3df2-493e-ae28-5e3a777f7e76"
|
||||
},
|
||||
"spec": {
|
||||
"finalizers": [
|
||||
"kubernetes"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"phase": "Active"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Namespace",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"labels\":{\"istio-injection\":\"disabled\"},\"name\":\"istio-system\"}}\n"
|
||||
},
|
||||
"creationTimestamp": "2021-01-21T01:05:43Z",
|
||||
"labels": {
|
||||
"istio-injection": "disabled"
|
||||
},
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:kubectl.kubernetes.io/last-applied-configuration": {}
|
||||
},
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:istio-injection": {}
|
||||
}
|
||||
},
|
||||
"f:status": {
|
||||
"f:phase": {}
|
||||
}
|
||||
},
|
||||
"manager": "kubectl-client-side-apply",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:05:43Z"
|
||||
}
|
||||
],
|
||||
"name": "istio-system",
|
||||
"resourceVersion": "450427",
|
||||
"selfLink": "/api/v1/namespaces/istio-system",
|
||||
"uid": "7f931f07-f8d0-4198-bf16-e459914e1866"
|
||||
},
|
||||
"spec": {
|
||||
"finalizers": [
|
||||
"kubernetes"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"phase": "Active"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Namespace",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"name\":\"monitoring\"}}\n"
|
||||
},
|
||||
"creationTimestamp": "2021-01-21T01:10:49Z",
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:kubectl.kubernetes.io/last-applied-configuration": {}
|
||||
}
|
||||
},
|
||||
"f:status": {
|
||||
"f:phase": {}
|
||||
}
|
||||
},
|
||||
"manager": "kubectl-client-side-apply",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:10:49Z"
|
||||
}
|
||||
],
|
||||
"name": "monitoring",
|
||||
"resourceVersion": "452095",
|
||||
"selfLink": "/api/v1/namespaces/monitoring",
|
||||
"uid": "afb98a87-39bb-4c8f-b0dd-8ea3683ba745"
|
||||
},
|
||||
"spec": {
|
||||
"finalizers": [
|
||||
"kubernetes"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"phase": "Active"
|
||||
}
|
||||
}
|
||||
],
|
||||
"kind": "List",
|
||||
"metadata": {
|
||||
"resourceVersion": "",
|
||||
"selfLink": ""
|
||||
}
|
||||
}
|
527
infrastructure/kubequery/internal/k8s/core/testdata/node_test.json
vendored
Normal file
527
infrastructure/kubequery/internal/k8s/core/testdata/node_test.json
vendored
Normal file
@ -0,0 +1,527 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Node",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"node.alpha.kubernetes.io/ttl": "0",
|
||||
"projectcalico.org/IPv4Address": "192.168.192.1/20",
|
||||
"projectcalico.org/IPv4VXLANTunnelAddr": "10.1.26.0",
|
||||
"volumes.kubernetes.io/controller-managed-attach-detach": "true"
|
||||
},
|
||||
"creationTimestamp": "2021-01-12T18:30:24Z",
|
||||
"labels": {
|
||||
"beta.kubernetes.io/arch": "amd64",
|
||||
"beta.kubernetes.io/os": "linux",
|
||||
"kubernetes.io/arch": "amd64",
|
||||
"kubernetes.io/hostname": "seshu",
|
||||
"kubernetes.io/os": "linux",
|
||||
"microk8s.io/cluster": "true"
|
||||
},
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
"f:projectcalico.org/IPv4Address": {},
|
||||
"f:projectcalico.org/IPv4VXLANTunnelAddr": {}
|
||||
}
|
||||
},
|
||||
"f:status": {
|
||||
"f:conditions": {
|
||||
"k:{\"type\":\"NetworkUnavailable\"}": {
|
||||
".": {},
|
||||
"f:lastHeartbeatTime": {},
|
||||
"f:lastTransitionTime": {},
|
||||
"f:message": {},
|
||||
"f:reason": {},
|
||||
"f:status": {},
|
||||
"f:type": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"manager": "calico-node",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-12T18:30:48Z"
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:volumes.kubernetes.io/controller-managed-attach-detach": {}
|
||||
},
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:beta.kubernetes.io/arch": {},
|
||||
"f:beta.kubernetes.io/os": {},
|
||||
"f:kubernetes.io/arch": {},
|
||||
"f:kubernetes.io/hostname": {},
|
||||
"f:kubernetes.io/os": {},
|
||||
"f:microk8s.io/cluster": {}
|
||||
}
|
||||
},
|
||||
"f:status": {
|
||||
"f:addresses": {
|
||||
".": {},
|
||||
"k:{\"type\":\"Hostname\"}": {
|
||||
".": {},
|
||||
"f:address": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"k:{\"type\":\"InternalIP\"}": {
|
||||
".": {},
|
||||
"f:address": {},
|
||||
"f:type": {}
|
||||
}
|
||||
},
|
||||
"f:allocatable": {
|
||||
".": {},
|
||||
"f:cpu": {},
|
||||
"f:ephemeral-storage": {},
|
||||
"f:hugepages-1Gi": {},
|
||||
"f:hugepages-2Mi": {},
|
||||
"f:memory": {},
|
||||
"f:pods": {}
|
||||
},
|
||||
"f:capacity": {
|
||||
".": {},
|
||||
"f:cpu": {},
|
||||
"f:ephemeral-storage": {},
|
||||
"f:hugepages-1Gi": {},
|
||||
"f:hugepages-2Mi": {},
|
||||
"f:memory": {},
|
||||
"f:pods": {}
|
||||
},
|
||||
"f:conditions": {
|
||||
".": {},
|
||||
"k:{\"type\":\"DiskPressure\"}": {
|
||||
".": {},
|
||||
"f:lastHeartbeatTime": {},
|
||||
"f:lastTransitionTime": {},
|
||||
"f:message": {},
|
||||
"f:reason": {},
|
||||
"f:status": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"k:{\"type\":\"MemoryPressure\"}": {
|
||||
".": {},
|
||||
"f:lastHeartbeatTime": {},
|
||||
"f:lastTransitionTime": {},
|
||||
"f:message": {},
|
||||
"f:reason": {},
|
||||
"f:status": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"k:{\"type\":\"PIDPressure\"}": {
|
||||
".": {},
|
||||
"f:lastHeartbeatTime": {},
|
||||
"f:lastTransitionTime": {},
|
||||
"f:message": {},
|
||||
"f:reason": {},
|
||||
"f:status": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"k:{\"type\":\"Ready\"}": {
|
||||
".": {},
|
||||
"f:lastHeartbeatTime": {},
|
||||
"f:lastTransitionTime": {},
|
||||
"f:message": {},
|
||||
"f:reason": {},
|
||||
"f:status": {},
|
||||
"f:type": {}
|
||||
}
|
||||
},
|
||||
"f:daemonEndpoints": {
|
||||
"f:kubeletEndpoint": {
|
||||
"f:Port": {}
|
||||
}
|
||||
},
|
||||
"f:images": {},
|
||||
"f:nodeInfo": {
|
||||
"f:architecture": {},
|
||||
"f:bootID": {},
|
||||
"f:containerRuntimeVersion": {},
|
||||
"f:kernelVersion": {},
|
||||
"f:kubeProxyVersion": {},
|
||||
"f:kubeletVersion": {},
|
||||
"f:machineID": {},
|
||||
"f:operatingSystem": {},
|
||||
"f:osImage": {},
|
||||
"f:systemUUID": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"manager": "kubelet",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-12T18:31:34Z"
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
"f:node.alpha.kubernetes.io/ttl": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"manager": "kube-controller-manager",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:10:50Z"
|
||||
}
|
||||
],
|
||||
"name": "seshu",
|
||||
"resourceVersion": "499998",
|
||||
"selfLink": "/api/v1/nodes/seshu",
|
||||
"uid": "d0d45111-421d-4d4f-89c9-3e75ca2dc06c"
|
||||
},
|
||||
"spec": {},
|
||||
"status": {
|
||||
"addresses": [
|
||||
{
|
||||
"address": "192.168.0.28",
|
||||
"type": "InternalIP"
|
||||
},
|
||||
{
|
||||
"address": "seshu",
|
||||
"type": "Hostname"
|
||||
}
|
||||
],
|
||||
"allocatable": {
|
||||
"cpu": "12",
|
||||
"ephemeral-storage": "958151776Ki",
|
||||
"hugepages-1Gi": "0",
|
||||
"hugepages-2Mi": "0",
|
||||
"memory": "32411744Ki",
|
||||
"pods": "110"
|
||||
},
|
||||
"capacity": {
|
||||
"cpu": "12",
|
||||
"ephemeral-storage": "959200352Ki",
|
||||
"hugepages-1Gi": "0",
|
||||
"hugepages-2Mi": "0",
|
||||
"memory": "32514144Ki",
|
||||
"pods": "110"
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"lastHeartbeatTime": "2021-01-20T16:31:53Z",
|
||||
"lastTransitionTime": "2021-01-20T16:31:53Z",
|
||||
"message": "Calico is running on this node",
|
||||
"reason": "CalicoIsUp",
|
||||
"status": "False",
|
||||
"type": "NetworkUnavailable"
|
||||
},
|
||||
{
|
||||
"lastHeartbeatTime": "2021-01-21T19:24:08Z",
|
||||
"lastTransitionTime": "2021-01-12T18:30:24Z",
|
||||
"message": "kubelet has sufficient memory available",
|
||||
"reason": "KubeletHasSufficientMemory",
|
||||
"status": "False",
|
||||
"type": "MemoryPressure"
|
||||
},
|
||||
{
|
||||
"lastHeartbeatTime": "2021-01-21T19:24:08Z",
|
||||
"lastTransitionTime": "2021-01-12T18:30:24Z",
|
||||
"message": "kubelet has no disk pressure",
|
||||
"reason": "KubeletHasNoDiskPressure",
|
||||
"status": "False",
|
||||
"type": "DiskPressure"
|
||||
},
|
||||
{
|
||||
"lastHeartbeatTime": "2021-01-21T19:24:08Z",
|
||||
"lastTransitionTime": "2021-01-12T18:30:24Z",
|
||||
"message": "kubelet has sufficient PID available",
|
||||
"reason": "KubeletHasSufficientPID",
|
||||
"status": "False",
|
||||
"type": "PIDPressure"
|
||||
},
|
||||
{
|
||||
"lastHeartbeatTime": "2021-01-21T19:24:08Z",
|
||||
"lastTransitionTime": "2021-01-21T01:12:31Z",
|
||||
"message": "kubelet is posting ready status. AppArmor enabled",
|
||||
"reason": "KubeletReady",
|
||||
"status": "True",
|
||||
"type": "Ready"
|
||||
}
|
||||
],
|
||||
"daemonEndpoints": {
|
||||
"kubeletEndpoint": {
|
||||
"Port": 10250
|
||||
}
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"names": [
|
||||
"docker.io/library/kubequery:latest"
|
||||
],
|
||||
"sizeBytes": 202523444
|
||||
},
|
||||
{
|
||||
"names": null,
|
||||
"sizeBytes": 174592418
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"k8s.gcr.io/ingress-nginx/controller@sha256:fc4979d8b8443a831c9789b5155cded454cb7de737a8b727bc2ba0106d2eae8b",
|
||||
"k8s.gcr.io/ingress-nginx/controller:v0.35.0"
|
||||
],
|
||||
"sizeBytes": 111763794
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/istio/proxyv2@sha256:3ad9ee2b43b299e5e6d97aaea5ed47dbf3da9293733607d9b52f358313e852ae",
|
||||
"docker.io/istio/proxyv2:1.5.1"
|
||||
],
|
||||
"sizeBytes": 106728139
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/jaegertracing/jaeger-operator@sha256:5a3198179f7972028a29dd7fbf71ac7a21e0dbf46c85e8cc2c37e3b6a5ee26a4",
|
||||
"docker.io/jaegertracing/jaeger-operator:1.14.0"
|
||||
],
|
||||
"sizeBytes": 99946252
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/calico/node@sha256:cb9dea7b86471c71925ae318f7c60af72d9ddf1dab0fe2029832a671b83bba6a",
|
||||
"docker.io/calico/node:v3.13.2"
|
||||
],
|
||||
"sizeBytes": 88917441
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/istio/mixer@sha256:92940f04e9aa20a41e330eb8a00a0b8ee7a3f4029dcdadfca4a5d009774474b2",
|
||||
"docker.io/istio/mixer:1.5.1"
|
||||
],
|
||||
"sizeBytes": 86988340
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/istio/pilot@sha256:818aecc1c73c53af9091ac1d4f500d9d7cec6d135d372d03cffab1addaff4ec0",
|
||||
"docker.io/istio/pilot:1.5.1"
|
||||
],
|
||||
"sizeBytes": 85950908
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/uptycs/kubequery@sha256:96b6c15753941f58e97fc6f80ee7ec06ce63d48a14b53ee0cc1dd10dc3585e7d",
|
||||
"docker.io/uptycs/kubequery:latest"
|
||||
],
|
||||
"sizeBytes": 82661645
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/istio/galley@sha256:d69acf890e5c82cb0c000fc15c540777ee566ae225762d85f157f69c9665338c",
|
||||
"docker.io/istio/galley:1.5.1"
|
||||
],
|
||||
"sizeBytes": 82020368
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/istio/sidecar_injector@sha256:cf334211f192378e7fcb66baeeb43412e483e34d739e93711d0a61568dd00462",
|
||||
"docker.io/istio/sidecar_injector:1.5.1"
|
||||
],
|
||||
"sizeBytes": 77988679
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/calico/cni@sha256:bbf7e3ac3f80d0a356a6c27b095bd313d1106f8ed84f85850816ed79295843c1",
|
||||
"docker.io/calico/cni:v3.13.2"
|
||||
],
|
||||
"sizeBytes": 76710099
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/istio/kubectl@sha256:83ea57063cf3344a2462c5bbaa5b125810f2e8ef7283d2ba3bfd9393e624b80f",
|
||||
"docker.io/istio/kubectl:1.5.1"
|
||||
],
|
||||
"sizeBytes": 76608582
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/grafana/grafana@sha256:bd55ea2bad17f5016431734b42fdfc202ebdc7d08b6c4ad35ebb03d06efdff69",
|
||||
"docker.io/grafana/grafana:6.4.3"
|
||||
],
|
||||
"sizeBytes": 76169588
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"quay.io/kiali/kiali:v1.9"
|
||||
],
|
||||
"sizeBytes": 75529164
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/istio/citadel@sha256:92b985411af9844b75c5fc9c39c33fc27ef549c31b5221358f334062aadb86ec",
|
||||
"docker.io/istio/citadel:1.5.1"
|
||||
],
|
||||
"sizeBytes": 72604439
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/kubernetesui/dashboard@sha256:06868692fb9a7f2ede1a06de1b7b32afabc40ec739c1181d83b5ed3eb147ec6e",
|
||||
"docker.io/kubernetesui/dashboard:v2.0.0"
|
||||
],
|
||||
"sizeBytes": 66209190
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/grafana/grafana@sha256:89304bc2335f4976618548d7b93d165ed67369d3a051d2f627fc4e0aa3d0aff1",
|
||||
"docker.io/grafana/grafana:7.1.0"
|
||||
],
|
||||
"sizeBytes": 59911815
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"quay.io/prometheus/prometheus@sha256:d4ba4dd1a9ebb90916d0bfed3c204adcb118ed24546bf8dd2e6b30fc0fd2009e",
|
||||
"quay.io/prometheus/prometheus:v2.20.0"
|
||||
],
|
||||
"sizeBytes": 59435495
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/prom/prometheus@sha256:cd93b8711bb92eb9c437d74217311519e0a93bc55779aa664325dc83cd13cb32",
|
||||
"docker.io/prom/prometheus:v2.12.0"
|
||||
],
|
||||
"sizeBytes": 54819393
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/calico/pod2daemon-flexvol@sha256:0022da5a9a89512f8a117f12d2088b3f1f8f22c094ee15aae24d58085f2c186a",
|
||||
"docker.io/calico/pod2daemon-flexvol:v3.13.2"
|
||||
],
|
||||
"sizeBytes": 37530211
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"quay.io/prometheus/alertmanager@sha256:24a5204b418e8fa0214cfb628486749003b039c279c56b5bddb5b10cd100d926",
|
||||
"quay.io/prometheus/alertmanager:v0.21.0"
|
||||
],
|
||||
"sizeBytes": 27097956
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/jaegertracing/all-in-one@sha256:738442983b772a5d413c8a2c44a5563956adaff224e5b38f52a959124dafc119",
|
||||
"docker.io/jaegertracing/all-in-one:1.16"
|
||||
],
|
||||
"sizeBytes": 23571671
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/directxman12/k8s-prometheus-adapter@sha256:44558d3ae98467e44fee72ebc3948ce59630996013a51d49cf925682a7b87c18",
|
||||
"docker.io/directxman12/k8s-prometheus-adapter:v0.7.0"
|
||||
],
|
||||
"sizeBytes": 23407634
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/jaegertracing/all-in-one@sha256:021aefafecbb5559078206996f1f4e8fc5907debab047f4fcc5c837689a66cfa",
|
||||
"docker.io/jaegertracing/all-in-one:1.14.0"
|
||||
],
|
||||
"sizeBytes": 23208939
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/calico/kube-controllers@sha256:a635173cbe9deb33deba9baadffd933f61c63fbdadc0e3fa60ff1a14198c1da8",
|
||||
"docker.io/calico/kube-controllers:v3.13.2"
|
||||
],
|
||||
"sizeBytes": 23132265
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"quay.io/brancz/kube-rbac-proxy@sha256:05e15e1164fd7ac85f5702b3f87ef548f4e00de3a79e6c4a6a34c92035497a9a",
|
||||
"quay.io/brancz/kube-rbac-proxy:v0.8.0"
|
||||
],
|
||||
"sizeBytes": 19991394
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/kubernetesui/metrics-scraper@sha256:555981a24f184420f3be0c79d4efb6c948a85cfce84034f85a563f4151a81cbf",
|
||||
"docker.io/kubernetesui/metrics-scraper:v1.0.4"
|
||||
],
|
||||
"sizeBytes": 16020077
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/coredns/coredns@sha256:41bee6992c2ed0f4628fcef75751048927bcd6b1cee89c79f6acb63ca5474d5a",
|
||||
"docker.io/coredns/coredns:1.6.6"
|
||||
],
|
||||
"sizeBytes": 12932169
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"quay.io/coreos/prometheus-operator@sha256:a54e806fb27d2fb0251da4f3b2a3bb5320759af63a54a755788304775f2384a7",
|
||||
"quay.io/coreos/prometheus-operator:v0.40.0"
|
||||
],
|
||||
"sizeBytes": 12496211
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"quay.io/prometheus/node-exporter@sha256:a2f29256e53cc3e0b64d7a472512600b2e9410347d53cdc85b49f659c17e02ee",
|
||||
"quay.io/prometheus/node-exporter:v0.18.1"
|
||||
],
|
||||
"sizeBytes": 11122661
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"gcr.io/k8s-staging-kube-state-metrics/kube-state-metrics@sha256:9718f2e7999e75f4993e312fccada801c0eb98eaba73db072f0f806d67fcc238",
|
||||
"gcr.io/k8s-staging-kube-state-metrics/kube-state-metrics:v1.9.7"
|
||||
],
|
||||
"sizeBytes": 10782953
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"k8s.gcr.io/metrics-server-amd64@sha256:c9c4e95068b51d6b33a9dccc61875df07dc650abbf4ac1a19d58b4628f89288b",
|
||||
"k8s.gcr.io/metrics-server-amd64:v0.3.6"
|
||||
],
|
||||
"sizeBytes": 10542830
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/cdkbot/hostpath-provisioner-amd64@sha256:339f78eabc68ffb1656d584e41f121cb4d2b667565428c8dde836caf5b8a0228",
|
||||
"docker.io/cdkbot/hostpath-provisioner-amd64:1.0.0"
|
||||
],
|
||||
"sizeBytes": 9745308
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"quay.io/coreos/prometheus-config-reloader@sha256:c679a143b24b7731ad1577a9865aa3805426cbf1b25e30807b951dff68466ffd",
|
||||
"quay.io/coreos/prometheus-config-reloader:v0.40.0"
|
||||
],
|
||||
"sizeBytes": 4254190
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"docker.io/jimmidyson/configmap-reload@sha256:d107c7a235c266273b1c3502a391fec374430e5625539403d0de797fa9c556a2",
|
||||
"docker.io/jimmidyson/configmap-reload:v0.3.0"
|
||||
],
|
||||
"sizeBytes": 4063371
|
||||
},
|
||||
{
|
||||
"names": [
|
||||
"k8s.gcr.io/pause@sha256:f78411e19d84a252e53bff71a4407a5686c46983a2c2eeed83929b888179acea",
|
||||
"k8s.gcr.io/pause:3.1"
|
||||
],
|
||||
"sizeBytes": 317164
|
||||
}
|
||||
],
|
||||
"nodeInfo": {
|
||||
"architecture": "amd64",
|
||||
"bootID": "0b51cb6f-120b-4557-b74a-e53a5f4f00d5",
|
||||
"containerRuntimeVersion": "containerd://1.3.7",
|
||||
"kernelVersion": "5.4.0-60-generic",
|
||||
"kubeProxyVersion": "v1.20.1-34+e7db93d188d0d1",
|
||||
"kubeletVersion": "v1.20.1-34+e7db93d188d0d1",
|
||||
"machineID": "c73ef4a4ef2a4ec19a75719b63db3bb7",
|
||||
"operatingSystem": "linux",
|
||||
"osImage": "Ubuntu 20.04.1 LTS",
|
||||
"systemUUID": "4c4c4544-0044-3510-8058-c6c04f5a5932"
|
||||
}
|
||||
}
|
||||
}
|
344
infrastructure/kubequery/internal/k8s/core/testdata/pod_test.json
vendored
Normal file
344
infrastructure/kubequery/internal/k8s/core/testdata/pod_test.json
vendored
Normal file
@ -0,0 +1,344 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"cni.projectcalico.org/podIP": "10.1.26.50/32",
|
||||
"cni.projectcalico.org/podIPs": "10.1.26.50/32"
|
||||
},
|
||||
"creationTimestamp": "2021-01-21T01:08:25Z",
|
||||
"generateName": "jaeger-operator-5db4f9d996-",
|
||||
"labels": {
|
||||
"name": "jaeger-operator",
|
||||
"pod-template-hash": "5db4f9d996"
|
||||
},
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:generateName": {},
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:pod-template-hash": {}
|
||||
},
|
||||
"f:ownerReferences": {
|
||||
".": {},
|
||||
"k:{\"uid\":\"2efeb411-ff99-434b-a5a2-4e06c2b0afaa\"}": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:blockOwnerDeletion": {},
|
||||
"f:controller": {},
|
||||
"f:kind": {},
|
||||
"f:name": {},
|
||||
"f:uid": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:spec": {
|
||||
"f:containers": {
|
||||
"k:{\"name\":\"jaeger-operator\"}": {
|
||||
".": {},
|
||||
"f:args": {},
|
||||
"f:env": {
|
||||
".": {},
|
||||
"k:{\"name\":\"OPERATOR_NAME\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:value": {}
|
||||
},
|
||||
"k:{\"name\":\"POD_NAME\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:fieldRef": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:fieldPath": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"POD_NAMESPACE\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:valueFrom": {
|
||||
".": {},
|
||||
"f:fieldRef": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:fieldPath": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"k:{\"name\":\"WATCH_NAMESPACE\"}": {
|
||||
".": {},
|
||||
"f:name": {}
|
||||
}
|
||||
},
|
||||
"f:image": {},
|
||||
"f:imagePullPolicy": {},
|
||||
"f:name": {},
|
||||
"f:ports": {
|
||||
".": {},
|
||||
"k:{\"containerPort\":8383,\"protocol\":\"TCP\"}": {
|
||||
".": {},
|
||||
"f:containerPort": {},
|
||||
"f:name": {},
|
||||
"f:protocol": {}
|
||||
}
|
||||
},
|
||||
"f:resources": {},
|
||||
"f:terminationMessagePath": {},
|
||||
"f:terminationMessagePolicy": {}
|
||||
}
|
||||
},
|
||||
"f:dnsPolicy": {},
|
||||
"f:enableServiceLinks": {},
|
||||
"f:restartPolicy": {},
|
||||
"f:schedulerName": {},
|
||||
"f:securityContext": {},
|
||||
"f:serviceAccount": {},
|
||||
"f:serviceAccountName": {},
|
||||
"f:terminationGracePeriodSeconds": {}
|
||||
}
|
||||
},
|
||||
"manager": "kube-controller-manager",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:08:25Z"
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:cni.projectcalico.org/podIP": {},
|
||||
"f:cni.projectcalico.org/podIPs": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"manager": "calico",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:08:26Z"
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:status": {
|
||||
"f:conditions": {
|
||||
"k:{\"type\":\"ContainersReady\"}": {
|
||||
".": {},
|
||||
"f:lastProbeTime": {},
|
||||
"f:lastTransitionTime": {},
|
||||
"f:status": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"k:{\"type\":\"Initialized\"}": {
|
||||
".": {},
|
||||
"f:lastProbeTime": {},
|
||||
"f:lastTransitionTime": {},
|
||||
"f:status": {},
|
||||
"f:type": {}
|
||||
},
|
||||
"k:{\"type\":\"Ready\"}": {
|
||||
".": {},
|
||||
"f:lastProbeTime": {},
|
||||
"f:lastTransitionTime": {},
|
||||
"f:status": {},
|
||||
"f:type": {}
|
||||
}
|
||||
},
|
||||
"f:containerStatuses": {},
|
||||
"f:hostIP": {},
|
||||
"f:phase": {},
|
||||
"f:podIP": {},
|
||||
"f:podIPs": {
|
||||
".": {},
|
||||
"k:{\"ip\":\"10.1.26.50\"}": {
|
||||
".": {},
|
||||
"f:ip": {}
|
||||
}
|
||||
},
|
||||
"f:startTime": {}
|
||||
}
|
||||
},
|
||||
"manager": "kubelet",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:08:52Z"
|
||||
}
|
||||
],
|
||||
"name": "jaeger-operator-5db4f9d996-pm7ld",
|
||||
"namespace": "default",
|
||||
"ownerReferences": [
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"blockOwnerDeletion": true,
|
||||
"controller": true,
|
||||
"kind": "ReplicaSet",
|
||||
"name": "jaeger-operator-5db4f9d996",
|
||||
"uid": "2efeb411-ff99-434b-a5a2-4e06c2b0afaa"
|
||||
}
|
||||
],
|
||||
"resourceVersion": "451808",
|
||||
"selfLink": "/api/v1/namespaces/default/pods/jaeger-operator-5db4f9d996-pm7ld",
|
||||
"uid": "2271363b-ffc9-4f00-984c-e0a125ee2d7a"
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"args": [
|
||||
"start"
|
||||
],
|
||||
"env": [
|
||||
{
|
||||
"name": "WATCH_NAMESPACE"
|
||||
},
|
||||
{
|
||||
"name": "POD_NAME",
|
||||
"valueFrom": {
|
||||
"fieldRef": {
|
||||
"apiVersion": "v1",
|
||||
"fieldPath": "metadata.name"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "POD_NAMESPACE",
|
||||
"valueFrom": {
|
||||
"fieldRef": {
|
||||
"apiVersion": "v1",
|
||||
"fieldPath": "metadata.namespace"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OPERATOR_NAME",
|
||||
"value": "jaeger-operator"
|
||||
}
|
||||
],
|
||||
"image": "jaegertracing/jaeger-operator:1.14.0",
|
||||
"imagePullPolicy": "Always",
|
||||
"name": "jaeger-operator",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 8383,
|
||||
"name": "metrics",
|
||||
"protocol": "TCP"
|
||||
}
|
||||
],
|
||||
"resources": {},
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"terminationMessagePolicy": "File",
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
|
||||
"name": "jaeger-operator-token-c94jx",
|
||||
"readOnly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"dnsPolicy": "ClusterFirst",
|
||||
"enableServiceLinks": true,
|
||||
"nodeName": "seshu",
|
||||
"preemptionPolicy": "PreemptLowerPriority",
|
||||
"priority": 0,
|
||||
"restartPolicy": "Always",
|
||||
"schedulerName": "default-scheduler",
|
||||
"securityContext": {},
|
||||
"serviceAccount": "jaeger-operator",
|
||||
"serviceAccountName": "jaeger-operator",
|
||||
"terminationGracePeriodSeconds": 30,
|
||||
"tolerations": [
|
||||
{
|
||||
"effect": "NoExecute",
|
||||
"key": "node.kubernetes.io/not-ready",
|
||||
"operator": "Exists",
|
||||
"tolerationSeconds": 300
|
||||
},
|
||||
{
|
||||
"effect": "NoExecute",
|
||||
"key": "node.kubernetes.io/unreachable",
|
||||
"operator": "Exists",
|
||||
"tolerationSeconds": 300
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"name": "jaeger-operator-token-c94jx",
|
||||
"secret": {
|
||||
"defaultMode": 420,
|
||||
"secretName": "jaeger-operator-token-c94jx"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"conditions": [
|
||||
{
|
||||
"lastProbeTime": null,
|
||||
"lastTransitionTime": "2021-01-21T01:08:25Z",
|
||||
"status": "True",
|
||||
"type": "Initialized"
|
||||
},
|
||||
{
|
||||
"lastProbeTime": null,
|
||||
"lastTransitionTime": "2021-01-21T01:08:52Z",
|
||||
"status": "True",
|
||||
"type": "Ready"
|
||||
},
|
||||
{
|
||||
"lastProbeTime": null,
|
||||
"lastTransitionTime": "2021-01-21T01:08:52Z",
|
||||
"status": "True",
|
||||
"type": "ContainersReady"
|
||||
},
|
||||
{
|
||||
"lastProbeTime": null,
|
||||
"lastTransitionTime": "2021-01-21T01:08:25Z",
|
||||
"status": "True",
|
||||
"type": "PodScheduled"
|
||||
}
|
||||
],
|
||||
"containerStatuses": [
|
||||
{
|
||||
"containerID": "containerd://4a8e3f149f24fb5d4429f4a38e86097e1aec3b6b174bb382a44c6706ad4406e1",
|
||||
"image": "docker.io/jaegertracing/jaeger-operator:1.14.0",
|
||||
"imageID": "docker.io/jaegertracing/jaeger-operator@sha256:5a3198179f7972028a29dd7fbf71ac7a21e0dbf46c85e8cc2c37e3b6a5ee26a4",
|
||||
"lastState": {
|
||||
"terminated": {
|
||||
"containerID": "containerd://d4c9607e13f2bd2eec99f5261693557963a1380cfe6aceda23b9e3d3d195962f",
|
||||
"exitCode": 1,
|
||||
"finishedAt": "2021-01-21T01:08:36Z",
|
||||
"reason": "Error",
|
||||
"startedAt": "2021-01-21T01:08:36Z"
|
||||
}
|
||||
},
|
||||
"name": "jaeger-operator",
|
||||
"ready": true,
|
||||
"restartCount": 2,
|
||||
"started": true,
|
||||
"state": {
|
||||
"running": {
|
||||
"startedAt": "2021-01-21T01:08:51Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"hostIP": "192.168.0.28",
|
||||
"phase": "Running",
|
||||
"podIP": "10.1.26.50",
|
||||
"podIPs": [
|
||||
{
|
||||
"ip": "10.1.26.50"
|
||||
}
|
||||
],
|
||||
"qosClass": "BestEffort",
|
||||
"startTime": "2021-01-21T01:08:25Z"
|
||||
}
|
||||
}
|
44
infrastructure/kubequery/internal/k8s/core/testdata/secret_test.json
vendored
Normal file
44
infrastructure/kubequery/internal/k8s/core/testdata/secret_test.json
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"data": {
|
||||
"cert-chain.pem": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lRSzZFK3FQVGpGRjM5TVRaU2FYSU1HekFOQmdrcWhraUc5dzBCQVFzRkFEQVkKTVJZd0ZBWURWUVFLRXcxamJIVnpkR1Z5TG14dlkyRnNNQjRYRFRJeE1ERXlNVEF4TURneU5Wb1hEVEl4TURReQpNVEF4TURneU5Wb3dBRENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFPWkZqazZWCkgxY1RoM1ZEdGowZy9rMWticnJadzQ3NHN1SkduSlJFVDArK1FBa1BDdE1sRzJOYVNENTByQWNFdTBBSlZzaXAKTmM0NTZkRlVzdk1IYVErQWhZYURQTDdHa3c2eDRyVVBRQkQwa3lYQUhjenUrY3FhZklXdGcrTGZibDhYYVZHTQpQMk5HVEJ1aEhtQVV0V0VORVB4NW1jaUlVOWpDZXQ0Szh0ZDFZQ2FtS1hSak1ldFBrR3ZrRDBGdGQ0WTVNSVNyCnNyNjdVdE9rWmgvTEpEWnFJVlBqa0JWdEJnQXdZNGdFRTV5SUdna3lNaVlreE9xL1JMOGxQejN2WVA5ci85aEMKQUtWVTJTSGxrNGFMa3VmVzJWaTdzSTJpRnZIYzgxeVJ6VE5UYkVFWkY2MUxFQm1MNzVIamdTbVN5R0poZTBQcwpzYWJQTzk2RDJOTkFNbjhDQXdFQUFhT0JoRENCZ1RBT0JnTlZIUThCQWY4RUJBTUNCYUF3SFFZRFZSMGxCQll3CkZBWUlLd1lCQlFVSEF3RUdDQ3NHQVFVRkJ3TUNNQXdHQTFVZEV3RUIvd1FDTUFBd1FnWURWUjBSQVFIL0JEZ3cKTm9ZMGMzQnBabVpsT2k4dlkyeDFjM1JsY2k1c2IyTmhiQzl1Y3k5a1pXWmhkV3gwTDNOaEwycGhaV2RsY2kxdgpjR1Z5WVhSdmNqQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFDYXFzY09QNXJnMm96ZmlpckdEWmx2dUFWOFZJCmR6ZUxEaTlMMHpLVjBxLy9TQW5SUEl5bWk0ampDYkRkbmYvYnpWWEdnZVNUNTNTeUR4Z3ZXVkQ2akZzK0JwTlcKcXFFWWE0NWdLUEFreUVpaVJJbW0vRFBQSzk4T2FKbGROK2xpVDllU1o1SUFocCtvVml5WnVwZURTR3cvTXdIdwphQ3dPbjYwSDdrUEU3cTY3NlZLU2tXd1BtdWpQU0xqeE5UWXhQVklPblZsVmo4REZwNUM4LzZGM3VUb1J6Qm1aCmM2Znhvblo1UWdreDBWRHl4R3lMU0w2UXRudFBXdkpha0RsZFphek4zUlM2ZnFqZ0dFa01FUWQwdjhGcEh3RTQKZmRJbTNMYksvWWtWSXkwZ0l1TGYzVklKNkxBcjdCWW11ODE3dGxjRExud3FIZUVFL1Z3cGxvWHpWZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",
|
||||
"root-cert.pem": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMzVENDQWNXZ0F3SUJBZ0lRUWlNTDcvcFoyV0hMWVZRMGFIelpMREFOQmdrcWhraUc5dzBCQVFzRkFEQVkKTVJZd0ZBWURWUVFLRXcxamJIVnpkR1Z5TG14dlkyRnNNQjRYRFRJeE1ERXlNVEF4TURZek1Gb1hEVE14TURFeApPVEF4TURZek1Gb3dHREVXTUJRR0ExVUVDaE1OWTJ4MWMzUmxjaTVzYjJOaGJEQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFLZGJpM0JYZ0FkcElYcDVCaThYdWMxVWhZei91SmtXYkxBODRxRTAKdmtHQ3R6N3cycFltUEJ2dmdvUzZzdyt2MGlHcFdsZllGdDQ0U1p1V1M4Um5SR2QzeXhtK09oWmFab1c0eFI2bwpRdE9wRTFUMnc3QUVFeTVKY2MvUkdjTHBiWXpPUFdCamtXU01YSmZoeEJSeTZZL3J3dUJMVjBrRjNlZnF5cUVUCklUcUxaWVYxYS9BYzhGcGVkcnlieVFBSHRzcWdnTUNMN250VlgrMUZwdUg5QVhmRGxpV0tTNnJ1T2tPUEMrY1IKY3l2ZkUyRmlINmMyZkVqeU5WMTU3cEc1UHliQTFsaGdMUVVXSUsxZ1FBTGg1Um9IVE1BUDFYakt3S2FWeDBRVApSeDhpaWlhZnVvdHEyZ3Q2NDRtL2ZmRndRUmVKVTcwLytrV2h6NXBsNGQrVVQzOENBd0VBQWFNak1DRXdEZ1lEClZSMFBBUUgvQkFRREFnSUVNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUIKQUtCcDdxS1MrNENhb29naCtiVmVmOWoyaFRLOFVPRDNWSzFuQXFLRllZcCtvU3l4dzI2bGNmcWpBVXlBYmp2RQpUSEtQaHhaL3NtbVd1RGU0SWI0YTAvNi9RaWRqemJSMTVCOWlwWTFESExqUGU4anJMMm1uSjd0YzBSYnM0ZFVrCjVIV0VXbzRDZXM0SFUwajVFVGdycHdUY2J5VXYyVTRXNjA1WTRMRnJCNVJWOS9wSkRyKzhtb1FhdWhEZEpTTHIKaW1yZ0xyVmRxZHRTOTl6dDdVRTRsZ3ovckpKV1h6eSs4S1dZRjh5RXUxSjVnNUhMR25ubXJZbjRGUUFEZW1iSQp3bnBvc1FObm5XUnZqSXZlRDE3dDNnOHFSbFhDa1krZGM4VGJKT2lEZ1JUOC9yUlo3REpiMjlsQlp0NkpkOE10CjRCZzNSaDllTVBhWHFIZUdlckhHMzgwPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="
|
||||
},
|
||||
"kind": "Secret",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"istio.io/service-account.name": "jaeger-operator"
|
||||
},
|
||||
"creationTimestamp": "2021-01-21T01:08:25Z",
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:data": {
|
||||
".": {},
|
||||
"f:cert-chain.pem": {},
|
||||
"f:key.pem": {},
|
||||
"f:root-cert.pem": {}
|
||||
},
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:istio.io/service-account.name": {}
|
||||
}
|
||||
},
|
||||
"f:type": {}
|
||||
},
|
||||
"manager": "istio_ca",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:08:25Z"
|
||||
}
|
||||
],
|
||||
"name": "istio.jaeger-operator",
|
||||
"namespace": "default",
|
||||
"resourceVersion": "451570",
|
||||
"selfLink": "/api/v1/namespaces/default/secrets/istio.jaeger-operator",
|
||||
"uid": "fb60f655-6b24-4f35-8e2d-17d7ca3ba7d4"
|
||||
},
|
||||
"type": "istio.io/key-and-cert"
|
||||
}
|
66
infrastructure/kubequery/internal/k8s/core/testdata/service_account_test.json
vendored
Normal file
66
infrastructure/kubequery/internal/k8s/core/testdata/service_account_test.json
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ServiceAccount",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"ServiceAccount\",\"metadata\":{\"annotations\":{},\"labels\":{\"app\":\"istio-ingressgateway\",\"chart\":\"gateways\",\"heritage\":\"Tiller\",\"release\":\"istio\"},\"name\":\"istio-ingressgateway-service-account\",\"namespace\":\"istio-system\"}}\n"
|
||||
},
|
||||
"creationTimestamp": "2021-01-21T01:05:43Z",
|
||||
"labels": {
|
||||
"app": "istio-ingressgateway",
|
||||
"chart": "gateways",
|
||||
"heritage": "Tiller",
|
||||
"release": "istio"
|
||||
},
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:secrets": {
|
||||
".": {},
|
||||
"k:{\"name\":\"istio-ingressgateway-service-account-token-zmk8b\"}": {
|
||||
".": {},
|
||||
"f:name": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"manager": "kube-controller-manager",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:05:43Z"
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:annotations": {
|
||||
".": {},
|
||||
"f:kubectl.kubernetes.io/last-applied-configuration": {}
|
||||
},
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:app": {},
|
||||
"f:chart": {},
|
||||
"f:heritage": {},
|
||||
"f:release": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"manager": "kubectl-client-side-apply",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:05:43Z"
|
||||
}
|
||||
],
|
||||
"name": "istio-ingressgateway-service-account",
|
||||
"namespace": "istio-system",
|
||||
"resourceVersion": "450491",
|
||||
"selfLink": "/api/v1/namespaces/istio-system/serviceaccounts/istio-ingressgateway-service-account",
|
||||
"uid": "de09c78a-ea26-42ff-82d5-2f7d3f24a8d1"
|
||||
},
|
||||
"secrets": [
|
||||
{
|
||||
"name": "istio-ingressgateway-service-account-token-zmk8b"
|
||||
}
|
||||
]
|
||||
}
|
94
infrastructure/kubequery/internal/k8s/core/testdata/services_test.json
vendored
Normal file
94
infrastructure/kubequery/internal/k8s/core/testdata/services_test.json
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"creationTimestamp": "2021-01-21T01:08:52Z",
|
||||
"labels": {
|
||||
"name": "jaeger-operator"
|
||||
},
|
||||
"managedFields": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"fieldsType": "FieldsV1",
|
||||
"fieldsV1": {
|
||||
"f:metadata": {
|
||||
"f:labels": {
|
||||
".": {},
|
||||
"f:name": {}
|
||||
},
|
||||
"f:ownerReferences": {
|
||||
".": {},
|
||||
"k:{\"uid\":\"baa856ea-2d04-4bbb-b9be-aa5b89c58087\"}": {
|
||||
".": {},
|
||||
"f:apiVersion": {},
|
||||
"f:blockOwnerDeletion": {},
|
||||
"f:controller": {},
|
||||
"f:kind": {},
|
||||
"f:name": {},
|
||||
"f:uid": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"f:spec": {
|
||||
"f:ports": {
|
||||
".": {},
|
||||
"k:{\"port\":8383,\"protocol\":\"TCP\"}": {
|
||||
".": {},
|
||||
"f:name": {},
|
||||
"f:port": {},
|
||||
"f:protocol": {},
|
||||
"f:targetPort": {}
|
||||
}
|
||||
},
|
||||
"f:selector": {
|
||||
".": {},
|
||||
"f:name": {}
|
||||
},
|
||||
"f:sessionAffinity": {},
|
||||
"f:type": {}
|
||||
}
|
||||
},
|
||||
"manager": "jaeger-operator",
|
||||
"operation": "Update",
|
||||
"time": "2021-01-21T01:08:52Z"
|
||||
}
|
||||
],
|
||||
"name": "jaeger-operator",
|
||||
"namespace": "default",
|
||||
"ownerReferences": [
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"blockOwnerDeletion": true,
|
||||
"controller": true,
|
||||
"kind": "Deployment",
|
||||
"name": "jaeger-operator",
|
||||
"uid": "baa856ea-2d04-4bbb-b9be-aa5b89c58087"
|
||||
}
|
||||
],
|
||||
"resourceVersion": "451805",
|
||||
"selfLink": "/api/v1/namespaces/default/services/jaeger-operator",
|
||||
"uid": "d8dfda88-e2c5-479e-bb2d-d0964805a925"
|
||||
},
|
||||
"spec": {
|
||||
"clusterIP": "10.152.183.187",
|
||||
"clusterIPs": [
|
||||
"10.152.183.187"
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"name": "metrics",
|
||||
"port": 8383,
|
||||
"protocol": "TCP",
|
||||
"targetPort": 8383
|
||||
}
|
||||
],
|
||||
"selector": {
|
||||
"name": "jaeger-operator"
|
||||
},
|
||||
"sessionAffinity": "None",
|
||||
"type": "ClusterIP"
|
||||
},
|
||||
"status": {
|
||||
"loadBalancer": {}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user