@@ -16,6 +16,7 @@ import (
16
16
17
17
"github.com/go-chi/chi/v5"
18
18
"github.com/google/uuid"
19
+ "github.com/hashicorp/hcl/v2"
19
20
"github.com/moby/moby/pkg/namesgenerator"
20
21
"github.com/sqlc-dev/pqtype"
21
22
"golang.org/x/xerrors"
@@ -1582,10 +1583,63 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
1582
1583
}
1583
1584
}
1584
1585
1586
+ var files fs.FS
1587
+ switch file .Mimetype {
1588
+ case "application/x-tar" :
1589
+ files = archivefs .FromTarReader (bytes .NewBuffer (file .Data ))
1590
+ case "application/zip" :
1591
+ files ,err = archivefs .FromZipReader (bytes .NewReader (file .Data ),int64 (len (file .Data )))
1592
+ if err != nil {
1593
+ httpapi .Write (ctx ,rw ,http .StatusInternalServerError , codersdk.Response {
1594
+ Message :"Internal error reading file" ,
1595
+ Detail :"extract zip archive: " + err .Error (),
1596
+ })
1597
+ return
1598
+ }
1599
+ default :
1600
+ httpapi .Write (ctx ,rw ,http .StatusBadRequest , codersdk.Response {
1601
+ Message :"Unsupported file type" ,
1602
+ Detail :fmt .Sprintf ("Mimetype %q is not supported" ,file .Mimetype ),
1603
+ })
1604
+ return
1605
+ }
1606
+ ownerData ,err := dynamicparameters .WorkspaceOwner (ctx ,api .Database ,organization .ID ,apiKey .UserID )
1607
+ if err != nil {
1608
+ if httpapi .Is404Error (err ) {
1609
+ httpapi .Write (ctx ,rw ,http .StatusBadRequest , codersdk.Response {
1610
+ Message :"Internal error checking workspace tags" ,
1611
+ Detail :fmt .Sprintf ("Owner not found, uuid=%s" ,apiKey .UserID .String ()),
1612
+ })
1613
+ return
1614
+ }
1615
+ httpapi .Write (ctx ,rw ,http .StatusInternalServerError , codersdk.Response {
1616
+ Message :"Internal error checking workspace tags" ,
1617
+ Detail :"fetch owner data: " + err .Error (),
1618
+ })
1619
+ return
1620
+ }
1621
+
1622
+ previewInput := preview.Input {
1623
+ PlanJSON :nil ,// Template versions are before `terraform plan`
1624
+ ParameterValues :nil ,// No user-specified parameters
1625
+ Owner :* ownerData ,
1626
+ Logger :stdslog .New (stdslog .DiscardHandler ),
1627
+ }
1628
+ previewOutput ,previewDiags := preview .Preview (ctx ,previewInput ,files )
1629
+
1630
+ // Validate presets on template version import to avoid errors that would
1631
+ // have caused workspace creation to fail:
1632
+ presetErr := dynamicparameters .CheckPresets (previewOutput ,nil )
1633
+ if presetErr != nil {
1634
+ code ,resp := presetErr .Response ()
1635
+ httpapi .Write (ctx ,rw ,code ,resp )
1636
+ return
1637
+ }
1638
+
1585
1639
var parsedTags map [string ]string
1586
1640
var ok bool
1587
1641
if dynamicTemplate {
1588
- parsedTags ,ok = api .dynamicTemplateVersionTags (ctx ,rw ,organization . ID , apiKey . UserID , file )
1642
+ parsedTags ,ok = api .dynamicTemplateVersionTags (ctx ,rw ,previewOutput , previewDiags )
1589
1643
if ! ok {
1590
1644
return
1591
1645
}
@@ -1762,50 +1816,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
1762
1816
warnings ))
1763
1817
}
1764
1818
1765
- func (api * API )dynamicTemplateVersionTags (ctx context.Context ,rw http.ResponseWriter ,orgID uuid.UUID ,owner uuid.UUID ,file database.File ) (map [string ]string ,bool ) {
1766
- ownerData ,err := dynamicparameters .WorkspaceOwner (ctx ,api .Database ,orgID ,owner )
1767
- if err != nil {
1768
- if httpapi .Is404Error (err ) {
1769
- httpapi .Write (ctx ,rw ,http .StatusBadRequest , codersdk.Response {
1770
- Message :"Internal error checking workspace tags" ,
1771
- Detail :fmt .Sprintf ("Owner not found, uuid=%s" ,owner .String ()),
1772
- })
1773
- return nil ,false
1774
- }
1775
- httpapi .Write (ctx ,rw ,http .StatusInternalServerError , codersdk.Response {
1776
- Message :"Internal error checking workspace tags" ,
1777
- Detail :"fetch owner data: " + err .Error (),
1778
- })
1779
- return nil ,false
1780
- }
1781
-
1782
- var files fs.FS
1783
- switch file .Mimetype {
1784
- case "application/x-tar" :
1785
- files = archivefs .FromTarReader (bytes .NewBuffer (file .Data ))
1786
- case "application/zip" :
1787
- files ,err = archivefs .FromZipReader (bytes .NewReader (file .Data ),int64 (len (file .Data )))
1788
- if err != nil {
1789
- httpapi .Write (ctx ,rw ,http .StatusInternalServerError , codersdk.Response {
1790
- Message :"Internal error checking workspace tags" ,
1791
- Detail :"extract zip archive: " + err .Error (),
1792
- })
1793
- return nil ,false
1794
- }
1795
- default :
1796
- httpapi .Write (ctx ,rw ,http .StatusBadRequest , codersdk.Response {
1797
- Message :"Unsupported file type for dynamic template version tags" ,
1798
- Detail :fmt .Sprintf ("Mimetype %q is not supported for dynamic template version tags" ,file .Mimetype ),
1799
- })
1800
- return nil ,false
1801
- }
1802
-
1803
- output ,diags := preview .Preview (ctx , preview.Input {
1804
- PlanJSON :nil ,// Template versions are before `terraform plan`
1805
- ParameterValues :nil ,// No user-specified parameters
1806
- Owner :* ownerData ,
1807
- Logger :stdslog .New (stdslog .DiscardHandler ),
1808
- },files )
1819
+ func (* API )dynamicTemplateVersionTags (ctx context.Context ,rw http.ResponseWriter ,output * preview.Output ,diags hcl.Diagnostics ) (map [string ]string ,bool ) {
1809
1820
tagErr := dynamicparameters .CheckTags (output ,diags )
1810
1821
if tagErr != nil {
1811
1822
code ,resp := tagErr .Response ()