provider/fastly: add ssl_hostname option

Fastly will fail if the user sets the port to 443, ssl_check_cert is set
to true and the ssl_hostname is not provided.
This commit is contained in:
zimbatm 2016-10-26 14:16:54 +01:00 committed by stack72
parent af0600815c
commit 01876ef415
No known key found for this signature in database
GPG Key ID: 8619A619B085CB16
12 changed files with 120 additions and 98 deletions

View File

@ -172,6 +172,12 @@ func resourceServiceV1() *schema.Resource {
Default: true, Default: true,
Description: "Be strict on checking SSL certs", Description: "Be strict on checking SSL certs",
}, },
"ssl_hostname": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: "",
Description: "SSL certificate hostname",
},
// UseSSL is something we want to support in the future, but // UseSSL is something we want to support in the future, but
// requires SSL setup we don't yet have // requires SSL setup we don't yet have
// TODO: Provide all SSL fields from https://docs.fastly.com/api/config#backend // TODO: Provide all SSL fields from https://docs.fastly.com/api/config#backend
@ -810,8 +816,9 @@ func resourceServiceV1Update(d *schema.ResourceData, meta interface{}) error {
Version: latestVersion, Version: latestVersion,
Name: df["name"].(string), Name: df["name"].(string),
Address: df["address"].(string), Address: df["address"].(string),
AutoLoadbalance: df["auto_loadbalance"].(bool), AutoLoadbalance: gofastly.CBool(df["auto_loadbalance"].(bool)),
SSLCheckCert: df["ssl_check_cert"].(bool), SSLCheckCert: gofastly.CBool(df["ssl_check_cert"].(bool)),
SSLHostname: df["ssl_hostname"].(string),
Port: uint(df["port"].(int)), Port: uint(df["port"].(int)),
BetweenBytesTimeout: uint(df["between_bytes_timeout"].(int)), BetweenBytesTimeout: uint(df["between_bytes_timeout"].(int)),
ConnectTimeout: uint(df["connect_timeout"].(int)), ConnectTimeout: uint(df["connect_timeout"].(int)),
@ -1485,14 +1492,15 @@ func flattenBackends(backendList []*gofastly.Backend) []map[string]interface{} {
nb := map[string]interface{}{ nb := map[string]interface{}{
"name": b.Name, "name": b.Name,
"address": b.Address, "address": b.Address,
"auto_loadbalance": b.AutoLoadbalance, "auto_loadbalance": gofastly.CBool(b.AutoLoadbalance),
"between_bytes_timeout": int(b.BetweenBytesTimeout), "between_bytes_timeout": int(b.BetweenBytesTimeout),
"connect_timeout": int(b.ConnectTimeout), "connect_timeout": int(b.ConnectTimeout),
"error_threshold": int(b.ErrorThreshold), "error_threshold": int(b.ErrorThreshold),
"first_byte_timeout": int(b.FirstByteTimeout), "first_byte_timeout": int(b.FirstByteTimeout),
"max_conn": int(b.MaxConn), "max_conn": int(b.MaxConn),
"port": int(b.Port), "port": int(b.Port),
"ssl_check_cert": b.SSLCheckCert, "ssl_check_cert": gofastly.CBool(b.SSLCheckCert),
"ssl_hostname": b.SSLHostname,
"weight": int(b.Weight), "weight": int(b.Weight),
} }
@ -1566,7 +1574,7 @@ func buildHeader(headerMap interface{}) (*gofastly.CreateHeaderInput, error) {
df := headerMap.(map[string]interface{}) df := headerMap.(map[string]interface{})
opts := gofastly.CreateHeaderInput{ opts := gofastly.CreateHeaderInput{
Name: df["name"].(string), Name: df["name"].(string),
IgnoreIfSet: gofastly.Compatibool(df["ignore_if_set"].(bool)), IgnoreIfSet: gofastly.CBool(df["ignore_if_set"].(bool)),
Destination: df["destination"].(string), Destination: df["destination"].(string),
Priority: uint(df["priority"].(int)), Priority: uint(df["priority"].(int)),
Source: df["source"].(string), Source: df["source"].(string),
@ -1762,12 +1770,12 @@ func buildRequestSetting(requestSettingMap interface{}) (*gofastly.CreateRequest
opts := gofastly.CreateRequestSettingInput{ opts := gofastly.CreateRequestSettingInput{
Name: df["name"].(string), Name: df["name"].(string),
MaxStaleAge: uint(df["max_stale_age"].(int)), MaxStaleAge: uint(df["max_stale_age"].(int)),
ForceMiss: gofastly.Compatibool(df["force_miss"].(bool)), ForceMiss: gofastly.CBool(df["force_miss"].(bool)),
ForceSSL: gofastly.Compatibool(df["force_ssl"].(bool)), ForceSSL: gofastly.CBool(df["force_ssl"].(bool)),
BypassBusyWait: gofastly.Compatibool(df["bypass_busy_wait"].(bool)), BypassBusyWait: gofastly.CBool(df["bypass_busy_wait"].(bool)),
HashKeys: df["hash_keys"].(string), HashKeys: df["hash_keys"].(string),
TimerSupport: gofastly.Compatibool(df["timer_support"].(bool)), TimerSupport: gofastly.CBool(df["timer_support"].(bool)),
GeoHeaders: gofastly.Compatibool(df["geo_headers"].(bool)), GeoHeaders: gofastly.CBool(df["geo_headers"].(bool)),
DefaultHost: df["default_host"].(string), DefaultHost: df["default_host"].(string),
RequestCondition: df["request_condition"].(string), RequestCondition: df["request_condition"].(string),
} }

View File

@ -21,7 +21,7 @@ func TestFastlyServiceV1_BuildHeaders(t *testing.T) {
remote: &gofastly.CreateHeaderInput{ remote: &gofastly.CreateHeaderInput{
Name: "someheadder", Name: "someheadder",
Action: gofastly.HeaderActionDelete, Action: gofastly.HeaderActionDelete,
IgnoreIfSet: true, IgnoreIfSet: gofastly.CBool(true),
Type: gofastly.HeaderTypeCache, Type: gofastly.HeaderTypeCache,
Destination: "http.aws-id", Destination: "http.aws-id",
Priority: uint(100), Priority: uint(100),
@ -45,6 +45,7 @@ func TestFastlyServiceV1_BuildHeaders(t *testing.T) {
remote: &gofastly.CreateHeaderInput{ remote: &gofastly.CreateHeaderInput{
Name: "someheadder", Name: "someheadder",
Action: gofastly.HeaderActionSet, Action: gofastly.HeaderActionSet,
IgnoreIfSet: gofastly.CBool(false),
Type: gofastly.HeaderTypeCache, Type: gofastly.HeaderTypeCache,
Destination: "http.aws-id", Destination: "http.aws-id",
Priority: uint(100), Priority: uint(100),

View File

@ -71,6 +71,7 @@ func TestResourceFastlyFlattenBackend(t *testing.T) {
FirstByteTimeout: uint(15000), FirstByteTimeout: uint(15000),
MaxConn: uint(200), MaxConn: uint(200),
SSLCheckCert: true, SSLCheckCert: true,
SSLHostname: "",
Weight: uint(100), Weight: uint(100),
}, },
}, },
@ -79,13 +80,14 @@ func TestResourceFastlyFlattenBackend(t *testing.T) {
"name": "test.notexample.com", "name": "test.notexample.com",
"address": "www.notexample.com", "address": "www.notexample.com",
"port": 80, "port": 80,
"auto_loadbalance": true, "auto_loadbalance": gofastly.CBool(true),
"between_bytes_timeout": 10000, "between_bytes_timeout": 10000,
"connect_timeout": 1000, "connect_timeout": 1000,
"error_threshold": 0, "error_threshold": 0,
"first_byte_timeout": 15000, "first_byte_timeout": 15000,
"max_conn": 200, "max_conn": 200,
"ssl_check_cert": true, "ssl_check_cert": gofastly.CBool(true),
"ssl_hostname": "",
"weight": 100, "weight": 100,
}, },
}, },

View File

@ -23,6 +23,7 @@ type Backend struct {
RequestCondition string `mapstructure:"request_condition"` RequestCondition string `mapstructure:"request_condition"`
HealthCheck string `mapstructure:"healthcheck"` HealthCheck string `mapstructure:"healthcheck"`
Hostname string `mapstructure:"hostname"` Hostname string `mapstructure:"hostname"`
Shield string `mapstructure:"shield"`
UseSSL bool `mapstructure:"use_ssl"` UseSSL bool `mapstructure:"use_ssl"`
SSLCheckCert bool `mapstructure:"ssl_check_cert"` SSLCheckCert bool `mapstructure:"ssl_check_cert"`
SSLHostname string `mapstructure:"ssl_hostname"` SSLHostname string `mapstructure:"ssl_hostname"`
@ -83,26 +84,27 @@ type CreateBackendInput struct {
Service string Service string
Version string Version string
Name string `form:"name,omitempty"` Name string `form:"name,omitempty"`
Address string `form:"address,omitempty"` Address string `form:"address,omitempty"`
Port uint `form:"port,omitempty"` Port uint `form:"port,omitempty"`
ConnectTimeout uint `form:"connect_timeout,omitempty"` ConnectTimeout uint `form:"connect_timeout,omitempty"`
MaxConn uint `form:"max_conn,omitempty"` MaxConn uint `form:"max_conn,omitempty"`
ErrorThreshold uint `form:"error_threshold,omitempty"` ErrorThreshold uint `form:"error_threshold,omitempty"`
FirstByteTimeout uint `form:"first_byte_timeout,omitempty"` FirstByteTimeout uint `form:"first_byte_timeout,omitempty"`
BetweenBytesTimeout uint `form:"between_bytes_timeout,omitempty"` BetweenBytesTimeout uint `form:"between_bytes_timeout,omitempty"`
AutoLoadbalance bool `form:"auto_loadbalance,omitempty"` AutoLoadbalance *Compatibool `form:"auto_loadbalance,omitempty"`
Weight uint `form:"weight,omitempty"` Weight uint `form:"weight,omitempty"`
RequestCondition string `form:"request_condition,omitempty"` RequestCondition string `form:"request_condition,omitempty"`
HealthCheck string `form:"healthcheck,omitempty"` HealthCheck string `form:"healthcheck,omitempty"`
UseSSL bool `form:"use_ssl,omitempty"` Shield string `form:"shield,omitempty"`
SSLCheckCert bool `form:"ssl_check_cert,omitempty"` UseSSL *Compatibool `form:"use_ssl,omitempty"`
SSLHostname string `form:"ssl_hostname,omitempty"` SSLCheckCert *Compatibool `form:"ssl_check_cert,omitempty"`
SSLCertHostname string `form:"ssl_cert_hostname,omitempty"` SSLHostname string `form:"ssl_hostname,omitempty"`
SSLSNIHostname string `form:"ssl_sni_hostname,omitempty"` SSLCertHostname string `form:"ssl_cert_hostname,omitempty"`
MinTLSVersion string `form:"min_tls_version,omitempty"` SSLSNIHostname string `form:"ssl_sni_hostname,omitempty"`
MaxTLSVersion string `form:"max_tls_version,omitempty"` MinTLSVersion string `form:"min_tls_version,omitempty"`
SSLCiphers []string `form:"ssl_ciphers,omitempty"` MaxTLSVersion string `form:"max_tls_version,omitempty"`
SSLCiphers []string `form:"ssl_ciphers,omitempty"`
} }
// CreateBackend creates a new Fastly backend. // CreateBackend creates a new Fastly backend.
@ -176,26 +178,27 @@ type UpdateBackendInput struct {
// Name is the name of the backend to update. // Name is the name of the backend to update.
Name string Name string
NewName string `form:"name,omitempty"` NewName string `form:"name,omitempty"`
Address string `form:"address,omitempty"` Address string `form:"address,omitempty"`
Port uint `form:"port,omitempty"` Port uint `form:"port,omitempty"`
ConnectTimeout uint `form:"connect_timeout,omitempty"` ConnectTimeout uint `form:"connect_timeout,omitempty"`
MaxConn uint `form:"max_conn,omitempty"` MaxConn uint `form:"max_conn,omitempty"`
ErrorThreshold uint `form:"error_threshold,omitempty"` ErrorThreshold uint `form:"error_threshold,omitempty"`
FirstByteTimeout uint `form:"first_byte_timeout,omitempty"` FirstByteTimeout uint `form:"first_byte_timeout,omitempty"`
BetweenBytesTimeout uint `form:"between_bytes_timeout,omitempty"` BetweenBytesTimeout uint `form:"between_bytes_timeout,omitempty"`
AutoLoadbalance bool `form:"auto_loadbalance,omitempty"` AutoLoadbalance *Compatibool `form:"auto_loadbalance,omitempty"`
Weight uint `form:"weight,omitempty"` Weight uint `form:"weight,omitempty"`
RequestCondition string `form:"request_condition,omitempty"` RequestCondition string `form:"request_condition,omitempty"`
HealthCheck string `form:"healthcheck,omitempty"` HealthCheck string `form:"healthcheck,omitempty"`
UseSSL bool `form:"use_ssl,omitempty"` Shield string `form:"shield,omitempty"`
SSLCheckCert bool `form:"ssl_check_cert,omitempty"` UseSSL *Compatibool `form:"use_ssl,omitempty"`
SSLHostname string `form:"ssl_hostname,omitempty"` SSLCheckCert *Compatibool `form:"ssl_check_cert,omitempty"`
SSLCertHostname string `form:"ssl_cert_hostname,omitempty"` SSLHostname string `form:"ssl_hostname,omitempty"`
SSLSNIHostname string `form:"ssl_sni_hostname,omitempty"` SSLCertHostname string `form:"ssl_cert_hostname,omitempty"`
MinTLSVersion string `form:"min_tls_version,omitempty"` SSLSNIHostname string `form:"ssl_sni_hostname,omitempty"`
MaxTLSVersion string `form:"max_tls_version,omitempty"` MinTLSVersion string `form:"min_tls_version,omitempty"`
SSLCiphers []string `form:"ssl_ciphers,omitempty"` MaxTLSVersion string `form:"max_tls_version,omitempty"`
SSLCiphers []string `form:"ssl_ciphers,omitempty"`
} }
// UpdateBackend updates a specific backend. // UpdateBackend updates a specific backend.

View File

@ -195,10 +195,11 @@ func (c *Client) DeleteDictionary(i *DeleteDictionaryInput) error {
} }
path := fmt.Sprintf("/service/%s/version/%s/dictionary/%s", i.Service, i.Version, i.Name) path := fmt.Sprintf("/service/%s/version/%s/dictionary/%s", i.Service, i.Version, i.Name)
_, err := c.Delete(path, nil) resp, err := c.Delete(path, nil)
if err != nil { if err != nil {
return err return err
} }
defer resp.Body.Close()
// Unlike other endpoints, the dictionary endpoint does not return a status // Unlike other endpoints, the dictionary endpoint does not return a status
// response - it just returns a 200 OK. // response - it just returns a 200 OK.

View File

@ -196,10 +196,11 @@ func (c *Client) DeleteDictionaryItem(i *DeleteDictionaryItemInput) error {
} }
path := fmt.Sprintf("/service/%s/dictionary/%s/item/%s", i.Service, i.Dictionary, i.ItemKey) path := fmt.Sprintf("/service/%s/dictionary/%s/item/%s", i.Service, i.Dictionary, i.ItemKey)
_, err := c.Delete(path, nil) resp, err := c.Delete(path, nil)
if err != nil { if err != nil {
return err return err
} }
defer resp.Body.Close()
// Unlike other endpoints, the dictionary endpoint does not return a status // Unlike other endpoints, the dictionary endpoint does not return a status
// response - it just returns a 200 OK. // response - it just returns a 200 OK.

View File

@ -20,6 +20,12 @@ var (
_ encoding.TextUnmarshaler = new(Compatibool) _ encoding.TextUnmarshaler = new(Compatibool)
) )
// Helper function to get a pointer to bool
func CBool(b bool) *Compatibool {
c := Compatibool(b)
return &c
}
// Compatibool is a boolean value that marshalls to 0/1 instead of true/false // Compatibool is a boolean value that marshalls to 0/1 instead of true/false
// for compatability with Fastly's API. // for compatability with Fastly's API.
type Compatibool bool type Compatibool bool

View File

@ -119,7 +119,7 @@ type CreateHeaderInput struct {
Name string `form:"name,omitempty"` Name string `form:"name,omitempty"`
Action HeaderAction `form:"action,omitempty"` Action HeaderAction `form:"action,omitempty"`
IgnoreIfSet Compatibool `form:"ignore_if_set,omitempty"` IgnoreIfSet *Compatibool `form:"ignore_if_set,omitempty"`
Type HeaderType `form:"type,omitempty"` Type HeaderType `form:"type,omitempty"`
Destination string `form:"dst,omitempty"` Destination string `form:"dst,omitempty"`
Source string `form:"src,omitempty"` Source string `form:"src,omitempty"`
@ -204,7 +204,7 @@ type UpdateHeaderInput struct {
NewName string `form:"name,omitempty"` NewName string `form:"name,omitempty"`
Action HeaderAction `form:"action,omitempty"` Action HeaderAction `form:"action,omitempty"`
IgnoreIfSet Compatibool `form:"ignore_if_set,omitempty"` IgnoreIfSet *Compatibool `form:"ignore_if_set,omitempty"`
Type HeaderType `form:"type,omitempty"` Type HeaderType `form:"type,omitempty"`
Destination string `form:"dst,omitempty"` Destination string `form:"dst,omitempty"`
Source string `form:"src,omitempty"` Source string `form:"src,omitempty"`

View File

@ -72,12 +72,12 @@ type CreateLogentriesInput struct {
Service string Service string
Version string Version string
Name string `form:"name,omitempty"` Name string `form:"name,omitempty"`
Port uint `form:"port,omitempty"` Port uint `form:"port,omitempty"`
UseTLS Compatibool `form:"use_tls,omitempty"` UseTLS *Compatibool `form:"use_tls,omitempty"`
Token string `form:"token,omitempty"` Token string `form:"token,omitempty"`
Format string `form:"format,omitempty"` Format string `form:"format,omitempty"`
ResponseCondition string `form:"response_condition,omitempty"` ResponseCondition string `form:"response_condition,omitempty"`
} }
// CreateLogentries creates a new Fastly logentries. // CreateLogentries creates a new Fastly logentries.
@ -151,12 +151,12 @@ type UpdateLogentriesInput struct {
// Name is the name of the logentries to update. // Name is the name of the logentries to update.
Name string Name string
NewName string `form:"name,omitempty"` NewName string `form:"name,omitempty"`
Port uint `form:"port,omitempty"` Port uint `form:"port,omitempty"`
UseTLS Compatibool `form:"use_tls,omitempty"` UseTLS *Compatibool `form:"use_tls,omitempty"`
Token string `form:"token,omitempty"` Token string `form:"token,omitempty"`
Format string `form:"format,omitempty"` Format string `form:"format,omitempty"`
ResponseCondition string `form:"response_condition,omitempty"` ResponseCondition string `form:"response_condition,omitempty"`
} }
// UpdateLogentries updates a specific logentries. // UpdateLogentries updates a specific logentries.

View File

@ -110,15 +110,15 @@ type CreateRequestSettingInput struct {
Version string Version string
Name string `form:"name,omitempty"` Name string `form:"name,omitempty"`
ForceMiss Compatibool `form:"force_miss,omitempty"` ForceMiss *Compatibool `form:"force_miss,omitempty"`
ForceSSL Compatibool `form:"force_ssl,omitempty"` ForceSSL *Compatibool `form:"force_ssl,omitempty"`
Action RequestSettingAction `form:"action,omitempty"` Action RequestSettingAction `form:"action,omitempty"`
BypassBusyWait Compatibool `form:"bypass_busy_wait,omitempty"` BypassBusyWait *Compatibool `form:"bypass_busy_wait,omitempty"`
MaxStaleAge uint `form:"max_stale_age,omitempty"` MaxStaleAge uint `form:"max_stale_age,omitempty"`
HashKeys string `form:"hash_keys,omitempty"` HashKeys string `form:"hash_keys,omitempty"`
XForwardedFor RequestSettingXFF `form:"xff,omitempty"` XForwardedFor RequestSettingXFF `form:"xff,omitempty"`
TimerSupport Compatibool `form:"timer_support,omitempty"` TimerSupport *Compatibool `form:"timer_support,omitempty"`
GeoHeaders Compatibool `form:"geo_headers,omitempty"` GeoHeaders *Compatibool `form:"geo_headers,omitempty"`
DefaultHost string `form:"default_host,omitempty"` DefaultHost string `form:"default_host,omitempty"`
RequestCondition string `form:"request_condition,omitempty"` RequestCondition string `form:"request_condition,omitempty"`
} }
@ -197,15 +197,15 @@ type UpdateRequestSettingInput struct {
Name string Name string
NewName string `form:"name,omitempty"` NewName string `form:"name,omitempty"`
ForceMiss Compatibool `form:"force_miss,omitempty"` ForceMiss *Compatibool `form:"force_miss,omitempty"`
ForceSSL Compatibool `form:"force_ssl,omitempty"` ForceSSL *Compatibool `form:"force_ssl,omitempty"`
Action RequestSettingAction `form:"action,omitempty"` Action RequestSettingAction `form:"action,omitempty"`
BypassBusyWait Compatibool `form:"bypass_busy_wait,omitempty"` BypassBusyWait *Compatibool `form:"bypass_busy_wait,omitempty"`
MaxStaleAge uint `form:"max_stale_age,omitempty"` MaxStaleAge uint `form:"max_stale_age,omitempty"`
HashKeys string `form:"hash_keys,omitempty"` HashKeys string `form:"hash_keys,omitempty"`
XForwardedFor RequestSettingXFF `form:"xff,omitempty"` XForwardedFor RequestSettingXFF `form:"xff,omitempty"`
TimerSupport Compatibool `form:"timer_support,omitempty"` TimerSupport *Compatibool `form:"timer_support,omitempty"`
GeoHeaders Compatibool `form:"geo_headers,omitempty"` GeoHeaders *Compatibool `form:"geo_headers,omitempty"`
DefaultHost string `form:"default_host,omitempty"` DefaultHost string `form:"default_host,omitempty"`
RequestCondition string `form:"request_condition,omitempty"` RequestCondition string `form:"request_condition,omitempty"`
} }

