Merge pull request #766 from hashicorp/f-exists-api
helper/schema: Exists API
This commit is contained in:
commit
466a54cfe4
|
@ -41,10 +41,17 @@ type Resource struct {
|
|||
// If any errors occur during each of the operation, an error should be
|
||||
// returned. If a resource was partially updated, be careful to enable
|
||||
// partial state mode for ResourceData and use it accordingly.
|
||||
//
|
||||
// Exists is a function that is called to check if a resource still
|
||||
// exists. If this returns false, then this will affect the diff
|
||||
// accordingly. If this function isn't set, it will not be called. It
|
||||
// is highly recommended to set it. The *ResourceData passed to Exists
|
||||
// should _not_ be modified.
|
||||
Create CreateFunc
|
||||
Read ReadFunc
|
||||
Update UpdateFunc
|
||||
Delete DeleteFunc
|
||||
Exists ExistsFunc
|
||||
}
|
||||
|
||||
// See Resource documentation.
|
||||
|
@ -59,6 +66,9 @@ type UpdateFunc func(*ResourceData, interface{}) error
|
|||
// See Resource documentation.
|
||||
type DeleteFunc func(*ResourceData, interface{}) error
|
||||
|
||||
// See Resource documentation.
|
||||
type ExistsFunc func(*ResourceData, interface{}) (bool, error)
|
||||
|
||||
// Apply creates, updates, and/or deletes a resource.
|
||||
func (r *Resource) Apply(
|
||||
s *terraform.InstanceState,
|
||||
|
@ -131,6 +141,23 @@ func (r *Resource) Validate(c *terraform.ResourceConfig) ([]string, []error) {
|
|||
func (r *Resource) Refresh(
|
||||
s *terraform.InstanceState,
|
||||
meta interface{}) (*terraform.InstanceState, error) {
|
||||
if r.Exists != nil {
|
||||
// Make a copy of data so that if it is modified it doesn't
|
||||
// affect our Read later.
|
||||
data, err := schemaMap(r.Schema).Data(s, nil)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
exists, err := r.Exists(data, meta)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
data, err := schemaMap(r.Schema).Data(s, nil)
|
||||
if err != nil {
|
||||
return s, err
|
||||
|
|
|
@ -410,3 +410,71 @@ func TestResourceRefresh_delete(t *testing.T) {
|
|||
t.Fatalf("bad: %#v", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourceRefresh_existsError(t *testing.T) {
|
||||
r := &Resource{
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
r.Exists = func(*ResourceData, interface{}) (bool, error) {
|
||||
return false, fmt.Errorf("error")
|
||||
}
|
||||
|
||||
r.Read = func(d *ResourceData, m interface{}) error {
|
||||
panic("shouldn't be called")
|
||||
}
|
||||
|
||||
s := &terraform.InstanceState{
|
||||
ID: "bar",
|
||||
Attributes: map[string]string{
|
||||
"foo": "12",
|
||||
},
|
||||
}
|
||||
|
||||
actual, err := r.Refresh(s, 42)
|
||||
if err == nil {
|
||||
t.Fatalf("should error")
|
||||
}
|
||||
if !reflect.DeepEqual(actual, s) {
|
||||
t.Fatalf("bad: %#v", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourceRefresh_noExists(t *testing.T) {
|
||||
r := &Resource{
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
r.Exists = func(*ResourceData, interface{}) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
r.Read = func(d *ResourceData, m interface{}) error {
|
||||
panic("shouldn't be called")
|
||||
}
|
||||
|
||||
s := &terraform.InstanceState{
|
||||
ID: "bar",
|
||||
Attributes: map[string]string{
|
||||
"foo": "12",
|
||||
},
|
||||
}
|
||||
|
||||
actual, err := r.Refresh(s, 42)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if actual != nil {
|
||||
t.Fatalf("should have no state")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,6 +158,10 @@ The CRUD operations in more detail, along with their contracts:
|
|||
* `Delete` - This is called to delete the resource. Terraform guarantees
|
||||
an existing ID will be set.
|
||||
|
||||
* `Exists` - This is called to verify a resource still exists. It is
|
||||
called prior to `Read`, and lowers the burden of `Read` to be able
|
||||
to assume the resource exists.
|
||||
|
||||
## Schemas
|
||||
|
||||
Both providers and resources require a schema to be specified. The schema
|
||||
|
|
Loading…
Reference in New Issue