2020-03-17 19:23:00 +00:00
package tenant
import (
"context"
2020-04-03 17:39:20 +00:00
"github.com/influxdata/influxdb/v2"
icontext "github.com/influxdata/influxdb/v2/context"
2021-09-13 19:12:35 +00:00
"github.com/influxdata/influxdb/v2/kit/platform"
2020-04-03 17:39:20 +00:00
"github.com/influxdata/influxdb/v2/kv"
2020-03-17 19:23:00 +00:00
)
2020-07-30 21:55:25 +00:00
type OrgSvc struct {
store * Store
svc * Service
}
func NewOrganizationSvc ( st * Store , svc * Service ) * OrgSvc {
return & OrgSvc {
store : st ,
svc : svc ,
}
}
2020-03-17 19:23:00 +00:00
// Returns a single organization by ID.
2021-03-30 18:10:02 +00:00
func ( s * OrgSvc ) FindOrganizationByID ( ctx context . Context , id platform . ID ) ( * influxdb . Organization , error ) {
2020-03-17 19:23:00 +00:00
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.
2020-07-30 21:55:25 +00:00
func ( s * OrgSvc ) FindOrganization ( ctx context . Context , filter influxdb . OrganizationFilter ) ( * influxdb . Organization , error ) {
2020-03-17 19:23:00 +00:00
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.
2020-07-30 21:55:25 +00:00
func ( s * OrgSvc ) FindOrganizations ( ctx context . Context , filter influxdb . OrganizationFilter , opt ... influxdb . FindOptions ) ( [ ] * influxdb . Organization , int , error ) {
2020-03-17 19:23:00 +00:00
// 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
2020-04-16 18:22:21 +00:00
if filter . UserID != nil {
// find urms for orgs with this user
2020-07-30 21:55:25 +00:00
urms , _ , err := s . svc . FindUserResourceMappings ( ctx , influxdb . UserResourceMappingFilter {
2020-04-16 18:22:21 +00:00
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
}
2020-03-17 19:23:00 +00:00
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.
2020-07-30 21:55:25 +00:00
func ( s * OrgSvc ) CreateOrganization ( ctx context . Context , o * influxdb . Organization ) error {
2020-03-17 19:23:00 +00:00
err := s . store . Update ( ctx , func ( tx kv . Tx ) error {
2020-07-30 21:55:25 +00:00
return s . store . CreateOrg ( ctx , tx , o )
} )
if err != nil {
return err
}
2020-03-17 19:23:00 +00:00
2020-07-30 21:55:25 +00:00
tb := & influxdb . Bucket {
OrgID : o . ID ,
Type : influxdb . BucketTypeSystem ,
Name : influxdb . TasksSystemBucketName ,
RetentionPeriod : influxdb . TasksSystemBucketRetention ,
Description : "System bucket for task logs" ,
}
2020-03-17 19:23:00 +00:00
2020-07-30 21:55:25 +00:00
if err := s . svc . CreateBucket ( ctx , tb ) ; err != nil {
return err
}
2020-03-17 19:23:00 +00:00
2020-07-30 21:55:25 +00:00
mb := & influxdb . Bucket {
OrgID : o . ID ,
Type : influxdb . BucketTypeSystem ,
Name : influxdb . MonitoringSystemBucketName ,
RetentionPeriod : influxdb . MonitoringSystemBucketRetention ,
Description : "System bucket for monitoring logs" ,
}
2020-03-17 19:23:00 +00:00
2020-07-30 21:55:25 +00:00
if err := s . svc . CreateBucket ( ctx , mb ) ; err != nil {
return err
}
2020-03-17 19:23:00 +00:00
2020-07-30 21:55:25 +00:00
// create associated URM
userID , err := icontext . GetUserID ( ctx )
2020-08-03 15:33:46 +00:00
if err == nil && userID . Valid ( ) {
2020-07-30 21:55:25 +00:00
// if I am given a userid i can associate the user as the org owner
err = s . svc . CreateUserResourceMapping ( ctx , & influxdb . UserResourceMapping {
UserID : userID ,
UserType : influxdb . Owner ,
MappingType : influxdb . UserMappingType ,
ResourceType : influxdb . OrgsResourceType ,
ResourceID : o . ID ,
} )
if err != nil {
return err
2020-03-17 19:23:00 +00:00
}
2020-07-30 21:55:25 +00:00
}
return nil
2020-03-17 19:23:00 +00:00
}
// Updates a single organization with changeset.
// Returns the new organization state after update.
2021-03-30 18:10:02 +00:00
func ( s * OrgSvc ) UpdateOrganization ( ctx context . Context , id platform . ID , upd influxdb . OrganizationUpdate ) ( * influxdb . Organization , error ) {
2020-03-17 19:23:00 +00:00
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
}
2020-04-11 04:51:13 +00:00
// DeleteOrganization removes a organization by ID and its dependent resources.
2021-03-30 18:10:02 +00:00
func ( s * OrgSvc ) DeleteOrganization ( ctx context . Context , id platform . ID ) error {
2020-07-30 21:55:25 +00:00
// clean up the buckets for this organization
filter := influxdb . BucketFilter {
OrganizationID : & id ,
}
bs , _ , err := s . svc . FindBuckets ( ctx , filter )
if err != nil {
return err
}
for _ , b := range bs {
if err := s . svc . DeleteBucket ( internalCtx ( ctx ) , b . ID ) ; err != nil {
if err != ErrBucketNotFound {
2020-03-17 19:23:00 +00:00
return err
}
}
2020-07-30 21:55:25 +00:00
}
2020-03-17 19:23:00 +00:00
2020-07-30 21:55:25 +00:00
err = s . store . Update ( ctx , func ( tx kv . Tx ) error {
2020-03-17 19:23:00 +00:00
return s . store . DeleteOrg ( ctx , tx , id )
} )
2020-07-30 21:55:25 +00:00
if err != nil {
return err
}
return s . removeResourceRelations ( ctx , id )
}
// removeResourceRelations allows us to clean up any resource relationship that would have normally been left over after a delete action of a resource.
2021-03-30 18:10:02 +00:00
func ( s * OrgSvc ) removeResourceRelations ( ctx context . Context , resourceID platform . ID ) error {
2020-07-30 21:55:25 +00:00
urms , _ , err := s . svc . FindUserResourceMappings ( ctx , influxdb . UserResourceMappingFilter {
ResourceID : resourceID ,
} )
if err != nil {
return err
}
for _ , urm := range urms {
err := s . svc . DeleteUserResourceMapping ( ctx , urm . ResourceID , urm . UserID )
if err != nil && err != ErrURMNotFound {
return err
}
}
return nil
2020-03-17 19:23:00 +00:00
}