(ctx context.Context, opts *ProvisionOptions)
| 21 | } |
| 22 | |
| 23 | func (s *Service) Provision(ctx context.Context, opts *ProvisionOptions) (*database.ProvisionerResource, error) { |
| 24 | // Attempt to find an existing provisioned resource |
| 25 | pr, err := s.DB.FindProvisionerResourceByTypeAndName(ctx, opts.DeploymentID, string(opts.Type), opts.Name) |
| 26 | if err != nil && !errors.Is(err, database.ErrNotFound) { |
| 27 | return nil, err |
| 28 | } |
| 29 | |
| 30 | // Find the provisioner to use |
| 31 | var provisionerName string |
| 32 | var p provisioner.Provisioner |
| 33 | if pr != nil { |
| 34 | if opts.Provisioner != "" && opts.Provisioner != pr.Provisioner { |
| 35 | return nil, fmt.Errorf("provisioner: cannot change provisioner from %q to %q for deployment %q", provisionerName, opts.Provisioner, opts.DeploymentID) |
| 36 | } |
| 37 | |
| 38 | var ok bool |
| 39 | provisionerName = pr.Provisioner |
| 40 | p, ok = s.ProvisionerSet[provisionerName] |
| 41 | if !ok { |
| 42 | return nil, fmt.Errorf("provisioner: previous provisioner %q is no longer in the provisioner set", provisionerName) |
| 43 | } |
| 44 | |
| 45 | if !p.Supports(opts.Type) { |
| 46 | return nil, fmt.Errorf("provisioner: previous provisioner %q no longer supports resource type %q", provisionerName, opts.Type) |
| 47 | } |
| 48 | } else if opts.Provisioner != "" { |
| 49 | provisionerName = opts.Provisioner |
| 50 | var ok bool |
| 51 | p, ok = s.ProvisionerSet[provisionerName] |
| 52 | if !ok { |
| 53 | return nil, fmt.Errorf("provisioner: the requested provisioner %q is not in the provisioner set", provisionerName) |
| 54 | } |
| 55 | |
| 56 | if !p.Supports(opts.Type) { |
| 57 | return nil, fmt.Errorf("provisioner: the requested provisioner %q does not support resource type %q", provisionerName, opts.Type) |
| 58 | } |
| 59 | } else { |
| 60 | for n, candidate := range s.ProvisionerSet { |
| 61 | if candidate.Supports(opts.Type) { |
| 62 | provisionerName = n |
| 63 | p = candidate |
| 64 | break |
| 65 | } |
| 66 | } |
| 67 | if p == nil { |
| 68 | return nil, fmt.Errorf("provisioner: no provisioner available that supports resource type %q", opts.Type) |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | // Insert a pending provisioner resource if it doesn't exist |
| 73 | if pr == nil { |
| 74 | pr, err = s.DB.InsertProvisionerResource(ctx, &database.InsertProvisionerResourceOptions{ |
| 75 | ID: uuid.New().String(), |
| 76 | DeploymentID: opts.DeploymentID, |
| 77 | Type: string(opts.Type), |
| 78 | Name: opts.Name, |
| 79 | Status: database.ProvisionerResourceStatusPending, |
| 80 | StatusMessage: "Provisioning...", |
no test coverage detected