View File

@ -74,14 +74,14 @@ type CreateSyslogInput struct {
Service string Service string
Version string Version string
Name string `form:"name,omitempty"` Name string `form:"name,omitempty"`
Address string `form:"address,omitempty"` Address string `form:"address,omitempty"`
Port uint `form:"port,omitempty"` Port uint `form:"port,omitempty"`
UseTLS Compatibool `form:"use_tls,omitempty"` UseTLS *Compatibool `form:"use_tls,omitempty"`
TLSCACert string `form:"tls_ca_cert,omitempty"` TLSCACert string `form:"tls_ca_cert,omitempty"`
Token string `form:"token,omitempty"` Token string `form:"token,omitempty"`
Format string `form:"format,omitempty"` Format string `form:"format,omitempty"`
ResponseCondition string `form:"response_condition,omitempty"` ResponseCondition string `form:"response_condition,omitempty"`
} }
// CreateSyslog creates a new Fastly syslog. // CreateSyslog creates a new Fastly syslog.
@ -155,14 +155,14 @@ type UpdateSyslogInput struct {
// Name is the name of the syslog to update. // Name is the name of the syslog to update.
Name string Name string
NewName string `form:"name,omitempty"` NewName string `form:"name,omitempty"`
Address string `form:"address,omitempty"` Address string `form:"address,omitempty"`
Port uint `form:"port,omitempty"` Port uint `form:"port,omitempty"`
UseTLS Compatibool `form:"use_tls,omitempty"` UseTLS *Compatibool `form:"use_tls,omitempty"`
TLSCACert string `form:"tls_ca_cert,omitempty"` TLSCACert string `form:"tls_ca_cert,omitempty"`
Token string `form:"token,omitempty"` Token string `form:"token,omitempty"`
Format string `form:"format,omitempty"` Format string `form:"format,omitempty"`
ResponseCondition string `form:"response_condition,omitempty"` ResponseCondition string `form:"response_condition,omitempty"`
} }
// UpdateSyslog updates a specific syslog. // UpdateSyslog updates a specific syslog.

6
vendor/vendor.json vendored
View File

@ -2194,10 +2194,10 @@
"revisionTime": "2016-10-27T15:40:24Z" "revisionTime": "2016-10-27T15:40:24Z"
}, },
{ {
"checksumSHA1": "DWJoWDXcRi4HUCyxU6dLVVjR4pI=", "checksumSHA1": "BqtlwAjgFuHsVVdnw+dGSe+CKLM=",
"path": "github.com/sethvargo/go-fastly", "path": "github.com/sethvargo/go-fastly",
"revision": "b0a18d43769d55365d4fbd9ba36493e5c0dcd8f5", "revision": "2f6c4b7ec89b1e3ece8e770af7b2b546c5a048de",
"revisionTime": "2016-07-08T18:18:56Z" "revisionTime": "2016-10-26T14:57:03Z"
}, },
{ {
"comment": "v1.1-2-g5578a8c", "comment": "v1.1-2-g5578a8c",