@@ -19,12 +19,10 @@ import (
1919 "context"
2020 "errors"
2121 "fmt"
22- "strings"
2322 "time"
2423
2524 "github.com/go-kratos/kratos/v2/log"
2625 "github.com/google/uuid"
27- "github.com/moby/moby/pkg/namesgenerator"
2826 "k8s.io/apimachinery/pkg/util/validation"
2927)
3028
@@ -57,22 +55,64 @@ func NewOrganizationUseCase(repo OrganizationRepo, repoUC *CASBackendUseCase, iU
5755 }
5856}
5957
58+ const OrganizationRandomNameMaxTries = 10
59+
60+ func (uc * OrganizationUseCase ) CreateWithRandomName (ctx context.Context ) (* Organization , error ) {
61+ // Try 10 times to create a random name
62+ for i := 0 ; i < OrganizationRandomNameMaxTries ; i ++ {
63+ // Create a random name
64+ name , err := generateRandomName ()
65+ if err != nil {
66+ return nil , fmt .Errorf ("failed to generate random name: %w" , err )
67+ }
68+
69+ org , err := uc .doCreate (ctx , name )
70+ if err != nil {
71+ // We retry if the organization already exists
72+ if errors .Is (err , ErrAlreadyExists ) {
73+ uc .logger .Debugw ("msg" , "Org exists!" , "name" , name )
74+ continue
75+ }
76+ uc .logger .Debugw ("msg" , "BOOM" , "name" , name , "err" , err )
77+ return nil , err
78+ }
79+
80+ return org , nil
81+ }
82+
83+ return nil , errors .New ("failed to create a random organization name" )
84+ }
85+
86+ // Create an organization with the given name
6087func (uc * OrganizationUseCase ) Create (ctx context.Context , name string ) (* Organization , error ) {
61- // Create a random name if none is provided
62- if name == "" {
63- name = namesgenerator .GetRandomName (0 )
64- // Replace underscores with dashes to make it compatible with DNS1123
65- name = strings .ReplaceAll (name , "_" , "-" )
88+ org , err := uc .doCreate (ctx , name )
89+ if err != nil {
90+ if errors .Is (err , ErrAlreadyExists ) {
91+ return nil , NewErrValidationStr ("organization already exists" )
92+ }
93+
94+ return nil , fmt .Errorf ("failed to create organization: %w" , err )
6695 }
6796
68- if err := validateOrgName (name ); err != nil {
97+ return org , nil
98+ }
99+
100+ func (uc * OrganizationUseCase ) doCreate (ctx context.Context , name string ) (* Organization , error ) {
101+ uc .logger .Infow ("msg" , "Creating organization" , "name" , name )
102+
103+ if err := ValidateOrgName (name ); err != nil {
69104 return nil , NewErrValidation (fmt .Errorf ("invalid organization name: %w" , err ))
70105 }
71106
72- return uc .orgRepo .Create (ctx , name )
107+ org , err := uc .orgRepo .Create (ctx , name )
108+ if err != nil {
109+ return nil , fmt .Errorf ("failed to create organization: %w" , err )
110+ }
111+
112+ return org , nil
73113}
74114
75- func validateOrgName (name string ) error {
115+ func ValidateOrgName (name string ) error {
76116 // The same validation done by Kubernetes for their namespace name
77117 // https://github.com/kubernetes/apimachinery/blob/fa98d6eaedb4caccd69fc07d90bbb6a1e551f00f/pkg/api/validation/generic.go#L63
78118 err := validation .IsDNS1123Label (name )
@@ -101,7 +141,7 @@ func (uc *OrganizationUseCase) Update(ctx context.Context, userID, orgID string,
101141
102142 // We validate the name to get ready for the name to become identifiers
103143 if name != nil {
104- if err := validateOrgName (* name ); err != nil {
144+ if err := ValidateOrgName (* name ); err != nil {
105145 return nil , NewErrValidation (fmt .Errorf ("invalid organization name: %w" , err ))
106146 }
107147 }
0 commit comments