2018-03-26 23:53:35 +00:00
package google
import (
"fmt"
"time"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
2018-04-24 21:43:00 +00:00
compute "google.golang.org/api/compute/v1"
2018-03-26 23:53:35 +00:00
)
func resourceComputeSslPolicy ( ) * schema . Resource {
return & schema . Resource {
Create : resourceComputeSslPolicyCreate ,
Read : resourceComputeSslPolicyRead ,
Update : resourceComputeSslPolicyUpdate ,
Delete : resourceComputeSslPolicyDelete ,
Importer : & schema . ResourceImporter {
State : schema . ImportStatePassthrough ,
} ,
Timeouts : & schema . ResourceTimeout {
Create : schema . DefaultTimeout ( 2 * time . Minute ) ,
Update : schema . DefaultTimeout ( 2 * time . Minute ) ,
Delete : schema . DefaultTimeout ( 2 * time . Minute ) ,
} ,
Schema : map [ string ] * schema . Schema {
"name" : & schema . Schema {
Type : schema . TypeString ,
Required : true ,
ForceNew : true ,
} ,
"custom_features" : & schema . Schema {
Type : schema . TypeSet ,
Optional : true ,
Elem : & schema . Schema { Type : schema . TypeString } ,
Set : schema . HashString ,
} ,
"description" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
ForceNew : true , // currently, the beta patch API call does not allow updating the description
} ,
"min_tls_version" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
Default : "TLS_1_0" ,
// Although compute-gen.go says that TLS_1_3 is a valid value, the API currently (26 Mar 2018)
// responds with an HTTP 200 but doesn't actually create/update the policy. Open bug for this:
// https://issuetracker.google.com/issues/76433946
ValidateFunc : validation . StringInSlice ( [ ] string { "TLS_1_0" , "TLS_1_1" , "TLS_1_2" } , false ) ,
} ,
"profile" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
Default : "COMPATIBLE" ,
ValidateFunc : validation . StringInSlice ( [ ] string { "COMPATIBLE" , "MODERN" , "RESTRICTED" , "CUSTOM" } , false ) ,
} ,
"project" : & schema . Schema {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
ForceNew : true ,
} ,
"enabled_features" : & schema . Schema {
Type : schema . TypeSet ,
Computed : true ,
Elem : & schema . Schema { Type : schema . TypeString } ,
Set : schema . HashString ,
} ,
"fingerprint" : & schema . Schema {
Type : schema . TypeString ,
Computed : true ,
} ,
"self_link" : & schema . Schema {
Type : schema . TypeString ,
Computed : true ,
} ,
} ,
CustomizeDiff : func ( diff * schema . ResourceDiff , v interface { } ) error {
profile := diff . Get ( "profile" )
customFeaturesCount := diff . Get ( "custom_features.#" )
// Validate that policy configs aren't incompatible during all phases
// CUSTOM profile demands non-zero custom_features, and other profiles (i.e., not CUSTOM) demand zero custom_features
if diff . HasChange ( "profile" ) || diff . HasChange ( "custom_features" ) {
if profile . ( string ) == "CUSTOM" {
if customFeaturesCount . ( int ) == 0 {
return fmt . Errorf ( "Error in SSL Policy %s: the profile is set to %s but no custom_features are set." , diff . Get ( "name" ) , profile . ( string ) )
}
} else {
if customFeaturesCount != 0 {
return fmt . Errorf ( "Error in SSL Policy %s: the profile is set to %s but using custom_features requires the profile to be CUSTOM." , diff . Get ( "name" ) , profile . ( string ) )
}
}
return nil
}
return nil
} ,
}
}
func resourceComputeSslPolicyCreate ( d * schema . ResourceData , meta interface { } ) error {
config := meta . ( * Config )
project , err := getProject ( d , config )
if err != nil {
return err
}
2018-04-24 21:43:00 +00:00
sslPolicy := & compute . SslPolicy {
2018-03-26 23:53:35 +00:00
Name : d . Get ( "name" ) . ( string ) ,
Description : d . Get ( "description" ) . ( string ) ,
Profile : d . Get ( "profile" ) . ( string ) ,
MinTlsVersion : d . Get ( "min_tls_version" ) . ( string ) ,
CustomFeatures : convertStringSet ( d . Get ( "custom_features" ) . ( * schema . Set ) ) ,
}
2018-04-24 21:43:00 +00:00
op , err := config . clientCompute . SslPolicies . Insert ( project , sslPolicy ) . Do ( )
2018-03-26 23:53:35 +00:00
if err != nil {
return fmt . Errorf ( "Error creating SSL Policy: %s" , err )
}
d . SetId ( sslPolicy . Name )
err = computeSharedOperationWaitTime ( config . clientCompute , op , project , int ( d . Timeout ( schema . TimeoutCreate ) . Minutes ( ) ) , "Creating SSL Policy" )
if err != nil {
d . SetId ( "" ) // if insert fails, remove from state
return err
}
return resourceComputeSslPolicyRead ( d , meta )
}
func resourceComputeSslPolicyRead ( d * schema . ResourceData , meta interface { } ) error {
config := meta . ( * Config )
project , err := getProject ( d , config )
if err != nil {
return err
}
name := d . Id ( )
2018-04-24 21:43:00 +00:00
sslPolicy , err := config . clientCompute . SslPolicies . Get ( project , name ) . Do ( )
2018-03-26 23:53:35 +00:00
if err != nil {
return handleNotFoundError ( err , d , fmt . Sprintf ( "SSL Policy %q" , name ) )
}
d . Set ( "name" , sslPolicy . Name )
d . Set ( "description" , sslPolicy . Description )
d . Set ( "min_tls_version" , sslPolicy . MinTlsVersion )
d . Set ( "profile" , sslPolicy . Profile )
d . Set ( "fingerprint" , sslPolicy . Fingerprint )
d . Set ( "project" , project )
d . Set ( "self_link" , ConvertSelfLinkToV1 ( sslPolicy . SelfLink ) )
d . Set ( "enabled_features" , convertStringArrToInterface ( sslPolicy . EnabledFeatures ) )
d . Set ( "custom_features" , convertStringArrToInterface ( sslPolicy . CustomFeatures ) )
d . SetId ( sslPolicy . Name )
return nil
}
func resourceComputeSslPolicyUpdate ( d * schema . ResourceData , meta interface { } ) error {
config := meta . ( * Config )
project , err := getProject ( d , config )
if err != nil {
return err
}
name := d . Get ( "name" ) . ( string )
2018-04-24 21:43:00 +00:00
sslPolicy := & compute . SslPolicy {
2018-03-26 23:53:35 +00:00
Fingerprint : d . Get ( "fingerprint" ) . ( string ) ,
Profile : d . Get ( "profile" ) . ( string ) ,
MinTlsVersion : d . Get ( "min_tls_version" ) . ( string ) ,
}
if v , ok := d . Get ( "custom_features" ) . ( * schema . Set ) ; ok {
if v . Len ( ) > 0 {
sslPolicy . CustomFeatures = convertStringSet ( v )
} else {
sslPolicy . NullFields = append ( sslPolicy . NullFields , "CustomFeatures" )
}
}
2018-04-24 21:43:00 +00:00
op , err := config . clientCompute . SslPolicies . Patch ( project , name , sslPolicy ) . Do ( )
2018-03-26 23:53:35 +00:00
if err != nil {
return fmt . Errorf ( "Error updating SSL Policy: %s" , err )
}
err = computeSharedOperationWaitTime ( config . clientCompute , op , project , int ( d . Timeout ( schema . TimeoutUpdate ) . Minutes ( ) ) , "Updating SSL Policy" )
if err != nil {
return err
}
return resourceComputeSslPolicyRead ( d , meta )
}
func resourceComputeSslPolicyDelete ( d * schema . ResourceData , meta interface { } ) error {
config := meta . ( * Config )
project , err := getProject ( d , config )
if err != nil {
return err
}
name := d . Get ( "name" ) . ( string )
2018-04-24 21:43:00 +00:00
op , err := config . clientCompute . SslPolicies . Delete ( project , name ) . Do ( )
2018-03-26 23:53:35 +00:00
if err != nil {
return fmt . Errorf ( "Error deleting SSL Policy: %s" , err )
}
err = computeSharedOperationWaitTime ( config . clientCompute , op , project , int ( d . Timeout ( schema . TimeoutDelete ) . Minutes ( ) ) , "Deleting Subnetwork" )
if err != nil {
return err
}
d . SetId ( "" )
return nil
}