influxdb/tenant/service_org.go

208 lines
5.2 KiB
Go

package tenant
import (
"context"
"github.com/influxdata/influxdb/v2"
icontext "github.com/influxdata/influxdb/v2/context"
"github.com/influxdata/influxdb/v2/kv"
)
// Returns a single organization by ID.
func (s *Service) FindOrganizationByID(ctx context.Context, id influxdb.ID) (*influxdb.Organization, error) {
var org *influxdb.Organization
err := s.store.View(ctx, func(tx kv.Tx) error {
o, err := s.store.GetOrg(ctx, tx, id)
if err != nil {
return err
}
org = o
return nil
})
if err != nil {
return nil, err
}
return org, nil
}
// Returns the first organization that matches filter.
func (s *Service) FindOrganization(ctx context.Context, filter influxdb.OrganizationFilter) (*influxdb.Organization, error) {
if filter.ID != nil {
return s.FindOrganizationByID(ctx, *filter.ID)
}
if filter.Name == nil {
return nil, influxdb.ErrInvalidOrgFilter
}
var org *influxdb.Organization
err := s.store.View(ctx, func(tx kv.Tx) error {
o, err := s.store.GetOrgByName(ctx, tx, *filter.Name)
if err != nil {
return err
}
org = o
return nil
})
if err != nil {
return nil, err
}
return org, nil
}
// Returns a list of organizations that match filter and the total count of matching organizations.
// Additional options provide pagination & sorting.
func (s *Service) FindOrganizations(ctx context.Context, filter influxdb.OrganizationFilter, opt ...influxdb.FindOptions) ([]*influxdb.Organization, int, error) {
// if im given a id or a name I know I can only return 1
if filter.ID != nil || filter.Name != nil {
org, err := s.FindOrganization(ctx, filter)
if err != nil {
return nil, 0, err
}
return []*influxdb.Organization{org}, 1, nil
}
var orgs []*influxdb.Organization
if filter.UserID != nil {
// find urms for orgs with this user
urms, _, err := s.FindUserResourceMappings(ctx, influxdb.UserResourceMappingFilter{
UserID: *filter.UserID,
ResourceType: influxdb.OrgsResourceType,
}, opt...)
if err != nil {
return nil, 0, err
}
// find orgs by the urm's resource ids.
for _, urm := range urms {
o, err := s.FindOrganizationByID(ctx, urm.ResourceID)
if err == nil {
// if there is an error then this is a crufty urm and we should just move on
orgs = append(orgs, o)
}
}
return orgs, len(orgs), nil
}
err := s.store.View(ctx, func(tx kv.Tx) error {
os, err := s.store.ListOrgs(ctx, tx, opt...)
if err != nil {
return err
}
orgs = os
return nil
})
if err != nil {
return nil, 0, err
}
return orgs, len(orgs), err
}
// Creates a new organization and sets b.ID with the new identifier.
func (s *Service) CreateOrganization(ctx context.Context, o *influxdb.Organization) error {
err := s.store.Update(ctx, func(tx kv.Tx) error {
err := s.store.CreateOrg(ctx, tx, o)
if err != nil {
return err
}
tb := &influxdb.Bucket{
OrgID: o.ID,
Type: influxdb.BucketTypeSystem,
Name: influxdb.TasksSystemBucketName,
RetentionPeriod: influxdb.TasksSystemBucketRetention,
Description: "System bucket for task logs",
}
if err := s.store.CreateBucket(ctx, tx, tb); err != nil {
return err
}
mb := &influxdb.Bucket{
OrgID: o.ID,
Type: influxdb.BucketTypeSystem,
Name: influxdb.MonitoringSystemBucketName,
RetentionPeriod: influxdb.MonitoringSystemBucketRetention,
Description: "System bucket for monitoring logs",
}
if err := s.store.CreateBucket(ctx, tx, mb); err != nil {
return err
}
// create assiciated URM
userID, err := icontext.GetUserID(ctx)
if err == nil {
// if I am given a userid i can associate the user as the org owner
err = s.store.CreateURM(ctx, tx, &influxdb.UserResourceMapping{
UserID: userID,
UserType: influxdb.Owner,
MappingType: influxdb.UserMappingType,
ResourceType: influxdb.OrgsResourceType,
ResourceID: o.ID,
})
if err != nil {
return err
}
}
return nil
})
return err
}
// Updates a single organization with changeset.
// Returns the new organization state after update.
func (s *Service) UpdateOrganization(ctx context.Context, id influxdb.ID, upd influxdb.OrganizationUpdate) (*influxdb.Organization, error) {
var org *influxdb.Organization
err := s.store.Update(ctx, func(tx kv.Tx) error {
o, err := s.store.UpdateOrg(ctx, tx, id, upd)
if err != nil {
return err
}
org = o
return nil
})
if err != nil {
return nil, err
}
return org, nil
}
// DeleteOrganization removes a organization by ID and its dependent resources.
func (s *Service) DeleteOrganization(ctx context.Context, id influxdb.ID) error {
err := s.store.Update(ctx, func(tx kv.Tx) error {
// clean up the buckets for this organization
filter := BucketFilter{
OrganizationID: &id,
}
bs, err := s.store.ListBuckets(ctx, tx, filter)
if err != nil {
return err
}
for _, b := range bs {
if err := s.store.DeleteBucket(ctx, tx, b.ID); err != nil {
if err != ErrBucketNotFound {
return err
}
}
if err := s.removeResourceRelations(ctx, tx, b.ID); err != nil {
return err
}
}
if err := s.removeResourceRelations(ctx, tx, id); err != nil {
return err
}
return s.store.DeleteOrg(ctx, tx, id)
})
return err
}