github.com/hashicorp/packer@v1.14.3/hcl2template/function/datetime.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package function
     5  
     6  import (
     7  	"fmt"
     8  	"time"
     9  
    10  	"github.com/jehiah/go-strftime"
    11  	"github.com/zclconf/go-cty/cty"
    12  	"github.com/zclconf/go-cty/cty/function"
    13  )
    14  
    15  // initTime is the UTC time when this package was initialized. It is
    16  // used as the timestamp for all configuration templates so that they
    17  // match for a single build.
    18  var initTime time.Time
    19  
    20  func init() {
    21  	initTime = time.Now().UTC()
    22  }
    23  
    24  // TimestampFunc constructs a function that returns a string representation of the current date and time.
    25  var TimestampFunc = function.New(&function.Spec{
    26  	Params:       []function.Parameter{},
    27  	Type:         function.StaticReturnType(cty.String),
    28  	RefineResult: refineNotNull,
    29  	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
    30  		return cty.StringVal(time.Now().UTC().Format(time.RFC3339)), nil
    31  	},
    32  })
    33  
    34  // Timestamp returns a string representation of the current date and time.
    35  //
    36  // In the HCL language, timestamps are conventionally represented as strings
    37  // using RFC 3339 "Date and Time format" syntax, and so timestamp returns a
    38  // string in this format.
    39  func Timestamp() (cty.Value, error) {
    40  	return TimestampFunc.Call([]cty.Value{})
    41  }
    42  
    43  // LegacyIsotimeFunc constructs a function that returns a string representation
    44  // of the current date and time using the Go language datetime formatting syntax.
    45  var LegacyIsotimeFunc = function.New(&function.Spec{
    46  	Params: []function.Parameter{},
    47  	VarParam: &function.Parameter{
    48  		Name: "format",
    49  		Type: cty.String,
    50  	},
    51  	Type:         function.StaticReturnType(cty.String),
    52  	RefineResult: refineNotNull,
    53  	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
    54  		if len(args) > 1 {
    55  			return cty.StringVal(""), fmt.Errorf("too many values, 1 needed: %v", args)
    56  		}
    57  		if len(args) == 0 {
    58  			return cty.StringVal(initTime.Format(time.RFC3339)), nil
    59  		}
    60  		format := args[0].AsString()
    61  		return cty.StringVal(initTime.Format(format)), nil
    62  	},
    63  })
    64  
    65  // LegacyStrftimeFunc constructs a function that returns a string representation
    66  // of the current date and time using the Go language strftime datetime formatting syntax.
    67  var LegacyStrftimeFunc = function.New(&function.Spec{
    68  	Params: []function.Parameter{},
    69  	VarParam: &function.Parameter{
    70  		Name: "format",
    71  		Type: cty.String,
    72  	},
    73  	Type:         function.StaticReturnType(cty.String),
    74  	RefineResult: refineNotNull,
    75  	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
    76  		if len(args) > 1 {
    77  			return cty.StringVal(""), fmt.Errorf("too many values, 1 needed: %v", args)
    78  		}
    79  		if len(args) == 0 {
    80  			return cty.StringVal(initTime.Format(time.RFC3339)), nil
    81  		}
    82  		format := args[0].AsString()
    83  		return cty.StringVal(strftime.Format(format, initTime)), nil
    84  	},
    85  })
    86  
    87  // LegacyIsotimeFunc returns a string representation of the current date and
    88  // time using the given format string. The format string follows golang's
    89  // datetime formatting. See
    90  // https://www.packer.io/docs/templates/legacy_json_templates/engine#isotime-function-format-reference
    91  // for more details.
    92  //
    93  // This function has been provided to create backwards compatability with
    94  // Packer's legacy JSON templates. However, we recommend that you upgrade your
    95  // HCL Packer template to use Timestamp and FormatDate together as soon as is
    96  // convenient.
    97  //
    98  // Please note that if you are using a large number of builders, provisioners
    99  // or post-processors, the isotime may be slightly different for each one
   100  // because it is from when the plugin is launched not the initial Packer
   101  // process. In order to avoid this and make the timestamp consistent across all
   102  // plugins, set it as a user variable and then access the user variable within
   103  // your plugins.
   104  func LegacyIsotime(format cty.Value) (cty.Value, error) {
   105  	return LegacyIsotimeFunc.Call([]cty.Value{format})
   106  }