(ctx context.Context, req *adminv1.EditReportRequest)
| 233 | } |
| 234 | |
| 235 | func (s *Server) EditReport(ctx context.Context, req *adminv1.EditReportRequest) (*adminv1.EditReportResponse, error) { |
| 236 | observability.AddRequestAttributes(ctx, |
| 237 | attribute.String("args.organization", req.Org), |
| 238 | attribute.String("args.project", req.Project), |
| 239 | attribute.String("args.name", req.Name), |
| 240 | ) |
| 241 | |
| 242 | proj, err := s.admin.DB.FindProjectByName(ctx, req.Org, req.Project) |
| 243 | if err != nil { |
| 244 | return nil, err |
| 245 | } |
| 246 | |
| 247 | claims := auth.GetClaims(ctx) |
| 248 | permissions := claims.ProjectPermissions(ctx, proj.OrganizationID, proj.ID) |
| 249 | if !permissions.ReadProd { |
| 250 | return nil, status.Error(codes.PermissionDenied, "does not have permission to read project repo") |
| 251 | } |
| 252 | |
| 253 | if proj.PrimaryDeploymentID == nil { |
| 254 | return nil, status.Error(codes.FailedPrecondition, "project does not have a production deployment") |
| 255 | } |
| 256 | |
| 257 | depl, err := s.admin.DB.FindDeployment(ctx, *proj.PrimaryDeploymentID) |
| 258 | if err != nil { |
| 259 | return nil, err |
| 260 | } |
| 261 | |
| 262 | spec, err := s.admin.LookupReport(ctx, depl, req.Name) |
| 263 | if err != nil { |
| 264 | return nil, fmt.Errorf("could not get report: %w", err) |
| 265 | } |
| 266 | annotations := parseReportAnnotations(spec.Annotations) |
| 267 | |
| 268 | if !annotations.AdminManaged { |
| 269 | return nil, status.Error(codes.FailedPrecondition, "can't edit report because it was not created from the UI") |
| 270 | } |
| 271 | |
| 272 | isOwner := claims.OwnerType() == auth.OwnerTypeUser && annotations.AdminOwnerUserID == claims.OwnerID() |
| 273 | if !permissions.ManageReports && !isOwner { |
| 274 | return nil, status.Error(codes.PermissionDenied, "does not have permission to edit report") |
| 275 | } |
| 276 | |
| 277 | data, err := s.yamlForManagedReport(req.Options, annotations.AdminOwnerUserID) |
| 278 | if err != nil { |
| 279 | return nil, status.Errorf(codes.InvalidArgument, "failed to generate report YAML: %s", err.Error()) |
| 280 | } |
| 281 | |
| 282 | err = s.admin.DB.UpsertVirtualFile(ctx, &database.InsertVirtualFileOptions{ |
| 283 | ProjectID: proj.ID, |
| 284 | Environment: "prod", |
| 285 | Path: virtualFilePathForManagedReport(req.Name), |
| 286 | Data: data, |
| 287 | }) |
| 288 | if err != nil { |
| 289 | return nil, fmt.Errorf("failed to update virtual file: %w", err) |
| 290 | } |
| 291 | |
| 292 | err = s.admin.TriggerParserAndAwaitResource(ctx, depl, req.Name, runtime.ResourceKindReport) |
nothing calls this directly
no test coverage detected