Merge remote-tracking branch 'origin/main' into ds-apiserver-with-configs
This commit is contained in:
+2
-49
@@ -1687,15 +1687,6 @@ exports[`better eslint`] = {
|
||||
"public/app/features/dashboard-scene/serialization/transformToV1TypesUtils.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/settings/GeneralSettingsEditView.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "1"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "2"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "3"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "4"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "5"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "6"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/settings/annotations/AnnotationSettingsEdit.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "1"],
|
||||
@@ -2547,10 +2538,10 @@ exports[`better eslint`] = {
|
||||
"public/app/features/plugins/loader/sharedDependencies.ts:5381": [
|
||||
[0, 0, 0, "* import is invalid because \'Layout,HorizontalGroup,VerticalGroup\' from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"]
|
||||
],
|
||||
"public/app/features/plugins/sandbox/distortion_map.ts:5381": [
|
||||
"public/app/features/plugins/sandbox/distortions.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/features/plugins/sandbox/sandbox_plugin_loader.ts:5381": [
|
||||
"public/app/features/plugins/sandbox/sandboxPluginLoader.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "2"]
|
||||
@@ -3130,9 +3121,6 @@ exports[`better eslint`] = {
|
||||
"public/app/plugins/datasource/cloud-monitoring/types/types.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/cloud-monitoring/webpack.config.ts:5381": [
|
||||
[0, 0, 0, "Do not re-export imported variable (\`config\`)", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/cloudwatch/components/ConfigEditor/ConfigEditor.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "1"],
|
||||
@@ -3299,9 +3287,6 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
],
|
||||
"public/app/plugins/datasource/grafana-testdata-datasource/webpack.config.ts:5381": [
|
||||
[0, 0, 0, "Do not re-export imported variable (\`config\`)", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/grafana/components/AnnotationQueryEditor.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "1"],
|
||||
@@ -3653,9 +3638,6 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
|
||||
],
|
||||
"public/app/plugins/datasource/tempo/webpack.config.ts:5381": [
|
||||
[0, 0, 0, "Do not re-export imported variable (\`config\`)", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/zipkin/QueryField.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
@@ -3666,9 +3648,6 @@ exports[`better eslint`] = {
|
||||
"public/app/plugins/datasource/zipkin/utils/transforms.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/zipkin/webpack.config.ts:5381": [
|
||||
[0, 0, 0, "Do not re-export imported variable (\`config\`)", "0"]
|
||||
],
|
||||
"public/app/plugins/panel/annolist/AnnoListPanel.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
@@ -4012,9 +3991,6 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
],
|
||||
"public/app/types/acl.ts:5381": [
|
||||
[0, 0, 0, "Do not re-export imported variable (\`OrgRole\`)", "0"]
|
||||
],
|
||||
"public/app/types/alerting.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
@@ -4036,29 +4012,6 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "8"]
|
||||
],
|
||||
"public/app/types/index.ts:5381": [
|
||||
[0, 0, 0, "Do not re-export imported variable (\`CoreEvents\`)", "0"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "1"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "2"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "3"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "4"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "5"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "6"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "7"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "8"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "9"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "10"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "11"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "12"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "13"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "14"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "15"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "16"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "17"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "18"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "19"],
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "20"]
|
||||
],
|
||||
"public/app/types/jquery/jquery.d.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
|
||||
@@ -7,6 +7,7 @@ on:
|
||||
|
||||
jobs:
|
||||
download-sources-from-crowdin:
|
||||
if: github.repository == 'grafana/grafana'
|
||||
uses: grafana/grafana-github-actions/.github/workflows/crowdin-download.yml@main
|
||||
with:
|
||||
crowdin_project_id: 5
|
||||
|
||||
@@ -14,6 +14,7 @@ on:
|
||||
|
||||
jobs:
|
||||
upload-sources-to-crowdin:
|
||||
if: github.repository == 'grafana/grafana'
|
||||
uses: grafana/grafana-github-actions/.github/workflows/crowdin-upload.yml@main
|
||||
with:
|
||||
crowdin_project_id: 5
|
||||
|
||||
+46
-36
@@ -1,29 +1,56 @@
|
||||
# Contributing to Grafana
|
||||
# Contribute to Grafana
|
||||
|
||||
Thank you for your interest in contributing to Grafana! We welcome all people who want to contribute in a healthy and constructive manner within our community. To help us create a safe and positive community experience for all, we require all participants to adhere to the [Code of Conduct](CODE_OF_CONDUCT.md).
|
||||
|
||||
This document is a guide to help you through the process of contributing to Grafana.
|
||||
This document is a guide to help you through the process of making technical contributions to Grafana.
|
||||
|
||||
## Become a contributor
|
||||
Whether you're a new contributer or a seasoned veteran we hope these resources help you connect with the community:
|
||||
|
||||
You can contribute to Grafana in several ways. Here are some examples:
|
||||
Interact and be heard:
|
||||
|
||||
- Contribute to the Grafana codebase.
|
||||
- Report and triage bugs.
|
||||
- Develop community plugins and dashboards.
|
||||
- Write technical documentation and blog posts, for users and contributors.
|
||||
- Organize meetups and user groups in your local area.
|
||||
- Help others by answering questions about Grafana.
|
||||
- Forums: Do you have a problem, question, or curiosity? Visit our [forums](https://gra.fan/fromgithubtoforums) for a reservoir of knowledge- submit your own questions and answers!
|
||||
- Meetups: Craving in-person connections without the long journeys? [Join your local Grafana & Friends meetup group](https://gra.fan/githubtomeetup)!
|
||||
- Community Slack: Eager for real-time connections with fellow users? Begin a conversation on [Slack](https://gra.fan/githubtoslack).
|
||||
Learn:
|
||||
- YouTube: From getting started to exploring newer projects like Pyroscope and Beyla, the [Grafana YouTube channel](https://gra.fan/githubtoyoutube) has what you need to get started!
|
||||
- Meetups: Join a [group near you](https://gra.fan/githubtomeetup) to learn from local experts and ask questions in real time.
|
||||
Share your story:
|
||||
- Meetups and blogs: We’d love to feature your OSS Grafana Labs use case or story at an upcoming Grafana & Friends meetup or on the Grafana blog! Submit your idea [here](https://gra.fan/githubtocca) and we’ll connect with you on next steps if accepted.
|
||||
|
||||
## Make technical contributions
|
||||
|
||||
We welcome your technical contributions! Here are some examples:
|
||||
|
||||
- Contribute to the Grafana codebase- check out these [help-wanted issues](<(https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)>)
|
||||
- Develop community [plugins](https://grafana.com/developers/plugin-tools)
|
||||
- Report [bugs](https://github.com/grafana/grafana/issues/new?template=0-bug-report.yaml)
|
||||
- [Triage issues](https://github.com/grafana/grafana/blob/4414b92e93440cc9ed0f281989ee71dc16216a15/contribute/triage-issues.md)
|
||||
- Report [security vulnerabilities](https://github.com/grafana/grafana/security/policy)
|
||||
- Submit a [feature request](https://github.com/grafana/grafana/issues/new?template=1-feature_requests.md)
|
||||
- Write [technical documentation](https://github.com/grafana/grafana/blob/4414b92e93440cc9ed0f281989ee71dc16216a15/contribute/documentation/README.md)
|
||||
|
||||
**Please note:** We do not currently accept contributions for translations. Please do not submit pull requests translating grafana.json files - they will be rejected. We do accept contributions to mark up phrases for translation. See [Internationalization](contribute/internationalization.md).
|
||||
|
||||
For more ways to contribute, check out the [Open Source Guides](https://opensource.guide/how-to-contribute/).
|
||||
### Your first contribution
|
||||
|
||||
Unsure where to begin contributing to Grafana? Start by browsing issues labeled `beginner friendly` or `help wanted`.
|
||||
|
||||
- [Beginner-friendly](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22beginner+friendly%22) issues are generally straightforward to complete.
|
||||
- [Help wanted](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) issues are problems we would like the community to help us with regardless of complexity.
|
||||
|
||||
If you're looking to make a code change, see how to set up your environment for [local development](contribute/developer-guide.md).
|
||||
|
||||
When you're ready to contribute, it's time to [create a pull request](/contribute/create-pull-request.md).
|
||||
|
||||
### Develop a plugin
|
||||
|
||||
Developing a Grafana plugin is a fantastic way to share your unique ideas with the community, extend the platform’s capabilities, and make a real impact on how people visualize and understand their data. Check out our guide to creating [plugins](https://grafana.com/developers/plugin-tools)
|
||||
|
||||
### Report bugs
|
||||
|
||||
Before submitting a new issue, try to make sure someone hasn't already reported the problem. Look through the [existing issues](https://github.com/grafana/grafana/issues) for similar issues.
|
||||
|
||||
Report a bug by submitting a [bug report](https://github.com/grafana/grafana/issues/new?labels=type%3A+bug&template=1-bug_report.md). Make sure that you provide as much information as possible on how to reproduce the bug.
|
||||
Report a bug by submitting a [bug report](https://github.com/grafana/grafana/issues/new?template=0-bug-report.yaml). Make sure that you provide as much information as possible on how to reproduce the bug.
|
||||
|
||||
Follow the issue template and add additional information that will help us replicate the problem.
|
||||
|
||||
@@ -38,42 +65,25 @@ For a dashboard related issues:
|
||||
|
||||
For authentication and alerting Grafana server logs are useful.
|
||||
|
||||
#### Security issues
|
||||
|
||||
If you believe you've found a security vulnerability, please read our [security policy](https://github.com/grafana/grafana/security/policy) for more details.
|
||||
|
||||
### Suggest enhancements
|
||||
|
||||
If you have an idea of how to improve Grafana, submit a [feature request](https://github.com/grafana/grafana/issues/new?assignees=&labels=type%2Ffeature-request&projects=&template=1-feature_requests.md).
|
||||
|
||||
We want to make Grafana accessible to even more people. Submit an [accessibility issue](https://github.com/grafana/grafana/issues/new?labels=type%3A+accessibility&template=3-accessibility.md) to help us understand what we can improve.
|
||||
|
||||
### Write documentation
|
||||
|
||||
To edit or write technical content, refer to [Contribute to our documentation](/contribute/documentation/README.md). We welcome your expertise and input as our body of technical content grows.
|
||||
|
||||
### Triage issues
|
||||
|
||||
If you don't have the knowledge or time to code, consider helping with _issue triage_. The community will thank you for saving them time by spending some of yours.
|
||||
|
||||
Read more about the ways you can [Triage issues](/contribute/triage-issues.md).
|
||||
|
||||
### Answering questions
|
||||
#### Security issues
|
||||
|
||||
If you have a question and you can't find the answer in the [documentation](https://grafana.com/docs/), the next step is to ask it on the [community site](https://community.grafana.com/).
|
||||
If you believe you've found a security vulnerability, please read our [security policy](https://github.com/grafana/grafana/security/policy) for more details on reporting.
|
||||
|
||||
It's important to us to help these users, and we'd love your help. Sign up to our [community site](https://community.grafana.com/), and start helping other Grafana users by answering their questions.
|
||||
### Suggest enhancements
|
||||
|
||||
### Your first contribution
|
||||
If you have an idea of how to improve Grafana, submit a [feature request](https://github.com/grafana/grafana/issues/new?template=1-feature_requests.md).
|
||||
|
||||
Unsure where to begin contributing to Grafana? Start by browsing issues labeled `beginner friendly` or `help wanted`.
|
||||
We want to make Grafana accessible to even more people. Submit an [accessibility issue](https://github.com/grafana/grafana/issues/new?template=2-accessibility.md) to help us understand what we can improve.
|
||||
|
||||
- [Beginner-friendly](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22beginner+friendly%22) issues are generally straightforward to complete.
|
||||
- [Help wanted](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) issues are problems we would like the community to help us with regardless of complexity.
|
||||
### Write documentation
|
||||
|
||||
If you're looking to make a code change, see how to set up your environment for [local development](contribute/developer-guide.md).
|
||||
|
||||
When you're ready to contribute, it's time to [create a pull request](/contribute/create-pull-request.md).
|
||||
To edit or write technical content, refer to [Contribute to our documentation](/contribute/documentation/README.md). We welcome your expertise and input as our body of technical content grows.
|
||||
|
||||
#### Contributor License Agreement (CLA)
|
||||
|
||||
|
||||
@@ -14,8 +14,6 @@ import (
|
||||
v0alpha1 "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
|
||||
)
|
||||
|
||||
var ()
|
||||
|
||||
var appManifestData = app.ManifestData{
|
||||
AppName: "alerting",
|
||||
Group: "notifications.alerting.grafana.app",
|
||||
|
||||
@@ -16,8 +16,6 @@ import (
|
||||
v2alpha1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1"
|
||||
)
|
||||
|
||||
var ()
|
||||
|
||||
var appManifestData = app.ManifestData{
|
||||
AppName: "dashboard",
|
||||
Group: "dashboard.grafana.app",
|
||||
|
||||
@@ -14,8 +14,6 @@ import (
|
||||
v1beta1 "github.com/grafana/grafana/apps/folder/pkg/apis/folder/v1beta1"
|
||||
)
|
||||
|
||||
var ()
|
||||
|
||||
var appManifestData = app.ManifestData{
|
||||
AppName: "folder",
|
||||
Group: "folder.grafana.app",
|
||||
|
||||
@@ -82,7 +82,7 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general-
|
||||
| `alertingMigrationUI` | Enables the alerting migration UI, to migrate data source-managed rules to Grafana-managed rules | Yes |
|
||||
| `alertingImportYAMLUI` | Enables a UI feature for importing rules from a Prometheus file to Grafana-managed rules | Yes |
|
||||
| `unifiedNavbars` | Enables unified navbars | |
|
||||
| `tabularNumbers` | Use fixed-width numbers globally in the UI | Yes |
|
||||
| `tabularNumbers` | Use fixed-width numbers globally in the UI | |
|
||||
|
||||
## Public preview feature toggles
|
||||
|
||||
|
||||
-8
@@ -239,10 +239,6 @@ Ensure that you have followed the steps in [Create the Microsoft Entra ID applic
|
||||
|
||||
## Configure Azure AD authentication client using the Grafana UI
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Available in Public Preview in Grafana 10.4 behind the `ssoSettingsApi` feature toggle.
|
||||
{{< /admonition >}}
|
||||
|
||||
As a Grafana Admin, you can configure your Azure AD/Entra ID OAuth client from within Grafana using the Grafana UI. To do this, navigate to the **Administration > Authentication > Azure AD** page and fill in the form. If you have a current configuration in the Grafana configuration file, the form will be pre-populated with those values. Otherwise the form will contain default values.
|
||||
|
||||
After you have filled in the form, click **Save** to save the configuration. If the save was successful, Grafana will apply the new configurations.
|
||||
@@ -255,10 +251,6 @@ If you run Grafana in high availability mode, configuration changes may not get
|
||||
|
||||
## Configure Azure AD authentication client using the Terraform provider
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Available in Public Preview in Grafana 10.4 behind the `ssoSettingsApi` feature toggle. Supported in the Terraform provider since v2.12.0.
|
||||
{{< /admonition >}}
|
||||
|
||||
```terraform
|
||||
resource "grafana_sso_settings" "azuread_sso_settings" {
|
||||
provider_name = "azuread"
|
||||
|
||||
-8
@@ -49,10 +49,6 @@ If Users use the same email address in Azure AD that they use with other authent
|
||||
|
||||
## Configure generic OAuth authentication client using the Grafana UI
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Available behind the `ssoSettingsAPI` feature toggle, which is enabled by default.
|
||||
{{< /admonition >}}
|
||||
|
||||
As a Grafana Admin, you can configure Generic OAuth client from within Grafana using the Generic OAuth UI. To do this, navigate to **Administration > Authentication > Generic OAuth** page and fill in the form. If you have a current configuration in the Grafana configuration file then the form will be pre-populated with those values otherwise the form will contain default values.
|
||||
|
||||
After you have filled in the form, click **Save** to save the configuration. If the save was successful, Grafana will apply the new configurations.
|
||||
@@ -67,10 +63,6 @@ Refer to [configuration options](#configuration-options) for more information.
|
||||
|
||||
## Configure generic OAuth authentication client using the Terraform provider
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Available behind the `ssoSettingsAPI` feature toggle, which is enabled by default. Supported in the Terraform provider since v2.12.0.
|
||||
{{< /admonition >}}
|
||||
|
||||
```terraform
|
||||
resource "grafana_sso_settings" "generic_sso_settings" {
|
||||
provider_name = "generic_oauth"
|
||||
|
||||
@@ -43,10 +43,6 @@ Ensure you know how to create a GitHub OAuth app. Consult GitHub's documentation
|
||||
|
||||
## Configure GitHub authentication client using the Grafana UI
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Available behind the `ssoSettingsAPI` feature toggle, which is enabled by default.
|
||||
{{< /admonition >}}
|
||||
|
||||
As a Grafana Admin, you can configure GitHub OAuth client from within Grafana using the GitHub UI. To do this, navigate to **Administration > Authentication > GitHub** page and fill in the form. If you have a current configuration in the Grafana configuration file, the form will be pre-populated with those values. Otherwise the form will contain default values.
|
||||
|
||||
After you have filled in the form, click **Save**. If the save was successful, Grafana will apply the new configurations.
|
||||
@@ -61,10 +57,6 @@ Refer to [configuration options](#configuration-options) for more information.
|
||||
|
||||
## Configure GitHub authentication client using the Terraform provider
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Available behind the `ssoSettingsAPI` feature toggle, which is enabled by default. Supported in the Terraform provider since v2.12.0.
|
||||
{{< /admonition >}}
|
||||
|
||||
```terraform
|
||||
resource "grafana_sso_settings" "github_sso_settings" {
|
||||
provider_name = "github"
|
||||
|
||||
@@ -57,10 +57,6 @@ Refer to [configuration options](#configuration-options) for more information.
|
||||
|
||||
## Configure GitLab authentication client using the Terraform provider
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Available behind the `ssoSettingsAPI` feature toggle, which is enabled by default. Supported in the Terraform provider since v2.12.0.
|
||||
{{< /admonition >}}
|
||||
|
||||
```terraform
|
||||
resource "grafana_sso_settings" "gitlab_sso_settings" {
|
||||
provider_name = "gitlab"
|
||||
|
||||
@@ -45,10 +45,6 @@ First, you need to create a Google OAuth Client:
|
||||
|
||||
## Configure Google authentication client using the Grafana UI
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Available behind the `ssoSettingsAPI` feature toggle, which is enabled by default.
|
||||
{{< /admonition >}}
|
||||
|
||||
As a Grafana Admin, you can configure Google OAuth client from within Grafana using the Google UI. To do this, navigate to **Administration > Authentication > Google** page and fill in the form. If you have a current configuration in the Grafana configuration file then the form will be pre-populated with those values otherwise the form will contain default values.
|
||||
|
||||
After you have filled in the form, click **Save**. If the save was successful, Grafana will apply the new configurations.
|
||||
@@ -61,10 +57,6 @@ If you run Grafana in high availability mode, configuration changes may not get
|
||||
|
||||
## Configure Google authentication client using the Terraform provider
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Available behind the `ssoSettingsAPI` feature toggle, which is enabled by default. Supported in the Terraform provider since v2.12.0.
|
||||
{{< /admonition >}}
|
||||
|
||||
```terraform
|
||||
resource "grafana_sso_settings" "google_sso_settings" {
|
||||
provider_name = "google"
|
||||
|
||||
@@ -101,10 +101,6 @@ If you want to configure the role for all users in the Okta directory, you can a
|
||||
|
||||
## Configure Okta authentication client using the Grafana UI
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Available behind the `ssoSettingsAPI` feature toggle, which is enabled by default.
|
||||
{{< /admonition >}}
|
||||
|
||||
As a Grafana Admin, you can configure Okta OAuth2 client from within Grafana using the Okta UI. To do this, navigate to **Administration > Authentication > Okta** page and fill in the form. If you have a current configuration in the Grafana configuration file then the form will be pre-populated with those values otherwise the form will contain default values.
|
||||
|
||||
After you have filled in the form, click **Save**. If the save was successful, Grafana will apply the new configurations.
|
||||
@@ -119,10 +115,6 @@ Refer to [configuration options](#configuration-options) for more information.
|
||||
|
||||
## Configure Okta authentication client using the Terraform provider
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Available behind the `ssoSettingsAPI` feature toggle, which is enabled by default. Supported in the Terraform provider since v2.12.0.
|
||||
{{< /admonition >}}
|
||||
|
||||
```terraform
|
||||
resource "grafana_sso_settings" "okta_sso_settings" {
|
||||
provider_name = "okta"
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ If you are using Okta or Azure AD as Identity Provider, see the following docume
|
||||
- [Configure SAML with Okta](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-security/configure-authentication/saml/configure-saml-with-okta/)
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
The API and Terraform support are available in Public Preview in Grafana v11.1 behind the `ssoSettingsSAML` feature toggle. You must also enable the `ssoSettingsApi` flag.
|
||||
The API and Terraform support are available in Public Preview in Grafana v11.1 behind the `ssoSettingsSAML` feature toggle.
|
||||
{{< /admonition >}}
|
||||
|
||||
All methods offer the same configuration options. However, if you want to keep all of Grafana authentication settings in one place, use the Grafana configuration file or the Terraform provider. If you are a Grafana Cloud user, you do not have access to Grafana configuration file. Instead, configure SAML through the other methods.
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"version": "12.1.0-pre",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "webpack -c ./webpack.config.ts --env production",
|
||||
"dev": "webpack -w -c ./webpack.config.ts --env development",
|
||||
"build": "NODE_OPTIONS='--experimental-strip-types --no-warnings=ExperimentalWarning' webpack -c ./webpack.config.ts --env production",
|
||||
"dev": "NODE_OPTIONS='--experimental-strip-types --no-warnings=ExperimentalWarning' webpack -w -c ./webpack.config.ts --env development",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "eslint --cache --ignore-path ./.gitignore --ext .js,.jsx,.ts,.tsx ."
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import CopyWebpackPlugin from 'copy-webpack-plugin';
|
||||
import grafanaConfig from '@grafana/plugin-configs/webpack.config';
|
||||
import grafanaConfig, { type Env } from '@grafana/plugin-configs/webpack.config.ts';
|
||||
import { mergeWithCustomize, unique } from 'webpack-merge';
|
||||
import { Configuration } from 'webpack';
|
||||
import { type Configuration } from 'webpack';
|
||||
|
||||
function skipFiles(f: string): boolean {
|
||||
if (f.includes('/dist/')) {
|
||||
@@ -19,7 +19,7 @@ function skipFiles(f: string): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
const config = async (env: Record<string, unknown>): Promise<Configuration> => {
|
||||
const config = async (env: Env): Promise<Configuration> => {
|
||||
const baseConfig = await grafanaConfig(env);
|
||||
const customConfig = {
|
||||
plugins: [
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"version": "12.1.0-pre",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "webpack -c ./webpack.config.ts --env production",
|
||||
"dev": "webpack -w -c ./webpack.config.ts --env development",
|
||||
"build": "NODE_OPTIONS='--experimental-strip-types --no-warnings=ExperimentalWarning' webpack -c ./webpack.config.ts --env production",
|
||||
"dev": "NODE_OPTIONS='--experimental-strip-types --no-warnings=ExperimentalWarning' webpack -w -c ./webpack.config.ts --env development",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "eslint --cache --ignore-path ./.gitignore --ext .js,.jsx,.ts,.tsx ."
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import CopyWebpackPlugin from 'copy-webpack-plugin';
|
||||
import grafanaConfig from '@grafana/plugin-configs/webpack.config';
|
||||
import grafanaConfig, { type Env } from '@grafana/plugin-configs/webpack.config.ts';
|
||||
import { mergeWithCustomize, unique } from 'webpack-merge';
|
||||
import { Configuration } from 'webpack';
|
||||
import { type Configuration } from 'webpack';
|
||||
|
||||
function skipFiles(f: string): boolean {
|
||||
if (f.includes('/dist/')) {
|
||||
@@ -19,7 +19,7 @@ function skipFiles(f: string): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
const config = async (env: Record<string, unknown>): Promise<Configuration> => {
|
||||
const config = async (env: Env): Promise<Configuration> => {
|
||||
const baseConfig = await grafanaConfig(env);
|
||||
const customConfig = {
|
||||
plugins: [
|
||||
|
||||
@@ -99,14 +99,14 @@ require (
|
||||
github.com/grafana/grafana-api-golang-client v0.27.0 // @grafana/alerting-backend
|
||||
github.com/grafana/grafana-app-sdk v0.39.2 // @grafana/grafana-app-platform-squad
|
||||
github.com/grafana/grafana-app-sdk/logging v0.39.1 // @grafana/grafana-app-platform-squad
|
||||
github.com/grafana/grafana-aws-sdk v1.0.2 // @grafana/aws-datasources
|
||||
github.com/grafana/grafana-aws-sdk v1.0.3 // @grafana/aws-datasources
|
||||
github.com/grafana/grafana-azure-sdk-go/v2 v2.1.6 // @grafana/partner-datasources
|
||||
github.com/grafana/grafana-cloud-migration-snapshot v1.6.0 // @grafana/grafana-operator-experience-squad
|
||||
github.com/grafana/grafana-google-sdk-go v0.4.1 // @grafana/partner-datasources
|
||||
github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79 // @grafana/grafana-backend-group
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.278.0 // @grafana/plugins-platform-backend
|
||||
github.com/grafana/loki/v3 v3.2.1 // @grafana/observability-logs
|
||||
github.com/grafana/nanogit v0.0.0-20250625082556-a4828b879bbb // @grafana-app-platform-squad
|
||||
github.com/grafana/nanogit v0.0.0-20250709085038-55508a6a9f40 // @grafana-app-platform-squad
|
||||
github.com/grafana/otel-profiling-go v0.5.1 // @grafana/grafana-backend-group
|
||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // @grafana/observability-traces-and-profiling
|
||||
github.com/grafana/pyroscope/api v1.2.1-0.20250415190842-3ff7247547ae // @grafana/observability-traces-and-profiling
|
||||
|
||||
@@ -1610,8 +1610,8 @@ github.com/grafana/grafana-app-sdk v0.39.2 h1:ymfr+1318t+JC9U2OYrzVpGmNG/aJONUmF
|
||||
github.com/grafana/grafana-app-sdk v0.39.2/go.mod h1:t0m6q561lpoHQCixS9LUHFUhUzDClzNtm7BH60gHVSY=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.39.1 h1:lI5rbrheuwVPuyIM6LIuEYOCSpgmXahfKtqeMyhbGPU=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.39.1/go.mod h1:WhDENSnaGHtyVVwZGVnAR7YLvh2xlLDYR3D7E6h7XVk=
|
||||
github.com/grafana/grafana-aws-sdk v1.0.2 h1:98eBuHYFmgvH0xO9kKf4RBsEsgQRp8EOA/9yhDIpkss=
|
||||
github.com/grafana/grafana-aws-sdk v1.0.2/go.mod h1:hO7q7yWV+t6dmiyJjMa3IbuYnYkBua+G/IAlOPVIYKE=
|
||||
github.com/grafana/grafana-aws-sdk v1.0.3 h1:FtGiTrdlPXuQmLqeZdyNjjkNKOOdvQ4sxWw8MtJc6ow=
|
||||
github.com/grafana/grafana-aws-sdk v1.0.3/go.mod h1:hO7q7yWV+t6dmiyJjMa3IbuYnYkBua+G/IAlOPVIYKE=
|
||||
github.com/grafana/grafana-azure-sdk-go/v2 v2.1.6 h1:OfCkitCuomzZKW1WYHrG8MxKwtMhALb7jqoj+487eTg=
|
||||
github.com/grafana/grafana-azure-sdk-go/v2 v2.1.6/go.mod h1:V7y2BmsWxS3A9Ohebwn4OiSfJJqi//4JQydQ8fHTduo=
|
||||
github.com/grafana/grafana-cloud-migration-snapshot v1.6.0 h1:S4kHwr//AqhtL9xHBtz1gqVgZQeCRGTxjgsRBAkpjKY=
|
||||
@@ -1654,8 +1654,8 @@ github.com/grafana/loki/pkg/push v0.0.0-20231124142027-e52380921608 h1:ZYk42718k
|
||||
github.com/grafana/loki/pkg/push v0.0.0-20231124142027-e52380921608/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0=
|
||||
github.com/grafana/loki/v3 v3.2.1 h1:VB7u+KHfvL5aHAxgoVBvz5wVhsdGuqKC7uuOFOOe7jw=
|
||||
github.com/grafana/loki/v3 v3.2.1/go.mod h1:WvdLl6wOS+yahaeQY+xhD2m2XzkHDfKr5FZaX7D/X2Y=
|
||||
github.com/grafana/nanogit v0.0.0-20250625082556-a4828b879bbb h1:JR672zBiCkfiKuRRsU76TRC2q12q0VfZl2SP8jBIAJQ=
|
||||
github.com/grafana/nanogit v0.0.0-20250625082556-a4828b879bbb/go.mod h1:tN93IZUaAmnSWgL0IgnKdLv6DNeIhTJGvl1wvQMrWco=
|
||||
github.com/grafana/nanogit v0.0.0-20250709085038-55508a6a9f40 h1:wsIgOI4Ou1o/UtxtJlemLufpVBpMdcXVJxedk0wLoCM=
|
||||
github.com/grafana/nanogit v0.0.0-20250709085038-55508a6a9f40/go.mod h1:ToqLjIdvV3AZQa3K6e5m9hy/nsGaUByc2dWQlctB9iA=
|
||||
github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8=
|
||||
github.com/grafana/otel-profiling-go v0.5.1/go.mod h1:ftN/t5A/4gQI19/8MoWurBEtC6gFw8Dns1sJZ9W4Tls=
|
||||
github.com/grafana/prometheus-alertmanager v0.25.1-0.20250620093340-be61a673dee6 h1:oJnbhG6ZNy10AjsgNeAtAKeGHogIGOMfAsBH6fYYa5M=
|
||||
|
||||
+4
-4
@@ -180,7 +180,7 @@
|
||||
"cypress": "14.3.2",
|
||||
"cypress-file-upload": "5.0.8",
|
||||
"cypress-recurse": "^1.35.3",
|
||||
"esbuild": "0.25.0",
|
||||
"esbuild": "0.25.6",
|
||||
"esbuild-loader": "4.3.0",
|
||||
"esbuild-plugin-browserslist": "^1.0.0",
|
||||
"eslint": "9.19.0",
|
||||
@@ -192,13 +192,13 @@
|
||||
"eslint-plugin-jsx-a11y": "6.10.2",
|
||||
"eslint-plugin-lodash": "8.0.0",
|
||||
"eslint-plugin-no-barrel-files": "^1.1.1",
|
||||
"eslint-plugin-react": "7.37.4",
|
||||
"eslint-plugin-react": "7.37.5",
|
||||
"eslint-plugin-react-hooks": "5.1.0",
|
||||
"eslint-plugin-testing-library": "^7.0.0",
|
||||
"eslint-plugin-unicorn": "^56.0.0",
|
||||
"eslint-scope": "^8.1.0",
|
||||
"eslint-webpack-plugin": "4.2.0",
|
||||
"expose-loader": "5.0.0",
|
||||
"expose-loader": "5.0.1",
|
||||
"fishery": "^2.2.2",
|
||||
"fork-ts-checker-webpack-plugin": "9.0.2",
|
||||
"glob": "11.0.1",
|
||||
@@ -279,7 +279,7 @@
|
||||
"@grafana/faro-web-sdk": "^1.13.2",
|
||||
"@grafana/faro-web-tracing": "^1.13.2",
|
||||
"@grafana/flamegraph": "workspace:*",
|
||||
"@grafana/google-sdk": "0.3.2",
|
||||
"@grafana/google-sdk": "0.3.4",
|
||||
"@grafana/i18n": "workspace:*",
|
||||
"@grafana/lezer-logql": "0.2.8",
|
||||
"@grafana/llm": "0.22.1",
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
"@types/react": "18.3.18",
|
||||
"@types/react-dom": "18.3.5",
|
||||
"@types/tinycolor2": "1.4.6",
|
||||
"esbuild": "0.25.0",
|
||||
"esbuild": "0.25.6",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"rimraf": "6.0.1",
|
||||
|
||||
@@ -999,7 +999,7 @@ export interface FeatureToggles {
|
||||
preferLibraryPanelTitle?: boolean;
|
||||
/**
|
||||
* Use fixed-width numbers globally in the UI
|
||||
* @default true
|
||||
* @default false
|
||||
*/
|
||||
tabularNumbers?: boolean;
|
||||
/**
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"@rollup/plugin-node-resolve": "16.0.1",
|
||||
"@types/node": "22.15.0",
|
||||
"@types/semver": "7.7.0",
|
||||
"esbuild": "0.25.0",
|
||||
"esbuild": "0.25.6",
|
||||
"rimraf": "6.0.1",
|
||||
"rollup": "^4.22.4",
|
||||
"rollup-plugin-esbuild": "6.2.0",
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
"@types/react-virtualized-auto-sizer": "1.0.4",
|
||||
"@types/tinycolor2": "1.4.6",
|
||||
"babel-jest": "29.7.0",
|
||||
"esbuild": "0.25.0",
|
||||
"esbuild": "0.25.6",
|
||||
"jest": "^29.6.4",
|
||||
"jest-canvas-mock": "2.5.2",
|
||||
"rollup": "^4.22.4",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"dependencies": {
|
||||
"tslib": "2.8.1"
|
||||
},
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@grafana/tsconfig": "^2.0.0",
|
||||
"@swc/core": "1.10.12",
|
||||
|
||||
@@ -4,19 +4,11 @@
|
||||
"alwaysStrict": true,
|
||||
"declaration": false,
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "bundler"
|
||||
},
|
||||
"ts-node": {
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"moduleResolution": "Node",
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"transpileOnly": true
|
||||
"moduleResolution": "bundler",
|
||||
"noEmit": true,
|
||||
"allowImportingTsExtensions": true
|
||||
},
|
||||
"extends": "@grafana/tsconfig",
|
||||
|
||||
"exclude": ["**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts", "**/*.spec.tsx"],
|
||||
"include": ["./types", "."]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
declare module 'replace-in-file-webpack-plugin' {
|
||||
import { Compiler, Plugin } from 'webpack';
|
||||
|
||||
interface ReplaceRule {
|
||||
search: string | RegExp;
|
||||
replace: string | ((match: string) => string);
|
||||
}
|
||||
|
||||
interface ReplaceOption {
|
||||
dir?: string;
|
||||
files?: string[];
|
||||
test?: RegExp | RegExp[];
|
||||
rules: ReplaceRule[];
|
||||
}
|
||||
|
||||
class ReplaceInFilePlugin extends Plugin {
|
||||
constructor(options?: ReplaceOption[]);
|
||||
options: ReplaceOption[];
|
||||
apply(compiler: Compiler): void;
|
||||
}
|
||||
|
||||
export = ReplaceInFilePlugin;
|
||||
}
|
||||
@@ -3,12 +3,19 @@ import { glob } from 'glob';
|
||||
import path from 'path';
|
||||
import process from 'process';
|
||||
|
||||
// Support for node 22 and 24. Due to the many changes in importing json files
|
||||
// across recent node versions we load the json files using fs for simplicity.
|
||||
function loadJson(path: string) {
|
||||
const rawJson = fs.readFileSync(path, 'utf8');
|
||||
return JSON.parse(rawJson);
|
||||
}
|
||||
|
||||
export function getPackageJson() {
|
||||
return require(path.resolve(process.cwd(), 'package.json'));
|
||||
return loadJson(path.resolve(process.cwd(), 'package.json'));
|
||||
}
|
||||
|
||||
export function getPluginJson() {
|
||||
return require(path.resolve(process.cwd(), 'plugin.json'));
|
||||
return loadJson(path.resolve(process.cwd(), 'plugin.json'));
|
||||
}
|
||||
|
||||
export async function getEntries(): Promise<Record<string, string>> {
|
||||
|
||||
@@ -2,15 +2,14 @@ import CopyWebpackPlugin from 'copy-webpack-plugin';
|
||||
import ESLintPlugin from 'eslint-webpack-plugin';
|
||||
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
|
||||
import path from 'path';
|
||||
// @ts-expect-error - there are no types for this package
|
||||
import ReplaceInFileWebpackPlugin from 'replace-in-file-webpack-plugin';
|
||||
import TerserPlugin from 'terser-webpack-plugin';
|
||||
import { type Configuration, BannerPlugin } from 'webpack';
|
||||
import webpack, { type Configuration } from 'webpack';
|
||||
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
||||
import VirtualModulesPlugin from 'webpack-virtual-modules';
|
||||
|
||||
import { DIST_DIR } from './constants';
|
||||
import { getPackageJson, getPluginJson, getEntries, hasLicense } from './utils';
|
||||
import { DIST_DIR } from './constants.ts';
|
||||
import { getPackageJson, getPluginJson, getEntries, hasLicense } from './utils.ts';
|
||||
|
||||
function skipFiles(f: string): boolean {
|
||||
if (f.includes('/dist/')) {
|
||||
@@ -32,7 +31,7 @@ function skipFiles(f: string): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
type Env = {
|
||||
export type Env = {
|
||||
[key: string]: true | string | Env;
|
||||
};
|
||||
|
||||
@@ -54,9 +53,13 @@ const config = async (env: Env): Promise<Configuration> => {
|
||||
cache: {
|
||||
type: 'filesystem',
|
||||
buildDependencies: {
|
||||
config: [__filename],
|
||||
config: [import.meta.filename],
|
||||
},
|
||||
cacheDirectory: path.resolve(__dirname, '../../node_modules/.cache/webpack', path.basename(process.cwd())),
|
||||
cacheDirectory: path.resolve(
|
||||
import.meta.dirname,
|
||||
'../../node_modules/.cache/webpack',
|
||||
path.basename(process.cwd())
|
||||
),
|
||||
},
|
||||
|
||||
context: process.cwd(),
|
||||
@@ -114,7 +117,7 @@ const config = async (env: Env): Promise<Configuration> => {
|
||||
test: /module\.tsx?$/,
|
||||
use: [
|
||||
{
|
||||
loader: require.resolve('imports-loader'),
|
||||
loader: 'imports-loader',
|
||||
options: {
|
||||
imports: `side-effects grafana-public-path`,
|
||||
},
|
||||
@@ -125,10 +128,10 @@ const config = async (env: Env): Promise<Configuration> => {
|
||||
exclude: /(node_modules)/,
|
||||
test: /\.[tj]sx?$/,
|
||||
use: {
|
||||
loader: require.resolve('swc-loader'),
|
||||
loader: 'swc-loader',
|
||||
options: {
|
||||
jsc: {
|
||||
baseUrl: path.resolve(__dirname),
|
||||
baseUrl: path.resolve(import.meta.dirname),
|
||||
target: 'es2015',
|
||||
loose: false,
|
||||
parser: {
|
||||
@@ -209,7 +212,7 @@ const config = async (env: Env): Promise<Configuration> => {
|
||||
plugins: [
|
||||
virtualPublicPath,
|
||||
// Insert create plugin version information into the bundle so Grafana will load from cdn with script tags.
|
||||
new BannerPlugin({
|
||||
new webpack.BannerPlugin({
|
||||
banner: '/* [create-plugin] version: 5.22.0 */',
|
||||
raw: true,
|
||||
entryOnly: true,
|
||||
@@ -264,7 +267,7 @@ const config = async (env: Env): Promise<Configuration> => {
|
||||
extensions: ['.ts', '.tsx'],
|
||||
lintDirtyModulesOnly: true, // don't lint on start, only lint changed files
|
||||
cacheLocation: path.resolve(
|
||||
__dirname,
|
||||
import.meta.dirname,
|
||||
'../../node_modules/.cache/eslint-webpack-plugin',
|
||||
path.basename(process.cwd()),
|
||||
'.eslintcache'
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
"@types/node": "22.15.0",
|
||||
"@types/pluralize": "^0.0.33",
|
||||
"@types/prismjs": "1.26.5",
|
||||
"esbuild": "0.25.0",
|
||||
"esbuild": "0.25.6",
|
||||
"i18next-parser": "9.3.0",
|
||||
"jest": "29.7.0",
|
||||
"jest-environment-jsdom": "29.7.0",
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
"@types/lodash": "4.17.20",
|
||||
"@types/react": "18.3.18",
|
||||
"@types/react-dom": "18.3.5",
|
||||
"esbuild": "0.25.0",
|
||||
"esbuild": "0.25.6",
|
||||
"lodash": "4.17.21",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"devDependencies": {
|
||||
"@grafana/tsconfig": "^2.0.0",
|
||||
"@rollup/plugin-node-resolve": "16.0.1",
|
||||
"esbuild": "0.25.0",
|
||||
"esbuild": "0.25.6",
|
||||
"glob": "^11.0.0",
|
||||
"rimraf": "6.0.1",
|
||||
"rollup": "^4.22.4",
|
||||
|
||||
@@ -15,6 +15,7 @@ export const pluginVersion = "12.1.0-pre";
|
||||
export interface Options {
|
||||
controlsStorageKey?: string;
|
||||
dedupStrategy: common.LogsDedupStrategy;
|
||||
detailsMode?: ('inline' | 'sidebar');
|
||||
displayedFields?: Array<string>;
|
||||
enableInfiniteScrolling?: boolean;
|
||||
enableLogDetails: boolean;
|
||||
|
||||
@@ -181,8 +181,8 @@
|
||||
"core-js": "3.40.0",
|
||||
"css-loader": "7.1.2",
|
||||
"csstype": "3.1.3",
|
||||
"esbuild": "0.25.0",
|
||||
"expose-loader": "5.0.0",
|
||||
"esbuild": "0.25.6",
|
||||
"expose-loader": "5.0.1",
|
||||
"fs-extra": "^11.2.0",
|
||||
"mock-raf": "1.0.1",
|
||||
"msw": "^2.10.2",
|
||||
|
||||
@@ -2,6 +2,8 @@ import { css, keyframes } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
|
||||
import { getIconPath } from '../Icon/utils';
|
||||
|
||||
const slideUpIn = keyframes({
|
||||
'0%': {
|
||||
opacity: 0,
|
||||
@@ -58,143 +60,146 @@ const slideDownOut = keyframes({
|
||||
},
|
||||
});
|
||||
|
||||
export const getCascaderStyles = (theme: GrafanaTheme2) => ({
|
||||
dropdown: css({
|
||||
'&.rc-cascader-dropdown': {
|
||||
position: 'absolute',
|
||||
// Required, otherwise the portal that the popup is shown in will render under other components
|
||||
zIndex: 9999,
|
||||
export const getCascaderStyles = (theme: GrafanaTheme2) => {
|
||||
const iconPath = getIconPath('angle-right');
|
||||
return {
|
||||
dropdown: css({
|
||||
'&.rc-cascader-dropdown': {
|
||||
position: 'absolute',
|
||||
// Required, otherwise the portal that the popup is shown in will render under other components
|
||||
zIndex: 9999,
|
||||
|
||||
'&-hidden': {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
'.rc-cascader': {
|
||||
'&-menus': {
|
||||
overflow: 'hidden',
|
||||
background: theme.colors.background.elevated,
|
||||
border: `none`,
|
||||
borderRadius: theme.shape.radius.default,
|
||||
boxShadow: theme.shadows.z3,
|
||||
whiteSpace: 'nowrap',
|
||||
|
||||
'&.slide-up-enter, &.slide-up-appear': {
|
||||
animationDuration: '0.3s',
|
||||
animationFillMode: 'both',
|
||||
transformOrigin: '0 0',
|
||||
opacity: 0,
|
||||
animationTimingFunction: 'cubic-bezier(0.08, 0.82, 0.17, 1)',
|
||||
animationPlayState: 'paused',
|
||||
},
|
||||
|
||||
'&.slide-up-enter.slide-up-enter-active.rc-cascader-menus-placement, &.slide-up-appear.slide-up-appear-active.rc-cascader-menus-placement':
|
||||
{
|
||||
'&-bottomLeft': {
|
||||
animationName: slideUpIn,
|
||||
animationPlayState: 'running',
|
||||
},
|
||||
|
||||
'&-topLeft': {
|
||||
animationName: slideDownIn,
|
||||
animationPlayState: 'running',
|
||||
},
|
||||
},
|
||||
|
||||
'&.slide-up-leave': {
|
||||
animationDuration: '0.3s',
|
||||
animationFillMode: 'both',
|
||||
transformOrigin: '0 0',
|
||||
opacity: 1,
|
||||
animationTimingFunction: 'cubic-bezier(0.6, 0.04, 0.98, 0.34)',
|
||||
animationPlayState: 'paused',
|
||||
|
||||
'&.slide-up-leave-active.rc-cascader-menus-placement': {
|
||||
'&-bottomLeft': {
|
||||
animationName: slideUpOut,
|
||||
animationPlayState: 'running',
|
||||
},
|
||||
|
||||
'&-topLeft': {
|
||||
animationName: slideDownOut,
|
||||
animationPlayState: 'running',
|
||||
},
|
||||
},
|
||||
'&-hidden': {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
|
||||
'&-menu': {
|
||||
display: 'inline-block',
|
||||
maxWidth: '50vw',
|
||||
height: '192px',
|
||||
listStyle: 'none',
|
||||
margin: 0,
|
||||
padding: theme.spacing(0.5),
|
||||
borderRight: `1px solid ${theme.colors.border.weak}`,
|
||||
overflow: 'auto',
|
||||
|
||||
'&:last-child': {
|
||||
borderRight: 0,
|
||||
},
|
||||
|
||||
'&-item': {
|
||||
height: theme.spacing(4),
|
||||
lineHeight: theme.spacing(4),
|
||||
padding: theme.spacing(0, 4, 0, 2),
|
||||
borderRadius: theme.shape.radius.default,
|
||||
cursor: 'pointer',
|
||||
whiteSpace: 'nowrap',
|
||||
'.rc-cascader': {
|
||||
'&-menus': {
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
transition: 'all 0.3s ease',
|
||||
position: 'relative',
|
||||
background: theme.colors.background.elevated,
|
||||
border: `none`,
|
||||
borderRadius: theme.shape.radius.default,
|
||||
boxShadow: theme.shadows.z3,
|
||||
whiteSpace: 'nowrap',
|
||||
|
||||
'&:hover': {
|
||||
background: theme.colors.action.hover,
|
||||
'&.slide-up-enter, &.slide-up-appear': {
|
||||
animationDuration: '0.3s',
|
||||
animationFillMode: 'both',
|
||||
transformOrigin: '0 0',
|
||||
opacity: 0,
|
||||
animationTimingFunction: 'cubic-bezier(0.08, 0.82, 0.17, 1)',
|
||||
animationPlayState: 'paused',
|
||||
},
|
||||
|
||||
'&-disabled': {
|
||||
cursor: 'not-allowed',
|
||||
color: theme.colors.text.disabled,
|
||||
'&.slide-up-enter.slide-up-enter-active.rc-cascader-menus-placement, &.slide-up-appear.slide-up-appear-active.rc-cascader-menus-placement':
|
||||
{
|
||||
'&-bottomLeft': {
|
||||
animationName: slideUpIn,
|
||||
animationPlayState: 'running',
|
||||
},
|
||||
|
||||
'&:hover': {
|
||||
background: 'transparent',
|
||||
'&-topLeft': {
|
||||
animationName: slideDownIn,
|
||||
animationPlayState: 'running',
|
||||
},
|
||||
},
|
||||
|
||||
'&:after': {
|
||||
position: 'absolute',
|
||||
right: '12px',
|
||||
content: "'loading'",
|
||||
color: theme.colors.text.disabled,
|
||||
fontStyle: 'italic',
|
||||
'&.slide-up-leave': {
|
||||
animationDuration: '0.3s',
|
||||
animationFillMode: 'both',
|
||||
transformOrigin: '0 0',
|
||||
opacity: 1,
|
||||
animationTimingFunction: 'cubic-bezier(0.6, 0.04, 0.98, 0.34)',
|
||||
animationPlayState: 'paused',
|
||||
|
||||
'&.slide-up-leave-active.rc-cascader-menus-placement': {
|
||||
'&-bottomLeft': {
|
||||
animationName: slideUpOut,
|
||||
animationPlayState: 'running',
|
||||
},
|
||||
|
||||
'&-topLeft': {
|
||||
animationName: slideDownOut,
|
||||
animationPlayState: 'running',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
'&-active': {
|
||||
color: theme.colors.text.maxContrast,
|
||||
background: theme.colors.background.secondary,
|
||||
'&-menu': {
|
||||
display: 'inline-block',
|
||||
maxWidth: '50vw',
|
||||
height: '192px',
|
||||
listStyle: 'none',
|
||||
margin: 0,
|
||||
padding: theme.spacing(0.5),
|
||||
borderRight: `1px solid ${theme.colors.border.weak}`,
|
||||
overflow: 'auto',
|
||||
|
||||
'&:last-child': {
|
||||
borderRight: 0,
|
||||
},
|
||||
|
||||
'&-item': {
|
||||
height: theme.spacing(4),
|
||||
lineHeight: theme.spacing(4),
|
||||
padding: theme.spacing(0, 4, 0, 2),
|
||||
borderRadius: theme.shape.radius.default,
|
||||
cursor: 'pointer',
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
transition: 'all 0.3s ease',
|
||||
position: 'relative',
|
||||
|
||||
'&:hover': {
|
||||
background: theme.colors.action.hover,
|
||||
},
|
||||
},
|
||||
|
||||
'&-expand': {
|
||||
position: 'relative',
|
||||
'&-disabled': {
|
||||
cursor: 'not-allowed',
|
||||
color: theme.colors.text.disabled,
|
||||
|
||||
'&:after': {
|
||||
'&:hover': {
|
||||
background: 'transparent',
|
||||
},
|
||||
|
||||
'&:after': {
|
||||
position: 'absolute',
|
||||
right: '12px',
|
||||
content: "'loading'",
|
||||
color: theme.colors.text.disabled,
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
|
||||
'&-active': {
|
||||
color: theme.colors.text.maxContrast,
|
||||
background: theme.colors.background.secondary,
|
||||
content: "''",
|
||||
height: theme.spacing(3),
|
||||
mask: 'url(../img/icons/unicons/angle-right.svg)',
|
||||
maskType: 'luminance',
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: theme.spacing(0.5),
|
||||
width: theme.spacing(3),
|
||||
|
||||
'&:hover': {
|
||||
background: theme.colors.action.hover,
|
||||
},
|
||||
},
|
||||
|
||||
'&-expand': {
|
||||
position: 'relative',
|
||||
|
||||
'&:after': {
|
||||
background: theme.colors.text.primary,
|
||||
content: "''",
|
||||
height: theme.spacing(3),
|
||||
mask: `url(${iconPath})`,
|
||||
maskType: 'luminance',
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: theme.spacing(0.5),
|
||||
width: theme.spacing(3),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useStyles2 } from '../../themes/ThemeContext';
|
||||
import { IconName, IconType, IconSize } from '../../types/icon';
|
||||
import { spin } from '../../utils/keyframes';
|
||||
|
||||
import { getIconRoot, getIconSubDir, getSvgSize } from './utils';
|
||||
import { getIconPath, getSvgSize } from './utils';
|
||||
|
||||
export interface IconProps extends Omit<React.SVGProps<SVGElement>, 'onLoad' | 'onError' | 'ref'> {
|
||||
name: IconName;
|
||||
@@ -53,12 +53,10 @@ export const Icon = React.forwardRef<SVGElement, IconProps>(
|
||||
// handle the deprecated 'fa fa-spinner'
|
||||
const iconName: IconName = name === 'fa fa-spinner' ? 'spinner' : name;
|
||||
|
||||
const iconRoot = getIconRoot();
|
||||
const svgSize = getSvgSize(size);
|
||||
const svgHgt = svgSize;
|
||||
const svgWid = name.startsWith('gf-bar-align') ? 16 : name.startsWith('gf-interp') ? 30 : svgSize;
|
||||
const subDir = getIconSubDir(iconName, type);
|
||||
const svgPath = `${iconRoot}${subDir}/${iconName}.svg`;
|
||||
const svgPath = getIconPath(iconName, type);
|
||||
|
||||
const composedClassName = cx(
|
||||
styles.icon,
|
||||
|
||||
@@ -60,3 +60,9 @@ export function getIconRoot(): string {
|
||||
|
||||
return iconRoot;
|
||||
}
|
||||
|
||||
export function getIconPath(name: IconName, type: IconType = 'default'): string {
|
||||
const iconRoot = getIconRoot();
|
||||
const subDir = getIconSubDir(name, type);
|
||||
return `${iconRoot}${subDir}/${name}.svg`;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ export function TableCellActions(props: TableCellActionsProps) {
|
||||
dataProjection: 'EPSG:4326',
|
||||
});
|
||||
mode = TableCellInspectorMode.code;
|
||||
} else if ('cellType' in cellOptions && cellOptions.cellType === TableCellDisplayMode.JSONView) {
|
||||
}
|
||||
if (cellOptions.type === TableCellDisplayMode.JSONView) {
|
||||
mode = TableCellInspectorMode.code;
|
||||
}
|
||||
|
||||
|
||||
@@ -141,6 +141,14 @@ describe('TableNG Cells renderers', () => {
|
||||
expect(container).toBeInTheDocument();
|
||||
expect(container.childNodes).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should return AutoCell when cellOptions is unmapped', () => {
|
||||
const field = createField(FieldType.string);
|
||||
|
||||
const { container } = renderCell(field, { type: 'number' } as unknown as TableCellOptions);
|
||||
expect(container).toBeInTheDocument();
|
||||
expect(container.childNodes).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ export function getCellRenderer(field: Field, cellOptions: TableCellOptions): Ta
|
||||
if (cellType === TableCellDisplayMode.Auto) {
|
||||
return getAutoRendererResult(field);
|
||||
}
|
||||
return CELL_RENDERERS[cellType];
|
||||
return CELL_RENDERERS[cellType] ?? AUTO_RENDERER;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
||||
@@ -81,13 +81,14 @@ export function TableNG(props: TableNGProps) {
|
||||
onSortByChange,
|
||||
showTypeIcons,
|
||||
structureRev,
|
||||
transparent,
|
||||
width,
|
||||
} = props;
|
||||
|
||||
const theme = useTheme2();
|
||||
const styles = useStyles2(getGridStyles, {
|
||||
enablePagination,
|
||||
noHeader,
|
||||
transparent,
|
||||
});
|
||||
const panelContext = usePanelContext();
|
||||
|
||||
@@ -244,21 +245,9 @@ export function TableNG(props: TableNGProps) {
|
||||
},
|
||||
sortColumns,
|
||||
rowHeight,
|
||||
headerRowClass: styles.headerRow,
|
||||
headerRowHeight: headerHeight,
|
||||
bottomSummaryRows: hasFooter ? [{}] : undefined,
|
||||
}) satisfies Partial<DataGridProps<TableRow, TableSummaryRow>>,
|
||||
[
|
||||
enableVirtualization,
|
||||
resizeHandler,
|
||||
sortColumns,
|
||||
headerHeight,
|
||||
styles.headerRow,
|
||||
rowHeight,
|
||||
hasFooter,
|
||||
setSortColumns,
|
||||
onSortByChange,
|
||||
]
|
||||
[enableVirtualization, resizeHandler, sortColumns, rowHeight, hasFooter, setSortColumns, onSortByChange]
|
||||
);
|
||||
|
||||
interface Schema {
|
||||
@@ -437,6 +426,7 @@ export function TableNG(props: TableNGProps) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const hasNestedHeaders = firstNestedData.meta?.custom?.noHeader !== true;
|
||||
const renderRow = renderRowFactory(firstNestedData.fields, panelContext, expandedRows, enableSharedCrosshair);
|
||||
const { columns: nestedColumns, cellRootRenderers: nestedCellRootRenderers } = fromFields(
|
||||
firstNestedData.fields,
|
||||
@@ -486,11 +476,20 @@ export function TableNG(props: TableNGProps) {
|
||||
}
|
||||
|
||||
const expandedRecords = applySort(frameToRecords(nestedData), nestedData.fields, sortColumns);
|
||||
if (!expandedRecords.length) {
|
||||
return (
|
||||
<div className={styles.noDataNested}>
|
||||
<Trans i18nKey="grafana-ui.table.nested-table.no-data">No data</Trans>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<DataGrid<TableRow, TableSummaryRow>
|
||||
{...commonDataGridProps}
|
||||
className={cx(styles.grid, styles.gridNested)}
|
||||
headerRowClass={cx(styles.headerRow, { [styles.displayNone]: !hasNestedHeaders })}
|
||||
headerRowHeight={hasNestedHeaders ? defaultHeaderHeight : 0}
|
||||
columns={nestedColumns}
|
||||
rows={expandedRecords}
|
||||
renderers={{ renderRow, renderCell: renderCellRoot }}
|
||||
@@ -509,6 +508,7 @@ export function TableNG(props: TableNGProps) {
|
||||
crossFilterOrder,
|
||||
crossFilterRows,
|
||||
data,
|
||||
defaultHeaderHeight,
|
||||
defaultRowHeight,
|
||||
enableSharedCrosshair,
|
||||
expandedRows,
|
||||
@@ -552,6 +552,8 @@ export function TableNG(props: TableNGProps) {
|
||||
className={styles.grid}
|
||||
columns={structureRevColumns}
|
||||
rows={paginatedRows}
|
||||
headerRowClass={cx(styles.headerRow, { [styles.displayNone]: noHeader })}
|
||||
headerRowHeight={headerHeight}
|
||||
onCellClick={({ column, row }, { clientX, clientY, preventGridDefault }) => {
|
||||
// Note: could be column.field; JS says yes, but TS says no!
|
||||
const field = columns[column.idx].field;
|
||||
@@ -693,17 +695,20 @@ const renderRowFactory =
|
||||
|
||||
const getGridStyles = (
|
||||
theme: GrafanaTheme2,
|
||||
{ enablePagination, noHeader }: { enablePagination?: boolean; noHeader?: boolean }
|
||||
{ enablePagination, transparent }: { enablePagination?: boolean; transparent?: boolean }
|
||||
) => ({
|
||||
grid: css({
|
||||
'--rdg-background-color': theme.colors.background.primary,
|
||||
'--rdg-header-background-color': theme.colors.background.primary,
|
||||
'--rdg-border-color': theme.isDark ? '#282b30' : '#ebebec',
|
||||
'--rdg-background-color': transparent ? theme.colors.background.canvas : theme.colors.background.primary,
|
||||
'--rdg-header-background-color': transparent ? theme.colors.background.canvas : theme.colors.background.primary,
|
||||
'--rdg-border-color': theme.colors.border.weak,
|
||||
'--rdg-color': theme.colors.text.primary,
|
||||
|
||||
// note: this cannot have any transparency since default cells that
|
||||
// overlay/overflow on hover inherit this background and need to occlude cells below
|
||||
'--rdg-row-hover-background-color': theme.isDark ? '#212428' : '#f4f5f5',
|
||||
'--rdg-row-background-color': transparent ? theme.colors.background.canvas : theme.colors.background.primary,
|
||||
'--rdg-row-hover-background-color': transparent
|
||||
? theme.colors.background.primary
|
||||
: theme.colors.background.secondary,
|
||||
|
||||
// TODO: magic 32px number is unfortunate. it would be better to have the content
|
||||
// flow using flexbox rather than hard-coding this size via a calc
|
||||
@@ -723,15 +728,24 @@ const getGridStyles = (
|
||||
}),
|
||||
gridNested: css({
|
||||
height: '100%',
|
||||
width: `calc(100% - ${COLUMN.EXPANDER_WIDTH - 1}px)`,
|
||||
width: `calc(100% - ${COLUMN.EXPANDER_WIDTH - TABLE.CELL_PADDING * 2 - 1}px)`,
|
||||
overflow: 'visible',
|
||||
marginLeft: COLUMN.EXPANDER_WIDTH - 1,
|
||||
marginLeft: COLUMN.EXPANDER_WIDTH - TABLE.CELL_PADDING - 1,
|
||||
marginBlock: TABLE.CELL_PADDING,
|
||||
}),
|
||||
cellNested: css({
|
||||
'&[aria-selected=true]': {
|
||||
outline: 'none',
|
||||
},
|
||||
}),
|
||||
noDataNested: css({
|
||||
height: TABLE.NESTED_NO_DATA_HEIGHT,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: theme.colors.text.secondary,
|
||||
fontSize: theme.typography.h4.fontSize,
|
||||
}),
|
||||
cellActions: css({
|
||||
display: 'none',
|
||||
position: 'absolute',
|
||||
@@ -739,7 +753,7 @@ const getGridStyles = (
|
||||
margin: 'auto',
|
||||
height: '100%',
|
||||
color: theme.colors.text.primary,
|
||||
background: theme.isDark ? 'rgba(0, 0, 0, 0.3)' : 'rgba(255, 255, 255, 0.7)',
|
||||
background: theme.isDark ? 'rgba(0, 0, 0, 0.7)' : 'rgba(255, 255, 255, 0.7)',
|
||||
padding: theme.spacing.x0_5,
|
||||
paddingInlineStart: theme.spacing.x1,
|
||||
}),
|
||||
@@ -752,12 +766,14 @@ const getGridStyles = (
|
||||
headerRow: css({
|
||||
paddingBlockStart: 0,
|
||||
fontWeight: 'normal',
|
||||
...(noHeader ? { display: 'none' } : {}),
|
||||
'& .rdg-cell': {
|
||||
height: '100%',
|
||||
alignItems: 'flex-end',
|
||||
},
|
||||
}),
|
||||
displayNone: css({
|
||||
display: 'none',
|
||||
}),
|
||||
paginationContainer: css({
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
@@ -835,6 +851,7 @@ const getCellStyles = (
|
||||
whiteSpace: 'pre-line',
|
||||
height: 'fit-content',
|
||||
minWidth: 'fit-content',
|
||||
paddingBlock: (rowHeight - TABLE.LINE_HEIGHT) / 2 - 1,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
|
||||
@@ -14,5 +14,6 @@ export const TABLE = {
|
||||
SCROLL_BAR_WIDTH: 8,
|
||||
SCROLL_BAR_MARGIN: 2,
|
||||
LINE_HEIGHT: 22,
|
||||
NESTED_NO_DATA_HEIGHT: 60,
|
||||
BORDER_RIGHT: 0.666667,
|
||||
};
|
||||
|
||||
@@ -503,9 +503,13 @@ export function useRowHeight({
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Ensure we have a minimum height (defaultHeight) for the nested table even if data is empty
|
||||
const rowCount = row.data?.length ?? 0;
|
||||
return Math.max(defaultHeight, defaultHeight * rowCount + headerHeight);
|
||||
if (rowCount === 0) {
|
||||
return TABLE.NESTED_NO_DATA_HEIGHT + TABLE.CELL_PADDING * 2;
|
||||
}
|
||||
|
||||
const nestedHeaderHeight = row.data?.meta?.custom?.noHeader ? 0 : defaultHeight;
|
||||
return Math.max(defaultHeight, defaultHeight * rowCount + nestedHeaderHeight + TABLE.CELL_PADDING * 2);
|
||||
}
|
||||
|
||||
// regular rows
|
||||
@@ -519,7 +523,6 @@ export function useRowHeight({
|
||||
fields,
|
||||
hasNestedFrames,
|
||||
hasWrappedCols,
|
||||
headerHeight,
|
||||
maxWrapCellOptions,
|
||||
colWidths,
|
||||
]);
|
||||
|
||||
@@ -131,6 +131,7 @@ export interface BaseTableProps {
|
||||
enablePagination?: boolean;
|
||||
cellHeight?: TableCellHeight;
|
||||
structureRev?: number;
|
||||
transparent?: boolean;
|
||||
/** @alpha Used by SparklineCell when provided */
|
||||
timeRange?: TimeRange;
|
||||
enableSharedCrosshair?: boolean;
|
||||
|
||||
@@ -74,7 +74,7 @@ func (hs *HTTPServer) SetHomeDashboard(c *contextmodel.ReqContext) response.Resp
|
||||
func (hs *HTTPServer) GetUserPreferences(c *contextmodel.ReqContext) response.Response {
|
||||
userID, err := identity.UserIdentifier(c.GetID())
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to update user preferences", err)
|
||||
return response.Error(http.StatusUnauthorized, "Not a valid identity", err)
|
||||
}
|
||||
|
||||
return prefapi.GetPreferencesFor(c.Req.Context(), hs.DashboardService, hs.preferenceService, hs.Features, c.GetOrgID(), userID, 0)
|
||||
|
||||
+1
-53
@@ -9,88 +9,36 @@ require (
|
||||
google.golang.org/protobuf v1.36.6
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/apimachinery v0.33.2
|
||||
k8s.io/apiserver v0.33.2
|
||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/cenkalti/backoff/v5 v5.0.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/gnostic-models v0.6.9 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
|
||||
github.com/jonboulle/clockwork v0.5.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.22.2 // indirect
|
||||
github.com/onsi/gomega v1.36.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.22.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.64.0 // indirect
|
||||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.etcd.io/bbolt v1.4.0 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.21 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.21 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.21 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||
go.opentelemetry.io/otel v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.36.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.6.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect
|
||||
golang.org/x/net v0.41.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/term v0.32.0 // indirect
|
||||
golang.org/x/text v0.26.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
golang.org/x/tools v0.34.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
k8s.io/api v0.33.2 // indirect
|
||||
k8s.io/client-go v0.33.2 // indirect
|
||||
k8s.io/component-base v0.33.2 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
|
||||
|
||||
@@ -1,41 +1,11 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
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/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||
github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8=
|
||||
github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
|
||||
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
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/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
@@ -46,156 +16,58 @@ github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF
|
||||
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/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.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
|
||||
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
|
||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250514132646-acbc7b54ed9e h1:BTKk7LHuG1kmAkucwTA7DuMbKpKvJTKrGdBmUNO4dfQ=
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250514132646-acbc7b54ed9e/go.mod h1:IA4SOwun8QyST9c5UNs/fN37XL6boXXDvRYFcFwbipg=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 h1:uGoIog/wiQHI9GAxXO5TJbT0wWKH3O9HhOJW1F9c3fY=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
|
||||
github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
|
||||
github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
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/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/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
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/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
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 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-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
|
||||
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
|
||||
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
|
||||
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
||||
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
||||
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.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.64.0 h1:pdZeA+g617P7oGv1CzdTzyeShxAGrTBsolKNOLQPGO4=
|
||||
github.com/prometheus/common v0.64.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
|
||||
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
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/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 h1:S2dVYn90KE98chqDkyE9Z4N61UnQd+KOfgp5Iu53llk=
|
||||
github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=
|
||||
go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=
|
||||
go.etcd.io/etcd/api/v3 v3.5.21 h1:A6O2/JDb3tvHhiIz3xf9nJ7REHvtEFJJ3veW3FbCnS8=
|
||||
go.etcd.io/etcd/api/v3 v3.5.21/go.mod h1:c3aH5wcvXv/9dqIw2Y810LDXJfhSYdHQ0vxmP3CCHVY=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.21 h1:lPBu71Y7osQmzlflM9OfeIV2JlmpBjqBNlLtcoBqUTc=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.21/go.mod h1:BgqT/IXPjK9NkeSDjbzwsHySX3yIle2+ndz28nVsjUs=
|
||||
go.etcd.io/etcd/client/v2 v2.305.21 h1:eLiFfexc2mE+pTLz9WwnoEsX5JTTpLCYVivKkmVXIRA=
|
||||
go.etcd.io/etcd/client/v2 v2.305.21/go.mod h1:OKkn4hlYNf43hpjEM3Ke3aRdUkhSl8xjKjSf8eCq2J8=
|
||||
go.etcd.io/etcd/client/v3 v3.5.21 h1:T6b1Ow6fNjOLOtM0xSoKNQt1ASPCLWrF9XMHcH9pEyY=
|
||||
go.etcd.io/etcd/client/v3 v3.5.21/go.mod h1:mFYy67IOqmbRf/kRUvsHixzo3iG+1OF2W2+jVIQRAnU=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.21 h1:jUItxeKyrDuVuWhdh0HtjUANwyuzcb7/FAeUfABmQsk=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.21/go.mod h1:wpZx8Egv1g4y+N7JAsqi2zoUiBIUWznLjqJbylDjWgU=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.21 h1:dOmE0mT55dIUsX77TKBLq+RgyumsQuYeiRQnW/ylugk=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.21/go.mod h1:fmcuY5R2SNkklU4+fKVBQi2biVp5vafMrWUEj4TJ4Cs=
|
||||
go.etcd.io/etcd/server/v3 v3.5.21 h1:9w0/k12majtgarGmlMVuhwXRI2ob3/d1Ik3X5TKo0yU=
|
||||
go.etcd.io/etcd/server/v3 v3.5.21/go.mod h1:G1mOzdwuzKT1VRL7SqRchli/qcFrtLBTAQ4lV20sXXo=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
|
||||
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
|
||||
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 h1:JgtbA0xkWHnTmYk7YusopJFX6uleBmAuZ8n05NEh8nQ=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0/go.mod h1:179AK5aar5R3eS9FucPy6rggvU0g52cvKId8pv4+v0c=
|
||||
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
|
||||
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
|
||||
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
|
||||
@@ -204,139 +76,58 @@ go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFw
|
||||
go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
|
||||
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
|
||||
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
|
||||
go.opentelemetry.io/proto/otlp v1.6.0 h1:jQjP+AQyTf+Fe7OKj/MfkDrmK4MNVtw2NpXsf9fefDI=
|
||||
go.opentelemetry.io/proto/otlp v1.6.0/go.mod h1:cicgGehlFuNdgZkcALOCh3VE6K/u2tAjzlRhDwmVpZc=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
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.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
||||
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
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/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-20181201002055-351d144fa1fc/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
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-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-20201020160332-67f06af15bc9/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
|
||||
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
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-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/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-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
|
||||
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
|
||||
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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE=
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 h1:Kog3KlB4xevJlAcbbbzPfRG0+X9fdoGM+UBRKVz6Wr0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237/go.mod h1:ezi0AVyMKDWy5xAncvjLWH7UcLBB5n7y2fQ8MzjJcto=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 h1:cJfm9zPbe1e873mHJzmQ1nwVEeRDU/T1wXDK2kUSU34=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
|
||||
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/api v0.33.2 h1:YgwIS5jKfA+BZg//OQhkJNIfie/kmRsO0BmNaVSimvY=
|
||||
k8s.io/api v0.33.2/go.mod h1:fhrbphQJSM2cXzCWgqU29xLDuks4mu7ti9vveEnpSXs=
|
||||
k8s.io/apimachinery v0.33.2 h1:IHFVhqg59mb8PJWTLi8m1mAoepkUNYmptHsV+Z1m5jY=
|
||||
k8s.io/apimachinery v0.33.2/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
||||
k8s.io/apiserver v0.33.2 h1:KGTRbxn2wJagJowo29kKBp4TchpO1DRO3g+dB/KOJN4=
|
||||
k8s.io/apiserver v0.33.2/go.mod h1:9qday04wEAMLPWWo9AwqCZSiIn3OYSZacDyu/AcoM/M=
|
||||
k8s.io/client-go v0.33.2 h1:z8CIcc0P581x/J1ZYf4CNzRKxRvQAwoAolYPbtQes+E=
|
||||
k8s.io/client-go v0.33.2/go.mod h1:9mCgT4wROvL948w6f6ArJNb7yQd7QsvqavDeZHvNmHo=
|
||||
k8s.io/component-base v0.33.2 h1:sCCsn9s/dG3ZrQTX/Us0/Sx2R0G5kwa0wbZFYoVp/+0=
|
||||
k8s.io/component-base v0.33.2/go.mod h1:/41uw9wKzuelhN+u+/C59ixxf4tYQKW7p32ddkYNe2k=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
|
||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
|
||||
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
|
||||
@@ -4,10 +4,8 @@ import (
|
||||
"fmt"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
)
|
||||
@@ -33,7 +31,6 @@ var SecureValuesResourceInfo = utils.NewResourceInfo(
|
||||
{Name: "Description", Type: "string", Format: "string", Description: "Short description that explains the purpose of this SecureValue"},
|
||||
{Name: "Keeper", Type: "string", Format: "string", Description: "Storage of the secure value"},
|
||||
{Name: "Ref", Type: "string", Format: "string", Description: "If present, the reference to a secret"},
|
||||
{Name: "Status", Type: "string", Format: "string", Description: "The status of the secure value"},
|
||||
},
|
||||
// Decodes the object into a concrete type. Return order in the slice must be the same as in `Definition`.
|
||||
Reader: func(obj any) ([]interface{}, error) {
|
||||
@@ -44,7 +41,6 @@ var SecureValuesResourceInfo = utils.NewResourceInfo(
|
||||
r.Spec.Description,
|
||||
r.Spec.Keeper,
|
||||
r.Spec.Ref,
|
||||
r.Status.Phase,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -92,13 +88,6 @@ var (
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the status phase to the selectable fields, besides the generic metadata name and namespace.
|
||||
func SelectableSecureValueFields(obj *SecureValue) fields.Set {
|
||||
return generic.MergeFieldsSets(generic.ObjectMetaFieldsSet(&obj.ObjectMeta, false), fields.Set{
|
||||
"status.phase": string(obj.Status.Phase),
|
||||
})
|
||||
}
|
||||
|
||||
// Adds the list of known types to the given scheme.
|
||||
func AddKnownTypes(scheme *runtime.Scheme, version string) error {
|
||||
// TODO: do we need a type for the secure value decrypt?
|
||||
@@ -112,20 +101,5 @@ func AddKnownTypes(scheme *runtime.Scheme, version string) error {
|
||||
// &secretV0.SecureValueActivityList{},
|
||||
)
|
||||
|
||||
err := scheme.AddFieldLabelConversionFunc(
|
||||
SecureValuesResourceInfo.GroupVersionKind(),
|
||||
func(label, value string) (string, string, error) {
|
||||
fieldSet := SelectableSecureValueFields(&SecureValue{})
|
||||
for key := range fieldSet {
|
||||
if label == key {
|
||||
return label, value, nil
|
||||
}
|
||||
}
|
||||
return "", "", fmt.Errorf("field label not supported for %s: %s", SecureValuesResourceInfo.GroupVersionKind(), label)
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -11,41 +11,18 @@ type SecureValue struct {
|
||||
// Standard object's metadata. It can only be one of `metav1.ObjectMeta` or `metav1.ListMeta`.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
metav1.ObjectMeta `json:"metadata"`
|
||||
|
||||
// This is the actual secure value schema.
|
||||
Spec SecureValueSpec `json:"spec"`
|
||||
|
||||
// Read-only observed status of the `SecureValue`.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||
Status SecureValueStatus `json:"status,omitempty"`
|
||||
Status SecureValueStatus `json:"status"`
|
||||
}
|
||||
|
||||
// +enum
|
||||
type SecureValuePhase string
|
||||
|
||||
const (
|
||||
// When the `SecureValue` is created, it will start in `Pending` phase to create the underlying secret asynchronously.
|
||||
SecureValuePhasePending SecureValuePhase = "Pending"
|
||||
|
||||
// If the creation of the secret is successful, it will move to the `Succeeded` phase.
|
||||
SecureValuePhaseSucceeded SecureValuePhase = "Succeeded"
|
||||
|
||||
// If the creation of the secret fails, it will move to the `Failed` phase.
|
||||
// Check the additional `status` fields for more information on what caused the failure.
|
||||
// This state is unrecoverable.
|
||||
SecureValuePhaseFailed SecureValuePhase = "Failed"
|
||||
)
|
||||
|
||||
type SecureValueStatus struct {
|
||||
// High-level summary of where the `SecureValue` is in its lifecycle.
|
||||
// One of: `Pending`, `Succeeded` or `Failed`.
|
||||
Phase SecureValuePhase `json:"phase"`
|
||||
|
||||
// A human readable message indicating details about why the `SecureValue` is in this phase.
|
||||
// Only applicable if the `phase=Failed`.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
Version int64 `json:"version"`
|
||||
|
||||
// +optional
|
||||
ExternalID string `json:"externalId,omitempty"`
|
||||
@@ -94,7 +71,7 @@ type SecureValueList struct {
|
||||
// Standard list's metadata. It can only be one of `metav1.ObjectMeta` or `metav1.ListMeta`.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
|
||||
// Slice containing all secure values. This will NOT output decrypted values.
|
||||
Items []SecureValue `json:"items"`
|
||||
|
||||
@@ -598,7 +598,7 @@ func schema_pkg_apis_secret_v0alpha1_SecureValue(ref common.ReferenceCallback) c
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"spec"},
|
||||
Required: []string{"spec", "status"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
@@ -734,20 +734,11 @@ func schema_pkg_apis_secret_v0alpha1_SecureValueStatus(ref common.ReferenceCallb
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"phase": {
|
||||
"version": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "High-level summary of where the `SecureValue` is in its lifecycle. One of: `Pending`, `Succeeded` or `Failed`.\n\nPossible enum values:\n - `\"Failed\"` If the creation of the secret fails, it will move to the `Failed` phase. Check the additional `status` fields for more information on what caused the failure. This state is unrecoverable.\n - `\"Pending\"` When the `SecureValue` is created, it will start in `Pending` phase to create the underlying secret asynchronously.\n - `\"Succeeded\"` If the creation of the secret is successful, it will move to the `Succeeded` phase.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
Enum: []interface{}{"Failed", "Pending", "Succeeded"},
|
||||
},
|
||||
},
|
||||
"message": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "A human readable message indicating details about why the `SecureValue` is in this phase. Only applicable if the `phase=Failed`.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
Default: 0,
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"externalId": {
|
||||
@@ -757,7 +748,7 @@ func schema_pkg_apis_secret_v0alpha1_SecureValueStatus(ref common.ReferenceCallb
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"phase"},
|
||||
Required: []string{"version"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -6,3 +6,4 @@ API rule violation: names_match,github.com/grafana/grafana/pkg/apis/secret/v0alp
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/secret/v0alpha1,KeeperSpec,Azure
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/secret/v0alpha1,KeeperSpec,HashiCorp
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/secret/v0alpha1,SecureValueStatus,ExternalID
|
||||
API rule violation: streaming_list_type_json_tags,github.com/grafana/grafana/pkg/apis/secret/v0alpha1,SecureValueList,ListMeta
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.10.6. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package filestorage
|
||||
|
||||
@@ -17,6 +17,10 @@ type MockFileStorage struct {
|
||||
func (_m *MockFileStorage) CreateFolder(ctx context.Context, path string) error {
|
||||
ret := _m.Called(ctx, path)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for CreateFolder")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
|
||||
r0 = rf(ctx, path)
|
||||
@@ -31,6 +35,10 @@ func (_m *MockFileStorage) CreateFolder(ctx context.Context, path string) error
|
||||
func (_m *MockFileStorage) Delete(ctx context.Context, path string) error {
|
||||
ret := _m.Called(ctx, path)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Delete")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
|
||||
r0 = rf(ctx, path)
|
||||
@@ -45,6 +53,10 @@ func (_m *MockFileStorage) Delete(ctx context.Context, path string) error {
|
||||
func (_m *MockFileStorage) DeleteFolder(ctx context.Context, path string, options *DeleteFolderOptions) error {
|
||||
ret := _m.Called(ctx, path, options)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DeleteFolder")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, *DeleteFolderOptions) error); ok {
|
||||
r0 = rf(ctx, path, options)
|
||||
@@ -59,7 +71,16 @@ func (_m *MockFileStorage) DeleteFolder(ctx context.Context, path string, option
|
||||
func (_m *MockFileStorage) Get(ctx context.Context, path string, options *GetFileOptions) (*File, bool, error) {
|
||||
ret := _m.Called(ctx, path, options)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Get")
|
||||
}
|
||||
|
||||
var r0 *File
|
||||
var r1 bool
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, *GetFileOptions) (*File, bool, error)); ok {
|
||||
return rf(ctx, path, options)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, *GetFileOptions) *File); ok {
|
||||
r0 = rf(ctx, path, options)
|
||||
} else {
|
||||
@@ -68,14 +89,12 @@ func (_m *MockFileStorage) Get(ctx context.Context, path string, options *GetFil
|
||||
}
|
||||
}
|
||||
|
||||
var r1 bool
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, *GetFileOptions) bool); ok {
|
||||
r1 = rf(ctx, path, options)
|
||||
} else {
|
||||
r1 = ret.Get(1).(bool)
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(context.Context, string, *GetFileOptions) error); ok {
|
||||
r2 = rf(ctx, path, options)
|
||||
} else {
|
||||
@@ -89,7 +108,15 @@ func (_m *MockFileStorage) Get(ctx context.Context, path string, options *GetFil
|
||||
func (_m *MockFileStorage) List(ctx context.Context, folderPath string, paging *Paging, options *ListOptions) (*ListResponse, error) {
|
||||
ret := _m.Called(ctx, folderPath, paging, options)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for List")
|
||||
}
|
||||
|
||||
var r0 *ListResponse
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, *Paging, *ListOptions) (*ListResponse, error)); ok {
|
||||
return rf(ctx, folderPath, paging, options)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, *Paging, *ListOptions) *ListResponse); ok {
|
||||
r0 = rf(ctx, folderPath, paging, options)
|
||||
} else {
|
||||
@@ -98,7 +125,6 @@ func (_m *MockFileStorage) List(ctx context.Context, folderPath string, paging *
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, *Paging, *ListOptions) error); ok {
|
||||
r1 = rf(ctx, folderPath, paging, options)
|
||||
} else {
|
||||
@@ -112,6 +138,10 @@ func (_m *MockFileStorage) List(ctx context.Context, folderPath string, paging *
|
||||
func (_m *MockFileStorage) Upsert(ctx context.Context, command *UpsertFileCommand) error {
|
||||
ret := _m.Called(ctx, command)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Upsert")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *UpsertFileCommand) error); ok {
|
||||
r0 = rf(ctx, command)
|
||||
@@ -122,10 +152,14 @@ func (_m *MockFileStorage) Upsert(ctx context.Context, command *UpsertFileComman
|
||||
return r0
|
||||
}
|
||||
|
||||
// close provides a mock function with given fields:
|
||||
// close provides a mock function with no fields
|
||||
func (_m *MockFileStorage) close() error {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for close")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func() error); ok {
|
||||
r0 = rf()
|
||||
@@ -135,3 +169,17 @@ func (_m *MockFileStorage) close() error {
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// NewMockFileStorage creates a new instance of MockFileStorage. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewMockFileStorage(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *MockFileStorage {
|
||||
mock := &MockFileStorage{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func TestIntegrationSocialService_ProvideService(t *testing.T) {
|
||||
expectedGenericOAuthSkipOrgRoleSync bool
|
||||
}{
|
||||
{
|
||||
name: "should load all social connectors when ssoSettingsApi is enabled",
|
||||
name: "should load all social connectors",
|
||||
expectedSocialMapLength: 7,
|
||||
expectedGenericOAuthSkipOrgRoleSync: false,
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.27.1. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package socialtest
|
||||
|
||||
@@ -31,6 +31,10 @@ func (_m *MockSocialConnector) AuthCodeURL(state string, opts ...oauth2.AuthCode
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for AuthCodeURL")
|
||||
}
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func(string, ...oauth2.AuthCodeOption) string); ok {
|
||||
r0 = rf(state, opts...)
|
||||
@@ -45,6 +49,10 @@ func (_m *MockSocialConnector) AuthCodeURL(state string, opts ...oauth2.AuthCode
|
||||
func (_m *MockSocialConnector) Client(ctx context.Context, t *oauth2.Token) *http.Client {
|
||||
ret := _m.Called(ctx, t)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Client")
|
||||
}
|
||||
|
||||
var r0 *http.Client
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *oauth2.Token) *http.Client); ok {
|
||||
r0 = rf(ctx, t)
|
||||
@@ -68,6 +76,10 @@ func (_m *MockSocialConnector) Exchange(ctx context.Context, code string, authOp
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Exchange")
|
||||
}
|
||||
|
||||
var r0 *oauth2.Token
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, ...oauth2.AuthCodeOption) (*oauth2.Token, error)); ok {
|
||||
@@ -90,10 +102,14 @@ func (_m *MockSocialConnector) Exchange(ctx context.Context, code string, authOp
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetOAuthInfo provides a mock function with given fields:
|
||||
// GetOAuthInfo provides a mock function with no fields
|
||||
func (_m *MockSocialConnector) GetOAuthInfo() *social.OAuthInfo {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetOAuthInfo")
|
||||
}
|
||||
|
||||
var r0 *social.OAuthInfo
|
||||
if rf, ok := ret.Get(0).(func() *social.OAuthInfo); ok {
|
||||
r0 = rf()
|
||||
@@ -110,6 +126,10 @@ func (_m *MockSocialConnector) GetOAuthInfo() *social.OAuthInfo {
|
||||
func (_m *MockSocialConnector) IsEmailAllowed(email string) bool {
|
||||
ret := _m.Called(email)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for IsEmailAllowed")
|
||||
}
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func(string) bool); ok {
|
||||
r0 = rf(email)
|
||||
@@ -120,10 +140,14 @@ func (_m *MockSocialConnector) IsEmailAllowed(email string) bool {
|
||||
return r0
|
||||
}
|
||||
|
||||
// IsSignupAllowed provides a mock function with given fields:
|
||||
// IsSignupAllowed provides a mock function with no fields
|
||||
func (_m *MockSocialConnector) IsSignupAllowed() bool {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for IsSignupAllowed")
|
||||
}
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func() bool); ok {
|
||||
r0 = rf()
|
||||
@@ -138,6 +162,10 @@ func (_m *MockSocialConnector) IsSignupAllowed() bool {
|
||||
func (_m *MockSocialConnector) SupportBundleContent(_a0 *bytes.Buffer) error {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SupportBundleContent")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(*bytes.Buffer) error); ok {
|
||||
r0 = rf(_a0)
|
||||
@@ -152,6 +180,10 @@ func (_m *MockSocialConnector) SupportBundleContent(_a0 *bytes.Buffer) error {
|
||||
func (_m *MockSocialConnector) TokenSource(ctx context.Context, t *oauth2.Token) oauth2.TokenSource {
|
||||
ret := _m.Called(ctx, t)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for TokenSource")
|
||||
}
|
||||
|
||||
var r0 oauth2.TokenSource
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *oauth2.Token) oauth2.TokenSource); ok {
|
||||
r0 = rf(ctx, t)
|
||||
@@ -168,6 +200,10 @@ func (_m *MockSocialConnector) TokenSource(ctx context.Context, t *oauth2.Token)
|
||||
func (_m *MockSocialConnector) UserInfo(ctx context.Context, client *http.Client, token *oauth2.Token) (*social.BasicUserInfo, error) {
|
||||
ret := _m.Called(ctx, client, token)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for UserInfo")
|
||||
}
|
||||
|
||||
var r0 *social.BasicUserInfo
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *http.Client, *oauth2.Token) (*social.BasicUserInfo, error)); ok {
|
||||
@@ -190,13 +226,12 @@ func (_m *MockSocialConnector) UserInfo(ctx context.Context, client *http.Client
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewMockSocialConnector interface {
|
||||
// NewMockSocialConnector creates a new instance of MockSocialConnector. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewMockSocialConnector(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewMockSocialConnector creates a new instance of MockSocialConnector. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewMockSocialConnector(t mockConstructorTestingTNewMockSocialConnector) *MockSocialConnector {
|
||||
}) *MockSocialConnector {
|
||||
mock := &MockSocialConnector{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
|
||||
@@ -46,10 +46,6 @@ func DefaultService(cfg *config.PluginManagementCfg) *Service {
|
||||
|
||||
// Base returns the base path for the specified plugin.
|
||||
func (s *Service) Base(n PluginInfo) (string, error) {
|
||||
if n.class == plugins.ClassCore {
|
||||
baseDir := getBaseDir(n.fs.Base())
|
||||
return path.Join("public/app/plugins", string(n.pluginJSON.Type), baseDir), nil
|
||||
}
|
||||
if n.class == plugins.ClassCDN {
|
||||
return n.fs.Base(), nil
|
||||
}
|
||||
@@ -64,7 +60,6 @@ func (s *Service) Base(n PluginInfo) (string, error) {
|
||||
if s.cdn.PluginSupported(n.parent.pluginJSON.ID) {
|
||||
return s.cdn.AssetURL(n.parent.pluginJSON.ID, n.parent.pluginJSON.Info.Version, relPath)
|
||||
}
|
||||
return path.Join("public/plugins", n.parent.pluginJSON.ID, relPath), nil
|
||||
}
|
||||
|
||||
return path.Join("public/plugins", n.pluginJSON.ID), nil
|
||||
@@ -73,32 +68,12 @@ func (s *Service) Base(n PluginInfo) (string, error) {
|
||||
// Module returns the module.js path for the specified plugin.
|
||||
func (s *Service) Module(n PluginInfo) (string, error) {
|
||||
if n.class == plugins.ClassCore {
|
||||
if filepath.Base(n.fs.Base()) == "dist" {
|
||||
// The core plugin has been built externally, use the module from the dist folder
|
||||
} else {
|
||||
baseDir := getBaseDir(n.fs.Base())
|
||||
return path.Join("core:plugin", baseDir), nil
|
||||
if filepath.Base(n.fs.Base()) != "dist" {
|
||||
return path.Join("core:plugin", filepath.Base(n.fs.Base())), nil
|
||||
}
|
||||
}
|
||||
if n.class == plugins.ClassCDN {
|
||||
return pluginscdn.JoinPath(n.fs.Base(), "module.js")
|
||||
}
|
||||
|
||||
if s.cdn.PluginSupported(n.pluginJSON.ID) {
|
||||
return s.cdn.AssetURL(n.pluginJSON.ID, n.pluginJSON.Info.Version, "module.js")
|
||||
}
|
||||
if n.parent != nil {
|
||||
relPath, err := n.parent.fs.Rel(n.fs.Base())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if s.cdn.PluginSupported(n.parent.pluginJSON.ID) {
|
||||
return s.cdn.AssetURL(n.parent.pluginJSON.ID, n.parent.pluginJSON.Info.Version, path.Join(relPath, "module.js"))
|
||||
}
|
||||
return path.Join("public/plugins", n.parent.pluginJSON.ID, relPath, "module.js"), nil
|
||||
}
|
||||
|
||||
return path.Join("public/plugins", n.pluginJSON.ID, "module.js"), nil
|
||||
return s.RelativeURL(n, "module.js")
|
||||
}
|
||||
|
||||
// RelativeURL returns the relative URL for an arbitrary plugin asset.
|
||||
@@ -145,15 +120,6 @@ func (s *Service) DefaultLogoPath(pluginType plugins.Type) string {
|
||||
return path.Join("public/img", fmt.Sprintf("icn-%s.svg", string(pluginType)))
|
||||
}
|
||||
|
||||
func getBaseDir(pluginDir string) string {
|
||||
baseDir := filepath.Base(pluginDir)
|
||||
// Decoupled core plugins will be suffixed with "dist" if they have been built
|
||||
if baseDir == "dist" {
|
||||
return filepath.Base(strings.TrimSuffix(pluginDir, baseDir))
|
||||
}
|
||||
return baseDir
|
||||
}
|
||||
|
||||
func (s *Service) GetTranslations(n PluginInfo) (map[string]string, error) {
|
||||
pathToTranslations, err := s.RelativeURL(n, "locales")
|
||||
if err != nil {
|
||||
|
||||
@@ -78,7 +78,7 @@ func TestService(t *testing.T) {
|
||||
|
||||
base, err = svc.Base(NewPluginInfo(jsonData["table-old"], plugins.ClassCore, tableOldFS, nil))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "public/app/plugins/table-old", base)
|
||||
require.Equal(t, "public/plugins/table-old", base)
|
||||
|
||||
parentFS := pluginFS(oneCDNURL)
|
||||
parentFS.RelFunc = func(_ string) (string, error) {
|
||||
@@ -243,9 +243,9 @@ func TestService_ChildPlugins(t *testing.T) {
|
||||
return childInfo
|
||||
},
|
||||
expected: expected{
|
||||
module: "public/plugins/parent/child/module.js",
|
||||
baseURL: "public/plugins/parent/child",
|
||||
relURL: "public/plugins/parent/child/path/to/file.txt",
|
||||
module: "public/plugins/child/module.js",
|
||||
baseURL: "public/plugins/child",
|
||||
relURL: "public/plugins/child/path/to/file.txt",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -256,8 +256,8 @@ func TestService_ChildPlugins(t *testing.T) {
|
||||
},
|
||||
expected: expected{
|
||||
module: "core:plugin/parent",
|
||||
baseURL: "public/app/plugins/parent",
|
||||
relURL: "public/app/plugins/parent/path/to/file.txt",
|
||||
baseURL: "public/plugins/parent",
|
||||
relURL: "public/plugins/parent/path/to/file.txt",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -268,8 +268,8 @@ func TestService_ChildPlugins(t *testing.T) {
|
||||
},
|
||||
expected: expected{
|
||||
module: "public/plugins/parent/module.js",
|
||||
baseURL: "public/app/plugins/parent",
|
||||
relURL: "public/app/plugins/parent/path/to/file.txt",
|
||||
baseURL: "public/plugins/parent",
|
||||
relURL: "public/plugins/parent/path/to/file.txt",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -85,8 +85,8 @@ func TestLoader_Load(t *testing.T) {
|
||||
Description: "Data source for Amazon AWS monitoring service",
|
||||
Keywords: []string{"aws", "amazon"},
|
||||
Logos: plugins.Logos{
|
||||
Small: "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
|
||||
Large: "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
|
||||
Small: "public/plugins/cloudwatch/img/amazon-web-services.png",
|
||||
Large: "public/plugins/cloudwatch/img/amazon-web-services.png",
|
||||
},
|
||||
Links: []plugins.InfoLink{
|
||||
{Name: "Raise issue", URL: "https://github.com/grafana/grafana/issues/new"},
|
||||
@@ -123,7 +123,7 @@ func TestLoader_Load(t *testing.T) {
|
||||
QueryOptions: map[string]bool{"minInterval": true},
|
||||
},
|
||||
Module: "core:plugin/cloudwatch",
|
||||
BaseURL: "public/app/plugins/datasource/cloudwatch",
|
||||
BaseURL: "public/plugins/cloudwatch",
|
||||
FS: mustNewStaticFSForTests(t, filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch")),
|
||||
Signature: plugins.SignatureStatusInternal,
|
||||
Class: plugins.ClassCore,
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package legacy
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
|
||||
resourcepb "github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ func (b *FolderAPIBuilder) Mutate(ctx context.Context, a admission.Attributes, _
|
||||
if !ok {
|
||||
return fmt.Errorf("obj is not folders.Folder")
|
||||
}
|
||||
f.Spec.Title = strings.Trim(f.Spec.Title, "")
|
||||
f.Spec.Title = strings.Trim(f.Spec.Title, " ")
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -479,7 +479,7 @@ func TestFolderAPIBuilder_Mutate_Create(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := b.Validate(context.Background(), admission.NewAttributesRecord(
|
||||
admAttr := admission.NewAttributesRecord(
|
||||
tt.input,
|
||||
nil,
|
||||
folders.SchemeGroupVersion.WithKind("folder"),
|
||||
@@ -491,13 +491,18 @@ func TestFolderAPIBuilder_Mutate_Create(t *testing.T) {
|
||||
nil,
|
||||
true,
|
||||
&user.SignedInUser{},
|
||||
), nil)
|
||||
)
|
||||
|
||||
err := b.Validate(context.Background(), admAttr, nil)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
err = b.Mutate(context.Background(), admAttr, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.input, tt.expected)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -585,7 +590,7 @@ func TestFolderAPIBuilder_Mutate_Update(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := b.Validate(context.Background(), admission.NewAttributesRecord(
|
||||
admAttr := admission.NewAttributesRecord(
|
||||
tt.input,
|
||||
existingObj,
|
||||
folders.SchemeGroupVersion.WithKind("folder"),
|
||||
@@ -597,13 +602,18 @@ func TestFolderAPIBuilder_Mutate_Update(t *testing.T) {
|
||||
nil,
|
||||
true,
|
||||
&user.SignedInUser{},
|
||||
), nil)
|
||||
)
|
||||
|
||||
err := b.Validate(context.Background(), admAttr, nil)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
err = b.Mutate(context.Background(), admAttr, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.input, tt.expected)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package export
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package export
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package jobs
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package jobs
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package migrate
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
resourcepb "github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
)
|
||||
|
||||
// MockBulkStoreClient is an autogenerated mock type for the BulkStoreClient type
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package migrate
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package migrate
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package jobs
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package jobs
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package jobs
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package jobs
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package sync
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package sync
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package sync
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package sync
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package sync
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package jobs
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package repository
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package repository
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package repository
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package repository
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package repository
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package github
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package github
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package github
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package repository
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package gogit
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package gogit
|
||||
|
||||
|
||||
@@ -595,7 +595,7 @@ func (r *gitRepository) resolveRefToHash(ctx context.Context, ref string) (hash.
|
||||
|
||||
// Try to parse ref as a hash first
|
||||
refHash, err := hash.FromHex(ref)
|
||||
if err == nil && refHash != nil {
|
||||
if err == nil && refHash != hash.Zero {
|
||||
// Valid hash, return it
|
||||
return refHash, nil
|
||||
}
|
||||
@@ -604,9 +604,9 @@ func (r *gitRepository) resolveRefToHash(ctx context.Context, ref string) (hash.
|
||||
branchRef, err := r.client.GetRef(ctx, ref)
|
||||
if err != nil {
|
||||
if errors.Is(err, nanogit.ErrObjectNotFound) {
|
||||
return nil, fmt.Errorf("ref not found: %s: %w", ref, repository.ErrRefNotFound)
|
||||
return hash.Zero, fmt.Errorf("ref not found: %s: %w", ref, repository.ErrRefNotFound)
|
||||
}
|
||||
return nil, fmt.Errorf("get ref %s: %w", ref, err)
|
||||
return hash.Zero, fmt.Errorf("get ref %s: %w", ref, err)
|
||||
}
|
||||
|
||||
return branchRef.Hash, nil
|
||||
|
||||
@@ -695,7 +695,7 @@ func TestGitRepository_Read(t *testing.T) {
|
||||
Hash: hash.Hash{},
|
||||
}, nil)
|
||||
mockClient.GetCommitReturns(&nanogit.Commit{
|
||||
Tree: hash.Hash([]byte("tree-hash")),
|
||||
Tree: hash.MustFromHex("abcdef1234567890abcdef1234567890abcdef12"),
|
||||
}, nil)
|
||||
mockClient.GetTreeByPathReturns(&nanogit.Tree{
|
||||
Hash: hash.Hash{},
|
||||
@@ -1191,7 +1191,7 @@ func TestGitRepository_LatestRef(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3}, // Non-empty hash
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, // Non-empty hash
|
||||
}, nil)
|
||||
},
|
||||
gitConfig: RepositoryConfig{
|
||||
@@ -1412,11 +1412,11 @@ func TestGitRepository_CompareFiles(t *testing.T) {
|
||||
// Return refs for base and ref
|
||||
mockClient.GetRefReturnsOnCall(0, nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
mockClient.GetRefReturnsOnCall(1, nanogit.Ref{
|
||||
Name: "refs/heads/feature",
|
||||
Hash: hash.Hash{4, 5, 6},
|
||||
Hash: hash.Hash{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
|
||||
}, nil)
|
||||
|
||||
// Return comparison results
|
||||
@@ -1449,11 +1449,11 @@ func TestGitRepository_CompareFiles(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturnsOnCall(0, nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
mockClient.GetRefReturnsOnCall(1, nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
|
||||
mockClient.CompareCommitsReturns([]nanogit.CommitFile{}, nil)
|
||||
@@ -1547,7 +1547,7 @@ func TestGitRepository_ensureBranchExists(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/feature",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
},
|
||||
gitConfig: RepositoryConfig{
|
||||
@@ -1565,7 +1565,7 @@ func TestGitRepository_ensureBranchExists(t *testing.T) {
|
||||
// Second call - get source branch
|
||||
mockClient.GetRefReturnsOnCall(1, nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
// CreateRef succeeds
|
||||
mockClient.CreateRefReturns(nil)
|
||||
@@ -1862,7 +1862,7 @@ func TestGitRepository_resolveRefToHash(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
},
|
||||
gitConfig: RepositoryConfig{
|
||||
@@ -1887,7 +1887,7 @@ func TestGitRepository_resolveRefToHash(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/feature",
|
||||
Hash: hash.Hash{4, 5, 6},
|
||||
Hash: hash.Hash{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
|
||||
}, nil)
|
||||
},
|
||||
gitConfig: RepositoryConfig{
|
||||
@@ -1939,7 +1939,7 @@ func TestGitRepository_resolveRefToHash(t *testing.T) {
|
||||
|
||||
if tt.wantError {
|
||||
require.Error(t, err)
|
||||
require.Nil(t, refHash)
|
||||
require.Equal(t, hash.Zero, refHash)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, refHash)
|
||||
@@ -2212,7 +2212,7 @@ func TestGitRepository_EdgeCases(t *testing.T) {
|
||||
mockClient := &mocks.FakeClient{}
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
|
||||
mockWriter := &mocks.FakeStagedWriter{}
|
||||
@@ -2251,7 +2251,7 @@ func TestGitRepository_EdgeCases(t *testing.T) {
|
||||
mockClient := &mocks.FakeClient{}
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
mockClient.GetCommitReturns(&nanogit.Commit{Tree: hash.Hash{}}, nil)
|
||||
mockClient.GetBlobByPathReturns(&nanogit.Blob{}, errors.New("some read error"))
|
||||
@@ -2401,7 +2401,7 @@ func TestGitRepository_ResolveRefToHash_EdgeCases(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/invalid-hex",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
},
|
||||
ref: "invalid-hex-zzz",
|
||||
@@ -2412,7 +2412,7 @@ func TestGitRepository_ResolveRefToHash_EdgeCases(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/feature",
|
||||
Hash: hash.Hash{4, 5, 6},
|
||||
Hash: hash.Hash{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
|
||||
}, nil)
|
||||
},
|
||||
ref: "refs/heads/feature",
|
||||
@@ -2423,7 +2423,7 @@ func TestGitRepository_ResolveRefToHash_EdgeCases(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/tags/v1.0.0",
|
||||
Hash: hash.Hash{7, 8, 9},
|
||||
Hash: hash.Hash{7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26},
|
||||
}, nil)
|
||||
},
|
||||
ref: "refs/tags/v1.0.0",
|
||||
@@ -2540,11 +2540,11 @@ func TestGitRepository_CompareFiles_EdgeCases(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturnsOnCall(0, nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
mockClient.GetRefReturnsOnCall(1, nanogit.Ref{
|
||||
Name: "refs/heads/feature",
|
||||
Hash: hash.Hash{4, 5, 6},
|
||||
Hash: hash.Hash{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
|
||||
}, nil)
|
||||
mockClient.CompareCommitsReturns(nil, errors.New("compare error"))
|
||||
},
|
||||
@@ -2558,11 +2558,11 @@ func TestGitRepository_CompareFiles_EdgeCases(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturnsOnCall(0, nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
mockClient.GetRefReturnsOnCall(1, nanogit.Ref{
|
||||
Name: "refs/heads/feature",
|
||||
Hash: hash.Hash{4, 5, 6},
|
||||
Hash: hash.Hash{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
|
||||
}, nil)
|
||||
mockClient.CompareCommitsReturns([]nanogit.CommitFile{
|
||||
{
|
||||
@@ -2580,11 +2580,11 @@ func TestGitRepository_CompareFiles_EdgeCases(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturnsOnCall(0, nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
mockClient.GetRefReturnsOnCall(1, nanogit.Ref{
|
||||
Name: "refs/heads/feature",
|
||||
Hash: hash.Hash{4, 5, 6},
|
||||
Hash: hash.Hash{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
|
||||
}, nil)
|
||||
mockClient.CompareCommitsReturns([]nanogit.CommitFile{
|
||||
{
|
||||
@@ -2606,11 +2606,11 @@ func TestGitRepository_CompareFiles_EdgeCases(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturnsOnCall(0, nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
mockClient.GetRefReturnsOnCall(1, nanogit.Ref{
|
||||
Name: "refs/heads/feature",
|
||||
Hash: hash.Hash{4, 5, 6},
|
||||
Hash: hash.Hash{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
|
||||
}, nil)
|
||||
mockClient.CompareCommitsReturns([]nanogit.CommitFile{
|
||||
{
|
||||
@@ -2683,7 +2683,7 @@ func TestGitRepository_ReadTree_EdgeCases(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
mockClient.GetFlatTreeReturns(nil, errors.New("flat tree error"))
|
||||
},
|
||||
@@ -2694,23 +2694,23 @@ func TestGitRepository_ReadTree_EdgeCases(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
mockClient.GetFlatTreeReturns(&nanogit.FlatTree{
|
||||
Entries: []nanogit.FlatTreeEntry{
|
||||
{
|
||||
Path: "other/file.yaml", // Outside configs/
|
||||
Hash: hash.Hash{4, 5, 6},
|
||||
Hash: hash.Hash{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
|
||||
Type: protocol.ObjectTypeBlob,
|
||||
},
|
||||
{
|
||||
Path: "configs/included.yaml", // Inside configs/
|
||||
Hash: hash.Hash{7, 8, 9},
|
||||
Hash: hash.Hash{7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26},
|
||||
Type: protocol.ObjectTypeBlob,
|
||||
},
|
||||
{
|
||||
Path: "configs/dir", // Directory without trailing slash
|
||||
Hash: hash.Hash{10, 11, 12},
|
||||
Hash: hash.Hash{10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
|
||||
Type: protocol.ObjectTypeTree,
|
||||
},
|
||||
},
|
||||
@@ -2828,7 +2828,7 @@ func TestGitRepository_ensureBranchExists_ErrorConditions(t *testing.T) {
|
||||
// Second call - get source branch
|
||||
mockClient.GetRefReturnsOnCall(1, nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
// CreateRef fails
|
||||
mockClient.CreateRefReturns(errors.New("create ref failed"))
|
||||
@@ -2880,10 +2880,10 @@ func TestGitRepository_Read_EdgeCases(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121315"),
|
||||
}, nil)
|
||||
mockClient.GetCommitReturns(&nanogit.Commit{
|
||||
Tree: hash.Hash([]byte("tree-hash")),
|
||||
Tree: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.GetTreeByPathReturns(nil, errors.New("tree error"))
|
||||
},
|
||||
@@ -2895,7 +2895,7 @@ func TestGitRepository_Read_EdgeCases(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.GetCommitReturns(nil, errors.New("commit error"))
|
||||
},
|
||||
@@ -2907,10 +2907,10 @@ func TestGitRepository_Read_EdgeCases(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.GetCommitReturns(&nanogit.Commit{
|
||||
Tree: hash.Hash{4, 5, 6},
|
||||
Hash: hash.MustFromHex("0102030405060708092a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.GetBlobByPathReturns(nil, errors.New("blob error"))
|
||||
},
|
||||
@@ -2965,7 +2965,7 @@ func TestGitRepository_Create_ErrorConditions(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
mockClient.NewStagedWriterReturns(nil, errors.New("staged writer error"))
|
||||
},
|
||||
@@ -2977,7 +2977,7 @@ func TestGitRepository_Create_ErrorConditions(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockWriter := &mocks.FakeStagedWriter{}
|
||||
mockWriter.CreateBlobReturns(hash.Hash{}, errors.New("create blob error"))
|
||||
@@ -3030,7 +3030,7 @@ func TestGitRepository_Update_ErrorConditions(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.Hash{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
|
||||
}, nil)
|
||||
mockClient.NewStagedWriterReturns(nil, errors.New("staged writer error"))
|
||||
},
|
||||
@@ -3042,7 +3042,7 @@ func TestGitRepository_Update_ErrorConditions(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockWriter := &mocks.FakeStagedWriter{}
|
||||
mockWriter.UpdateBlobReturns(hash.Hash{}, errors.New("update blob error"))
|
||||
@@ -3096,7 +3096,7 @@ func TestGitRepository_Delete_ErrorConditions(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.NewStagedWriterReturns(nil, errors.New("staged writer error"))
|
||||
},
|
||||
@@ -3109,7 +3109,7 @@ func TestGitRepository_Delete_ErrorConditions(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockWriter := &mocks.FakeStagedWriter{}
|
||||
mockWriter.DeleteBlobReturns(hash.Hash{}, errors.New("delete blob error"))
|
||||
@@ -3124,7 +3124,7 @@ func TestGitRepository_Delete_ErrorConditions(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockWriter := &mocks.FakeStagedWriter{}
|
||||
mockWriter.DeleteTreeReturns(hash.Hash{}, errors.New("delete tree error"))
|
||||
@@ -3139,7 +3139,7 @@ func TestGitRepository_Delete_ErrorConditions(t *testing.T) {
|
||||
setupMock: func(mockClient *mocks.FakeClient) {
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockWriter := &mocks.FakeStagedWriter{}
|
||||
mockWriter.DeleteTreeReturns(hash.Hash{}, nanogit.ErrObjectNotFound)
|
||||
@@ -3186,7 +3186,7 @@ func TestGitRepository_CompareFiles_EmptyBase(t *testing.T) {
|
||||
// Only setup for ref resolution
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/feature",
|
||||
Hash: hash.Hash{4, 5, 6},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.CompareCommitsReturns([]nanogit.CommitFile{
|
||||
{
|
||||
@@ -3218,8 +3218,8 @@ func TestGitRepository_CompareFiles_EmptyBase(t *testing.T) {
|
||||
// Verify CompareCommits was called with empty base hash and feature hash
|
||||
require.Equal(t, 1, mockClient.CompareCommitsCallCount())
|
||||
_, baseHash, refHash := mockClient.CompareCommitsArgsForCall(0)
|
||||
require.Nil(t, baseHash) // Empty hash for empty base
|
||||
require.Equal(t, hash.Hash{4, 5, 6}, refHash)
|
||||
require.Equal(t, hash.Zero, baseHash) // Empty hash for empty base
|
||||
require.Equal(t, hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"), refHash)
|
||||
}
|
||||
|
||||
func TestGitRepository_EmptyRefHandling(t *testing.T) {
|
||||
@@ -3237,7 +3237,7 @@ func TestGitRepository_EmptyRefHandling(t *testing.T) {
|
||||
mockClient := &mocks.FakeClient{}
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
|
||||
mockWriter := &mocks.FakeStagedWriter{}
|
||||
@@ -3299,7 +3299,7 @@ func TestGitRepository_CompareFiles_ResolveErrors(t *testing.T) {
|
||||
// First call succeeds for base
|
||||
mockClient.GetRefReturnsOnCall(0, nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
// Second call fails for ref
|
||||
mockClient.GetRefReturnsOnCall(1, nanogit.Ref{}, errors.New("ref error"))
|
||||
@@ -3341,14 +3341,14 @@ func TestGitRepository_Read_EmptyRef(t *testing.T) {
|
||||
mockClient := &mocks.FakeClient{}
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.GetCommitReturns(&nanogit.Commit{
|
||||
Tree: hash.Hash{4, 5, 6},
|
||||
Tree: hash.Hash{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
|
||||
}, nil)
|
||||
mockClient.GetBlobByPathReturns(&nanogit.Blob{
|
||||
Content: []byte("file content"),
|
||||
Hash: hash.Hash{7, 8, 9},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
|
||||
gitRepo := &gitRepository{
|
||||
@@ -3376,13 +3376,13 @@ func TestGitRepository_ReadTree_EmptyRef(t *testing.T) {
|
||||
mockClient := &mocks.FakeClient{}
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.GetFlatTreeReturns(&nanogit.FlatTree{
|
||||
Entries: []nanogit.FlatTreeEntry{
|
||||
{
|
||||
Path: "configs/test.yaml",
|
||||
Hash: hash.Hash{4, 5, 6},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
Type: protocol.ObjectTypeBlob,
|
||||
},
|
||||
},
|
||||
@@ -3504,17 +3504,17 @@ func TestGitRepository_Write_DefaultRef(t *testing.T) {
|
||||
// First call for Read check - file not found
|
||||
mockClient.GetRefReturnsOnCall(0, nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.GetCommitReturns(&nanogit.Commit{
|
||||
Tree: hash.Hash{4, 5, 6},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.GetBlobByPathReturns(&nanogit.Blob{}, nanogit.ErrObjectNotFound)
|
||||
|
||||
// Second call for Create
|
||||
mockClient.GetRefReturnsOnCall(1, nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockWriter := &mocks.FakeStagedWriter{}
|
||||
mockWriter.CreateBlobReturns(hash.Hash{}, nil)
|
||||
@@ -3545,14 +3545,14 @@ func TestGitRepository_Read_RefInFileInfo(t *testing.T) {
|
||||
mockClient := &mocks.FakeClient{}
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/feature",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.GetCommitReturns(&nanogit.Commit{
|
||||
Tree: hash.Hash{4, 5, 6},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.GetBlobByPathReturns(&nanogit.Blob{
|
||||
Content: []byte("file content"),
|
||||
Hash: hash.Hash{7, 8, 9},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
|
||||
gitRepo := &gitRepository{
|
||||
@@ -3582,10 +3582,10 @@ func TestGitRepository_Read_GetTreeByPath_NotFound(t *testing.T) {
|
||||
mockClient := &mocks.FakeClient{}
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.GetCommitReturns(&nanogit.Commit{
|
||||
Tree: hash.Hash([]byte("tree-hash")),
|
||||
Tree: hash.Hash{30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49},
|
||||
}, nil)
|
||||
mockClient.GetTreeByPathReturns(nil, nanogit.ErrObjectNotFound)
|
||||
|
||||
@@ -3614,7 +3614,7 @@ func TestGitRepository_ReadTree_GetFlatTree_NotFound(t *testing.T) {
|
||||
mockClient := &mocks.FakeClient{}
|
||||
mockClient.GetRefReturns(nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.GetFlatTreeReturns(nil, nanogit.ErrObjectNotFound)
|
||||
|
||||
@@ -3655,11 +3655,11 @@ func TestGitRepository_CompareFiles_FilesOutsideConfiguredPath_AllStatuses(t *te
|
||||
mockClient := &mocks.FakeClient{}
|
||||
mockClient.GetRefReturnsOnCall(0, nanogit.Ref{
|
||||
Name: "refs/heads/main",
|
||||
Hash: hash.Hash{1, 2, 3},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121314"),
|
||||
}, nil)
|
||||
mockClient.GetRefReturnsOnCall(1, nanogit.Ref{
|
||||
Name: "refs/heads/feature",
|
||||
Hash: hash.Hash{4, 5, 6},
|
||||
Hash: hash.MustFromHex("0102030405060708090a0b0c0d0e0f1011121315"),
|
||||
}, nil)
|
||||
mockClient.CompareCommitsReturns([]nanogit.CommitFile{
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package repository
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package repository
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package resources
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package resources
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package resources
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package resources
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package resources
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.4. DO NOT EDIT.
|
||||
|
||||
package resources
|
||||
|
||||
@@ -26,64 +26,6 @@ func (_m *MockRepositoryResources) EXPECT() *MockRepositoryResources_Expecter {
|
||||
return &MockRepositoryResources_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// WriteResourceFileFromObject provides a mock function with given fields: ctx, obj, options
|
||||
func (_m *MockRepositoryResources) WriteResourceFileFromObject(ctx context.Context, obj *unstructured.Unstructured, options WriteOptions) (string, error) {
|
||||
ret := _m.Called(ctx, obj, options)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for WriteResourceFileFromObject")
|
||||
}
|
||||
|
||||
var r0 string
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *unstructured.Unstructured, WriteOptions) (string, error)); ok {
|
||||
return rf(ctx, obj, options)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *unstructured.Unstructured, WriteOptions) string); ok {
|
||||
r0 = rf(ctx, obj, options)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *unstructured.Unstructured, WriteOptions) error); ok {
|
||||
r1 = rf(ctx, obj, options)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockRepositoryResources_WriteResourceFileFromObject_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteResourceFileFromObject'
|
||||
type MockRepositoryResources_WriteResourceFileFromObject_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// WriteResourceFileFromObject is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - obj *unstructured.Unstructured
|
||||
// - options WriteOptions
|
||||
func (_e *MockRepositoryResources_Expecter) WriteResourceFileFromObject(ctx interface{}, obj interface{}, options interface{}) *MockRepositoryResources_WriteResourceFileFromObject_Call {
|
||||
return &MockRepositoryResources_WriteResourceFileFromObject_Call{Call: _e.mock.On("WriteResourceFileFromObject", ctx, obj, options)}
|
||||
}
|
||||
|
||||
func (_c *MockRepositoryResources_WriteResourceFileFromObject_Call) Run(run func(ctx context.Context, obj *unstructured.Unstructured, options WriteOptions)) *MockRepositoryResources_WriteResourceFileFromObject_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(*unstructured.Unstructured), args[2].(WriteOptions))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockRepositoryResources_WriteResourceFileFromObject_Call) Return(_a0 string, _a1 error) *MockRepositoryResources_WriteResourceFileFromObject_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockRepositoryResources_WriteResourceFileFromObject_Call) RunAndReturn(run func(context.Context, *unstructured.Unstructured, WriteOptions) (string, error)) *MockRepositoryResources_WriteResourceFileFromObject_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// EnsureFolderExists provides a mock function with given fields: ctx, folder, parentID
|
||||
func (_m *MockRepositoryResources) EnsureFolderExists(ctx context.Context, folder Folder, parentID string) error {
|
||||
ret := _m.Called(ctx, folder, parentID)
|
||||
@@ -520,6 +462,64 @@ func (_c *MockRepositoryResources_Stats_Call) RunAndReturn(run func(context.Cont
|
||||
return _c
|
||||
}
|
||||
|
||||
// WriteResourceFileFromObject provides a mock function with given fields: ctx, obj, options
|
||||
func (_m *MockRepositoryResources) WriteResourceFileFromObject(ctx context.Context, obj *unstructured.Unstructured, options WriteOptions) (string, error) {
|
||||
ret := _m.Called(ctx, obj, options)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for WriteResourceFileFromObject")
|
||||
}
|
||||
|
||||
var r0 string
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *unstructured.Unstructured, WriteOptions) (string, error)); ok {
|
||||
return rf(ctx, obj, options)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *unstructured.Unstructured, WriteOptions) string); ok {
|
||||
r0 = rf(ctx, obj, options)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *unstructured.Unstructured, WriteOptions) error); ok {
|
||||
r1 = rf(ctx, obj, options)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockRepositoryResources_WriteResourceFileFromObject_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteResourceFileFromObject'
|
||||
type MockRepositoryResources_WriteResourceFileFromObject_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// WriteResourceFileFromObject is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - obj *unstructured.Unstructured
|
||||
// - options WriteOptions
|
||||
func (_e *MockRepositoryResources_Expecter) WriteResourceFileFromObject(ctx interface{}, obj interface{}, options interface{}) *MockRepositoryResources_WriteResourceFileFromObject_Call {
|
||||
return &MockRepositoryResources_WriteResourceFileFromObject_Call{Call: _e.mock.On("WriteResourceFileFromObject", ctx, obj, options)}
|
||||
}
|
||||
|
||||
func (_c *MockRepositoryResources_WriteResourceFileFromObject_Call) Run(run func(ctx context.Context, obj *unstructured.Unstructured, options WriteOptions)) *MockRepositoryResources_WriteResourceFileFromObject_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(*unstructured.Unstructured), args[2].(WriteOptions))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockRepositoryResources_WriteResourceFileFromObject_Call) Return(_a0 string, _a1 error) *MockRepositoryResources_WriteResourceFileFromObject_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockRepositoryResources_WriteResourceFileFromObject_Call) RunAndReturn(run func(context.Context, *unstructured.Unstructured, WriteOptions) (string, error)) *MockRepositoryResources_WriteResourceFileFromObject_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// WriteResourceFromFile provides a mock function with given fields: ctx, path, ref
|
||||
func (_m *MockRepositoryResources) WriteResourceFromFile(ctx context.Context, path string, ref string) (string, schema.GroupVersionKind, error) {
|
||||
ret := _m.Called(ctx, path, ref)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user