@@ -2271,6 +2271,164 @@ func TestProviderImportState(t *testing.T) {
22712271 }
22722272}
22732273
2274+ func TestProviderImportStateWithIdentity (t * testing.T ) {
2275+ t .Parallel ()
2276+
2277+ testCases := map [string ]struct {
2278+ provider * Provider
2279+ info * terraform.InstanceInfo
2280+ id string
2281+ identity map [string ]string
2282+ expectedStates []* terraform.InstanceState
2283+ expectedErr error
2284+ }{
2285+ "error-missing-identity-schema" : {
2286+ provider : & Provider {
2287+ ResourcesMap : map [string ]* Resource {
2288+ "test_resource" : {
2289+ Importer : & ResourceImporter {},
2290+ // no identity schema defined
2291+ },
2292+ },
2293+ },
2294+ identity : map [string ]string {
2295+ "id" : "test-id" ,
2296+ },
2297+ info : & terraform.InstanceInfo {
2298+ Type : "test_resource" ,
2299+ },
2300+ expectedErr : fmt .Errorf ("resource test_resource doesn't support identity import" ),
2301+ },
2302+ "error-missing-ResourceData-Id" : {
2303+ provider : & Provider {
2304+ ResourcesMap : map [string ]* Resource {
2305+ "test_resource" : {
2306+ Importer : & ResourceImporter {
2307+ StateContext : func (_ context.Context , d * ResourceData , _ interface {}) ([]* ResourceData , error ) {
2308+ // Example for handling import based on identity but not
2309+ // setting the id even though it's still required to be set
2310+ d .SetId ("" )
2311+ return []* ResourceData {d }, nil
2312+ },
2313+ },
2314+ Identity : & ResourceIdentity {
2315+ Version : 1 ,
2316+ SchemaFunc : func () map [string ]* Schema {
2317+ return map [string ]* Schema {
2318+ "id" : {
2319+ Type : TypeString ,
2320+ RequiredForImport : true ,
2321+ },
2322+ }
2323+ },
2324+ },
2325+ },
2326+ },
2327+ },
2328+ info : & terraform.InstanceInfo {
2329+ Type : "test_resource" ,
2330+ },
2331+ identity : map [string ]string {
2332+ "id" : "test-id" ,
2333+ },
2334+ expectedErr : fmt .Errorf ("The provider returned a resource missing an identifier during ImportResourceState." ),
2335+ },
2336+ "Importer-StateContext-from-identity" : {
2337+ provider : & Provider {
2338+ ResourcesMap : map [string ]* Resource {
2339+ "test_resource" : {
2340+ Importer : & ResourceImporter {
2341+ StateContext : func (_ context.Context , d * ResourceData , meta interface {}) ([]* ResourceData , error ) {
2342+ if d .Id () != "" {
2343+ return nil , fmt .Errorf ("expected d.Id() to be empty, got: %s" , d .Id ())
2344+ }
2345+
2346+ identity , err := d .Identity ()
2347+ if err != nil {
2348+ return nil , fmt .Errorf ("error getting identity: %s" , err )
2349+ }
2350+ id , exists := identity .GetOk ("id" )
2351+ if ! exists {
2352+ return nil , fmt .Errorf ("expected identity to contain key id" )
2353+ }
2354+ if id != "test-id" {
2355+ return nil , fmt .Errorf ("expected identity id %q, got: %s" , "test-id" , id )
2356+ }
2357+
2358+ // set region as we act as if it's derived from provider defaults
2359+ err = identity .Set ("region" , "eu-central-1" )
2360+ if err != nil {
2361+ return nil , fmt .Errorf ("error setting identity region: %s" , err )
2362+ }
2363+ // set the id as well
2364+ d .SetId (id .(string ))
2365+
2366+ return []* ResourceData {d }, nil
2367+ },
2368+ },
2369+ Identity : & ResourceIdentity {
2370+ Version : 1 ,
2371+ SchemaFunc : func () map [string ]* Schema {
2372+ return map [string ]* Schema {
2373+ "id" : {
2374+ Type : TypeString ,
2375+ RequiredForImport : true ,
2376+ },
2377+ "region" : {
2378+ Type : TypeString ,
2379+ OptionalForImport : true ,
2380+ },
2381+ }
2382+ },
2383+ },
2384+ },
2385+ },
2386+ },
2387+ info : & terraform.InstanceInfo {
2388+ Type : "test_resource" ,
2389+ },
2390+ identity : map [string ]string {
2391+ "id" : "test-id" ,
2392+ },
2393+ expectedStates : []* terraform.InstanceState {
2394+ {
2395+ Attributes : map [string ]string {"id" : "test-id" },
2396+ Ephemeral : terraform.EphemeralState {Type : "test_resource" },
2397+ ID : "test-id" ,
2398+ Identity : map [string ]string {"id" : "test-id" , "region" : "eu-central-1" },
2399+ Meta : map [string ]interface {}{"schema_version" : "0" },
2400+ },
2401+ },
2402+ },
2403+ }
2404+
2405+ for name , testCase := range testCases {
2406+ t .Run (name , func (t * testing.T ) {
2407+ t .Parallel ()
2408+
2409+ states , err := testCase .provider .ImportStateWithIdentity (context .Background (), testCase .info , testCase .id , testCase .identity )
2410+
2411+ if err != nil {
2412+ if testCase .expectedErr == nil {
2413+ t .Fatalf ("unexpected error: %s" , err )
2414+ }
2415+
2416+ if ! strings .Contains (err .Error (), testCase .expectedErr .Error ()) {
2417+ t .Fatalf ("expected error %q, got: %s" , testCase .expectedErr , err )
2418+ }
2419+ }
2420+
2421+ if err == nil && testCase .expectedErr != nil {
2422+ t .Fatalf ("expected error %q, got none" , testCase .expectedErr )
2423+ }
2424+
2425+ if diff := cmp .Diff (states , testCase .expectedStates ); diff != "" {
2426+ t .Fatalf ("unexpected states difference: %s" , diff )
2427+ }
2428+ })
2429+ }
2430+ }
2431+
22742432func TestProviderMeta (t * testing.T ) {
22752433 p := new (Provider )
22762434 if v := p .Meta (); v != nil {
0 commit comments