diff --git a/api/handlers/app.go b/api/handlers/app.go index a1d2e9dfa..5ec7f742d 100644 --- a/api/handlers/app.go +++ b/api/handlers/app.go @@ -50,6 +50,7 @@ const ( type CFAppRepository interface { GetApp(context.Context, authorization.Info, string) (repositories.AppRecord, error) ListApps(context.Context, authorization.Info, repositories.ListAppsMessage) ([]repositories.AppRecord, error) + GetAppEnvVars(context.Context, authorization.Info, string) (repositories.AppEnvVarsRecord, error) PatchAppEnvVars(context.Context, authorization.Info, repositories.PatchAppEnvVarsMessage) (repositories.AppEnvVarsRecord, error) CreateApp(context.Context, authorization.Info, repositories.CreateAppMessage) (repositories.AppRecord, error) SetCurrentDroplet(context.Context, authorization.Info, repositories.SetCurrentDropletMessage) (repositories.CurrentDropletRecord, error) @@ -480,6 +481,19 @@ func getDomainsForRoutes(ctx context.Context, domainRepo CFDomainRepository, aut return routeRecords, nil } +func (h *App) getEnvVars(r *http.Request) (*routing.Response, error) { + authInfo, _ := authorization.InfoFromContext(r.Context()) + logger := logr.FromContextOrDiscard(r.Context()).WithName("handlers.app.get-env-vars") + appGUID := routing.URLParam(r, "guid") + + envVarsRecord, err := h.appRepo.GetAppEnvVars(r.Context(), authInfo, appGUID) + if err != nil { + return nil, apierrors.LogAndReturn(logger, err, "Failed to fetch app environment variables", "AppGUID", appGUID) + } + + return routing.NewResponse(http.StatusOK).WithBody(presenter.ForAppEnvVars(envVarsRecord, h.serverURL)), nil +} + func (h *App) updateEnvVars(r *http.Request) (*routing.Response, error) { authInfo, _ := authorization.InfoFromContext(r.Context()) logger := logr.FromContextOrDiscard(r.Context()).WithName("handlers.app.update-env-vars") @@ -717,6 +731,7 @@ func (h *App) AuthenticatedRoutes() []routing.Route { {Method: "GET", Pattern: AppProcessStatsByTypePath, Handler: h.getProcessStats}, {Method: "GET", Pattern: AppRoutesPath, Handler: h.getRoutes}, {Method: "DELETE", Pattern: AppPath, Handler: h.delete}, + {Method: "GET", Pattern: AppEnvVarsPath, Handler: h.getEnvVars}, {Method: "PATCH", Pattern: AppEnvVarsPath, Handler: h.updateEnvVars}, {Method: "GET", Pattern: AppEnvPath, Handler: h.getEnvironment}, {Method: "GET", Pattern: AppPackagesPath, Handler: h.getPackages}, diff --git a/api/repositories/app_repository.go b/api/repositories/app_repository.go index 7c2c75268..a1fba41a2 100644 --- a/api/repositories/app_repository.go +++ b/api/repositories/app_repository.go @@ -387,6 +387,36 @@ func (f *AppRepo) ListApps(ctx context.Context, authInfo authorization.Info, mes return f.sorter.Sort(slices.Collect(appRecords), message.OrderBy), nil } +func (f *AppRepo) GetAppEnvVars(ctx context.Context, authInfo authorization.Info, appGUID string) (AppEnvVarsRecord, error) { + app, err := f.GetApp(ctx, authInfo, appGUID) + if err != nil { + return AppEnvVarsRecord{}, err + } + + userClient, err := f.userClientFactory.BuildClient(authInfo) + if err != nil { + return AppEnvVarsRecord{}, fmt.Errorf("failed to build user client: %w", err) + } + + appEnvVarMap := map[string]string{} + if app.envSecretName != "" { + appEnvVarSecret := new(corev1.Secret) + err = userClient.Get(ctx, types.NamespacedName{Name: app.envSecretName, Namespace: app.SpaceGUID}, appEnvVarSecret) + if err != nil { + return AppEnvVarsRecord{}, fmt.Errorf("error finding environment variable Secret %q for App %q: %w", + app.envSecretName, + app.GUID, + apierrors.FromK8sError(err, AppEnvResourceType)) + } + appEnvVarMap = convertByteSliceValuesToStrings(appEnvVarSecret.Data) + } + + return AppEnvVarsRecord{ + AppGUID: app.GUID, + EnvironmentVariables: appEnvVarMap, + }, nil +} + func (f *AppRepo) PatchAppEnvVars(ctx context.Context, authInfo authorization.Info, message PatchAppEnvVarsMessage) (AppEnvVarsRecord, error) { secretObj := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{