Export starts a new export operation.
(ctx context.Context, principal *models.Principal, id, backend string, include, exclude []string)
| 132 | |
| 133 | // Export starts a new export operation. |
| 134 | func (s *Scheduler) Export(ctx context.Context, principal *models.Principal, id, backend string, include, exclude []string) (*models.ExportCreateResponse, error) { |
| 135 | if !s.exportConfig.Enabled.Get() { |
| 136 | return nil, ErrExportDisabled |
| 137 | } |
| 138 | if s.shuttingDown.Load() { |
| 139 | return nil, ErrExportShuttingDown |
| 140 | } |
| 141 | if err := validateExportID(id); err != nil { |
| 142 | return nil, err |
| 143 | } |
| 144 | if backend == "" { |
| 145 | return nil, fmt.Errorf("%w: backend is required", ErrExportValidation) |
| 146 | } |
| 147 | |
| 148 | bucket, path, err := s.validateStorageConfig(backend) |
| 149 | if err != nil { |
| 150 | return nil, err |
| 151 | } |
| 152 | |
| 153 | classes, err := s.resolveClasses(ctx, include, exclude) |
| 154 | if err != nil { |
| 155 | return nil, fmt.Errorf("%w: resolve classes: %w", ErrExportValidation, err) |
| 156 | } |
| 157 | |
| 158 | classes = filter.New[string](s.authorizer, s.rbacConfig).Filter( |
| 159 | ctx, |
| 160 | principal, |
| 161 | classes, |
| 162 | authorization.CREATE, |
| 163 | func(class string) string { |
| 164 | return authorization.Backups(class)[0] |
| 165 | }, |
| 166 | ) |
| 167 | |
| 168 | if len(classes) == 0 { |
| 169 | return nil, fmt.Errorf("%w: no exportable classes", ErrExportValidation) |
| 170 | } |
| 171 | |
| 172 | // Require async replication for every exported class with RF > 1. The |
| 173 | // selector also returns false when the class has no local index, so the |
| 174 | // error below keeps both causes in view. |
| 175 | var noAsync []string |
| 176 | for _, class := range classes { |
| 177 | if !s.selector.IsAsyncReplicationEnabled(ctx, class) { |
| 178 | noAsync = append(noAsync, class) |
| 179 | } |
| 180 | } |
| 181 | if len(noAsync) > 0 { |
| 182 | return nil, fmt.Errorf("%w: collections %v are not exportable: export "+ |
| 183 | "requires async replication for every collection with replication "+ |
| 184 | "factor > 1. This usually means async replication is disabled "+ |
| 185 | "cluster-wide — unset ASYNC_REPLICATION_DISABLED (or the equivalent "+ |
| 186 | "runtime override) to re-enable it — but it can also mean the "+ |
| 187 | "collection is not yet known to this node", ErrExportValidation, noAsync) |
| 188 | } |
| 189 | |
| 190 | backendStore, err := s.backends.BackupBackend(backend, modulecapabilities.BackendUseCaseExport) |
| 191 | if err != nil { |