Skip to content
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

add tenant-ids-field #190

Merged
merged 3 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Add Mimir Alertmanager datasource
- Add Mimir Alertmanager datasource.
- Add tenant ids field to the grafana organization CR to be able to support multiple tenants into one organization.
QuentinBisson marked this conversation as resolved.
Show resolved Hide resolved

### Changed

Expand Down
13 changes: 12 additions & 1 deletion api/v1alpha1/grafanaorganization_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,19 @@ type GrafanaOrganizationSpec struct {
DisplayName string `json:"displayName"`

// Access rules defines user permissions for interacting with the organization in Grafana.
RBAC *RBAC `json:"rbac,omitempty"`
RBAC *RBAC `json:"rbac"`

// Tenants is a list of tenants that are associated with the Grafana organization.
// +kubebuilder:example={"giantswarm"}
Tenants []TenantID `json:"tenants,omitempty"`
}

// TenantID is a unique identifier for a tenant. It must be lowercase.
// +kubebuilder:validation:Pattern="^[a-z]*$"
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=63
type TenantID string

// RBAC defines the RoleBasedAccessControl configuration for the Grafana organization.
// Each fields represents the mapping to a Grafana role:
//
Expand Down Expand Up @@ -62,6 +72,7 @@ type RBAC struct {
// GrafanaOrganizationStatus defines the observed state of GrafanaOrganization
type GrafanaOrganizationStatus struct {
// OrgID is the actual organisation ID in grafana.
// +optional
OrgID int64 `json:"orgID"`

// DataSources is a list of grafana data sources that are available to the Grafana organization.
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,22 @@ spec:
required:
- admins
type: object
tenants:
description: Tenants is a list of tenants that are associated with
the Grafana organization.
example:
- giantswarm
items:
description: TenantID is a unique identifier for a tenant. It must
be lowercase.
maxLength: 63
minLength: 1
pattern: ^[a-z]*$
type: string
type: array
required:
- displayName
- rbac
type: object
status:
description: GrafanaOrganizationStatus defines the observed state of GrafanaOrganization
Expand All @@ -104,8 +118,6 @@ spec:
description: OrgID is the actual organisation ID in grafana.
format: int64
type: integer
required:
- orgID
type: object
type: object
served: true
Expand Down
9 changes: 8 additions & 1 deletion internal/controller/grafanaorganization_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,16 @@ func (r GrafanaOrganizationReconciler) reconcileDelete(ctx context.Context, graf
return nil
}

// Delete organization in Grafana
var organization = grafana.Organization{
ID: grafanaOrganization.Status.OrgID,
Name: grafanaOrganization.Spec.DisplayName,
TenantID: grafanaOrganization.Name,
}

// Delete organization in Grafana if it exists
if grafanaOrganization.Status.OrgID > 0 {
err := grafana.DeleteByID(ctx, r.GrafanaAPI, grafanaOrganization.Status.OrgID)
err := grafana.DeleteOrganization(ctx, r.GrafanaAPI, organization)
if err != nil {
return errors.WithStack(err)
}
Expand Down
14 changes: 10 additions & 4 deletions pkg/grafana/grafana.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,22 @@ func UpdateOrganization(ctx context.Context, grafanaAPI *client.GrafanaHTTPAPI,
return &organization, nil
}

func DeleteByID(ctx context.Context, grafanaAPI *client.GrafanaHTTPAPI, id int64) error {
func DeleteOrganization(ctx context.Context, grafanaAPI *client.GrafanaHTTPAPI, organization Organization) error {
logger := log.FromContext(ctx)

logger.Info("deleting organization")
_, err := findByID(grafanaAPI, id)
_, err := findByID(grafanaAPI, organization.ID)
if err != nil {
logger.Error(err, fmt.Sprintf("failed to find organization with ID: %d", id))
if isNotFound(err) {
logger.Info("organization id was not found, skipping deletion")
// If the CR orgID does not exist in Grafana, then we create the organization
return nil
}
logger.Error(err, fmt.Sprintf("failed to find organization with ID: %d", organization.ID))
return errors.WithStack(err)
}

_, err = grafanaAPI.Orgs.DeleteOrgByID(id)
_, err = grafanaAPI.Orgs.DeleteOrgByID(organization.ID)
if err != nil {
logger.Error(err, "failed to delete organization")
return errors.WithStack(err)
Expand Down
Loading