github.com/winebarrel/terraform-provider-lambdazip@v0.6.1-0.20240313233639-361839f8c5c5/lambdazip/resource_file.go (about)

     1  package lambdazip
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
    10  	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
    11  	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
    12  	"github.com/winebarrel/terraform-provider-lambdazip/internal/cmd"
    13  	"github.com/winebarrel/terraform-provider-lambdazip/internal/glob"
    14  	"github.com/winebarrel/terraform-provider-lambdazip/internal/hash"
    15  	"github.com/winebarrel/terraform-provider-lambdazip/internal/zip"
    16  )
    17  
    18  func resourceFile() *schema.Resource {
    19  	return &schema.Resource{
    20  		CreateContext: createFile,
    21  		ReadContext:   readFile,
    22  		DeleteContext: deleteFile,
    23  
    24  		Schema: map[string]*schema.Schema{
    25  			"base_dir": {
    26  				Type:     schema.TypeString,
    27  				Optional: true,
    28  				Default:  "",
    29  				ForceNew: true,
    30  			},
    31  			"sources": {
    32  				Type: schema.TypeList,
    33  				Elem: &schema.Schema{
    34  					Type: schema.TypeString,
    35  				},
    36  				Required: true,
    37  				ForceNew: true,
    38  			},
    39  			"excludes": {
    40  				Type: schema.TypeList,
    41  				Elem: &schema.Schema{
    42  					Type: schema.TypeString,
    43  				},
    44  				Optional: true,
    45  				ForceNew: true,
    46  			},
    47  			"output": {
    48  				Type:     schema.TypeString,
    49  				Required: true,
    50  				ForceNew: true,
    51  			},
    52  			"before_create": {
    53  				Type:     schema.TypeString,
    54  				Optional: true,
    55  				ForceNew: true,
    56  			},
    57  			"triggers": {
    58  				Type: schema.TypeMap,
    59  				Elem: &schema.Schema{
    60  					Type: schema.TypeString,
    61  				},
    62  				Required: true,
    63  				ForceNew: true,
    64  			},
    65  			"base64sha256": {
    66  				Type:     schema.TypeString,
    67  				Computed: true,
    68  			},
    69  		},
    70  	}
    71  }
    72  
    73  func createFile(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
    74  	baseDir := d.Get("base_dir").(string)
    75  	cwd, err := os.Getwd()
    76  
    77  	if err != nil {
    78  		return diag.FromErr(err)
    79  	}
    80  
    81  	if baseDir != "" {
    82  		err = os.Chdir(baseDir)
    83  
    84  		if err != nil {
    85  			return diag.FromErr(err)
    86  		}
    87  
    88  		defer os.Chdir(cwd) //nolint:errcheck
    89  	}
    90  
    91  	sources := []string{}
    92  
    93  	if patterns, ok := d.GetOk("sources"); ok {
    94  		for _, pat := range patterns.([]any) {
    95  			sources = append(sources, pat.(string))
    96  		}
    97  	}
    98  
    99  	if len(sources) == 0 {
   100  		return diag.Errorf(`The attribute "sources" is required, but the list was empty.`)
   101  	}
   102  
   103  	output := d.Get("output").(string)
   104  	excludes := []string{}
   105  
   106  	if patterns, ok := d.GetOk("excludes"); ok {
   107  		for _, pat := range patterns.([]any) {
   108  			excludes = append(excludes, pat.(string))
   109  		}
   110  	}
   111  
   112  	if beforeCreate, ok := d.GetOk("before_create"); ok {
   113  		beforeCreateCmd := beforeCreate.(string)
   114  		cmdout, err := cmd.Run(beforeCreateCmd)
   115  
   116  		if err != nil {
   117  			errmsg := `"%s" failed - %w`
   118  
   119  			if cmdout != "" {
   120  				errmsg += ":\n" + cmdout
   121  			}
   122  
   123  			return diag.Errorf(errmsg, beforeCreateCmd, err)
   124  		}
   125  	}
   126  
   127  	sources, err = glob.Glob(sources, excludes)
   128  
   129  	if err != nil {
   130  		return diag.FromErr(err)
   131  	}
   132  
   133  	if baseDir != "" && !strings.HasPrefix("/", baseDir) {
   134  		output = filepath.Join(cwd, output)
   135  	}
   136  
   137  	err = zip.ZipFile(sources, output)
   138  
   139  	if err != nil {
   140  		return diag.FromErr(err)
   141  	}
   142  
   143  	base64Sha256, err := hash.Base64Sha256(output)
   144  
   145  	if err != nil {
   146  		return diag.FromErr(err)
   147  	}
   148  
   149  	d.Set("base64sha256", base64Sha256) //nolint:errcheck
   150  	d.SetId(id.UniqueId())
   151  
   152  	return nil
   153  }
   154  
   155  func readFile(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
   156  	return nil
   157  }
   158  
   159  func deleteFile(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
   160  	output := d.Get("output").(string)
   161  	os.Remove(output)
   162  	d.SetId("")
   163  
   164  	return nil
   165  }