github.com/nais/knorten@v0.0.0-20240104110906-55926958e361/pkg/database/services.go (about) 1 package database 2 3 import ( 4 "context" 5 "database/sql" 6 "errors" 7 "fmt" 8 9 "github.com/nais/knorten/pkg/database/gensql" 10 "golang.org/x/exp/slices" 11 ) 12 13 type AppService struct { 14 App string 15 Ingress string 16 Slug string 17 } 18 19 type TeamServices struct { 20 TeamID string 21 Slug string 22 Jupyterhub *AppService 23 Airflow *AppService 24 Events []EventWithLogs 25 } 26 27 type UserServices struct { 28 Services []TeamServices 29 Compute *gensql.ComputeInstance 30 UserGSM *gensql.UserGoogleSecretManager 31 UserEvents []EventWithLogs 32 } 33 34 func createIngress(team string, chartType gensql.ChartType) string { 35 switch chartType { 36 case gensql.ChartTypeJupyterhub: 37 return fmt.Sprintf("https://%v.jupyter.knada.io", team) 38 case gensql.ChartTypeAirflow: 39 return fmt.Sprintf("https://%v.airflow.knada.io", team) 40 } 41 42 return "" 43 } 44 45 func createAppService(slug string, chartType gensql.ChartType) *AppService { 46 return &AppService{ 47 App: string(chartType), 48 Ingress: createIngress(slug, chartType), 49 Slug: slug, 50 } 51 } 52 53 func (r *Repo) ChartsForTeamGet(ctx context.Context, teamID string) ([]gensql.ChartType, error) { 54 return r.querier.ChartsForTeamGet(ctx, teamID) 55 } 56 57 func (r *Repo) ChartDelete(ctx context.Context, teamID string, chartType gensql.ChartType) error { 58 return r.querier.ChartDelete(ctx, gensql.ChartDeleteParams{ 59 TeamID: teamID, 60 ChartType: chartType, 61 }) 62 } 63 64 func (r *Repo) ServicesForUser(ctx context.Context, email string) (UserServices, error) { 65 teamsForUser, err := r.querier.TeamsForUserGet(ctx, email) 66 if err != nil { 67 return UserServices{}, err 68 } 69 70 slices.SortFunc(teamsForUser, func(a, b gensql.TeamsForUserGetRow) int { 71 if a.ID < b.ID { 72 return -1 73 } else if a.ID > b.ID { 74 return 1 75 } else { 76 return 0 77 } 78 }) 79 80 var userServices UserServices 81 for _, team := range teamsForUser { 82 apps, err := r.querier.ChartsForTeamGet(ctx, team.ID) 83 if err != nil { 84 return UserServices{}, err 85 } 86 87 events, err := r.EventLogsForOwnerGet(ctx, team.ID, 3) 88 if err != nil { 89 return UserServices{}, err 90 } 91 92 teamServices := TeamServices{ 93 TeamID: team.ID, 94 Slug: team.Slug, 95 Events: events, 96 } 97 98 for _, app := range apps { 99 switch app { 100 case gensql.ChartTypeJupyterhub: 101 teamServices.Jupyterhub = createAppService(team.Slug, app) 102 case gensql.ChartTypeAirflow: 103 teamServices.Airflow = createAppService(team.Slug, app) 104 } 105 } 106 107 userServices.Services = append(userServices.Services, teamServices) 108 } 109 110 var hasUserServices bool 111 compute, err := r.querier.ComputeInstanceGet(ctx, email) 112 if err != nil { 113 if !errors.Is(err, sql.ErrNoRows) { 114 return UserServices{}, err 115 } 116 } else { 117 userServices.Compute = &compute 118 hasUserServices = true 119 } 120 121 manager, err := r.querier.UserGoogleSecretManagerGet(ctx, email) 122 if err != nil { 123 if !errors.Is(err, sql.ErrNoRows) { 124 return UserServices{}, err 125 } 126 } else { 127 userServices.UserGSM = &manager 128 hasUserServices = true 129 } 130 131 if hasUserServices { 132 events, err := r.EventLogsForOwnerGet(ctx, email, 3) 133 if err != nil { 134 return UserServices{}, err 135 } 136 137 userServices.UserEvents = events 138 } 139 140 return userServices, nil 141 } 142 143 func (r *Repo) TeamValueInsert(ctx context.Context, chartType gensql.ChartType, key, value, teamID string) error { 144 return r.querier.TeamValueInsert(ctx, gensql.TeamValueInsertParams{ 145 Key: key, 146 Value: value, 147 TeamID: teamID, 148 ChartType: chartType, 149 }) 150 } 151 152 func (r *Repo) HelmChartValuesInsert(ctx context.Context, chartType gensql.ChartType, chartValues map[string]string, teamID string) error { 153 tx, err := r.db.Begin() 154 if err != nil { 155 return err 156 } 157 158 querier := r.querier.WithTx(tx) 159 for key, value := range chartValues { 160 err := querier.TeamValueInsert(ctx, gensql.TeamValueInsertParams{ 161 Key: key, 162 Value: value, 163 TeamID: teamID, 164 ChartType: chartType, 165 }) 166 if err != nil { 167 if err := tx.Rollback(); err != nil { 168 r.log.WithError(err).Error("rolling back service create transaction - team chart value insert") 169 } 170 return err 171 } 172 } 173 174 if err := tx.Commit(); err != nil { 175 return err 176 } 177 return nil 178 }