-
-
Notifications
You must be signed in to change notification settings - Fork 339
feat: Add Grafana module #1509
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
feat: Add Grafana module #1509
Conversation
Implements Testcontainers support for Grafana with the following features: - Default Grafana image: grafana/grafana:11.0.0 - Support for custom username/password authentication - Anonymous access configuration - Ability to mount datasources, dashboards, plugins, and notifiers - HTTP health check wait strategy - Connection string generation with embedded credentials 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
✅ Deploy Preview for testcontainers-dotnet ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
4900ecd to
8fa5f1b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! It looks great overall, but there are a few small things we need to fix before we can merge it.
| /// <summary> | ||
| /// Mounts a datasource configuration file. | ||
| /// </summary> | ||
| /// <param name="datasourceFilePath">The path to the datasource configuration file.</param> | ||
| /// <returns>A configured instance of <see cref="GrafanaBuilder" />.</returns> | ||
| public GrafanaBuilder WithDataSource(string datasourceFilePath) | ||
| { | ||
| return WithBindMount(datasourceFilePath, "/etc/grafana/provisioning/datasources/"); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Mounts a dashboard configuration file. | ||
| /// </summary> | ||
| /// <param name="dashboardFilePath">The path to the dashboard configuration file.</param> | ||
| /// <returns>A configured instance of <see cref="GrafanaBuilder" />.</returns> | ||
| public GrafanaBuilder WithDashboard(string dashboardFilePath) | ||
| { | ||
| return WithBindMount(dashboardFilePath, "/etc/grafana/provisioning/dashboards/"); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Mounts a plugin configuration file. | ||
| /// </summary> | ||
| /// <param name="pluginFilePath">The path to the plugin configuration file.</param> | ||
| /// <returns>A configured instance of <see cref="GrafanaBuilder" />.</returns> | ||
| public GrafanaBuilder WithPlugin(string pluginFilePath) | ||
| { | ||
| return WithBindMount(pluginFilePath, "/etc/grafana/provisioning/plugins/"); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Mounts a notifier configuration file. | ||
| /// </summary> | ||
| /// <param name="notifierFilePath">The path to the notifier configuration file.</param> | ||
| /// <returns>A configured instance of <see cref="GrafanaBuilder" />.</returns> | ||
| public GrafanaBuilder WithNotifier(string notifierFilePath) | ||
| { | ||
| return WithBindMount(notifierFilePath, "/etc/grafana/provisioning/notifiers/"); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mounting a share isn't aligned with our best practices. It can make the module incompatible with remote container runtimes. Instead, we recommend using the WithResourceMapping(FileInfo, FileInfo) API, which copies the files into the container.
| .WithPortBinding(GrafanaPort, true) | ||
| .WithUsername(DefaultUsername) | ||
| .WithPassword(DefaultPassword) | ||
| .WithEnvironment("GF_AUTH_ANONYMOUS_ENABLED", "false") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .WithEnvironment("GF_AUTH_ANONYMOUS_ENABLED", "false") | |
| .WithAnonymousAccessDisabled() |
| /// <summary> | ||
| /// Mounts a datasource configuration file. | ||
| /// </summary> | ||
| /// <param name="datasourceFilePath">The path to the datasource configuration file.</param> | ||
| /// <returns>A configured instance of <see cref="GrafanaBuilder" />.</returns> | ||
| public GrafanaBuilder WithDataSource(string datasourceFilePath) | ||
| { | ||
| return WithBindMount(datasourceFilePath, "/etc/grafana/provisioning/datasources/"); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Mounts a dashboard configuration file. | ||
| /// </summary> | ||
| /// <param name="dashboardFilePath">The path to the dashboard configuration file.</param> | ||
| /// <returns>A configured instance of <see cref="GrafanaBuilder" />.</returns> | ||
| public GrafanaBuilder WithDashboard(string dashboardFilePath) | ||
| { | ||
| return WithBindMount(dashboardFilePath, "/etc/grafana/provisioning/dashboards/"); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Mounts a plugin configuration file. | ||
| /// </summary> | ||
| /// <param name="pluginFilePath">The path to the plugin configuration file.</param> | ||
| /// <returns>A configured instance of <see cref="GrafanaBuilder" />.</returns> | ||
| public GrafanaBuilder WithPlugin(string pluginFilePath) | ||
| { | ||
| return WithBindMount(pluginFilePath, "/etc/grafana/provisioning/plugins/"); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Mounts a notifier configuration file. | ||
| /// </summary> | ||
| /// <param name="notifierFilePath">The path to the notifier configuration file.</param> | ||
| /// <returns>A configured instance of <see cref="GrafanaBuilder" />.</returns> | ||
| public GrafanaBuilder WithNotifier(string notifierFilePath) | ||
| { | ||
| return WithBindMount(notifierFilePath, "/etc/grafana/provisioning/notifiers/"); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These builder APIs haven't been tested. We typically add builder APIs only for configurations that are essential to run an instance or required for specific use cases.
| public string GetConnectionString() | ||
| { | ||
| var endpoint = GetHttpEndpoint(); | ||
| var username = _configuration.Username ?? GrafanaBuilder.DefaultUsername; | ||
| var password = _configuration.Password ?? GrafanaBuilder.DefaultPassword; | ||
| return new UriBuilder(endpoint) | ||
| { | ||
| UserName = username, | ||
| Password = password | ||
| }.ToString(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of this? The tests only use the HTTP header for authentication.
Implements Testcontainers support for Grafana with the following features: