github.com/gophercloud/gophercloud@v1.11.0/internal/acceptance/openstack/identity/v3/applicationcredentials_test.go (about)

     1  //go:build acceptance
     2  // +build acceptance
     3  
     4  package v3
     5  
     6  import (
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/gophercloud/gophercloud/internal/acceptance/clients"
    11  	"github.com/gophercloud/gophercloud/internal/acceptance/tools"
    12  	"github.com/gophercloud/gophercloud/openstack"
    13  	"github.com/gophercloud/gophercloud/openstack/identity/v3/applicationcredentials"
    14  	"github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
    15  	th "github.com/gophercloud/gophercloud/testhelper"
    16  )
    17  
    18  func TestApplicationCredentialsCRD(t *testing.T) {
    19  	// maps are required, because Application Credential roles are returned in a random order
    20  	rolesToMap := func(roles []applicationcredentials.Role) map[string]string {
    21  		rolesMap := map[string]string{}
    22  		for _, role := range roles {
    23  			rolesMap[role.Name] = role.Name
    24  			rolesMap[role.ID] = role.ID
    25  		}
    26  		return rolesMap
    27  	}
    28  
    29  	client, err := clients.NewIdentityV3Client()
    30  	th.AssertNoErr(t, err)
    31  
    32  	ao, err := openstack.AuthOptionsFromEnv()
    33  	th.AssertNoErr(t, err)
    34  
    35  	authOptions := tokens.AuthOptions{
    36  		Username:   ao.Username,
    37  		Password:   ao.Password,
    38  		DomainName: ao.DomainName,
    39  		DomainID:   ao.DomainID,
    40  		// We need a scope to get the token roles list
    41  		Scope: tokens.Scope{
    42  			ProjectID:   ao.TenantID,
    43  			ProjectName: ao.TenantName,
    44  			DomainID:    ao.DomainID,
    45  			DomainName:  ao.DomainName,
    46  		},
    47  	}
    48  
    49  	token, err := tokens.Create(client, &authOptions).Extract()
    50  	th.AssertNoErr(t, err)
    51  	tools.PrintResource(t, token)
    52  
    53  	user, err := tokens.Get(client, token.ID).ExtractUser()
    54  	th.AssertNoErr(t, err)
    55  	tools.PrintResource(t, user)
    56  
    57  	roles, err := tokens.Get(client, token.ID).ExtractRoles()
    58  	th.AssertNoErr(t, err)
    59  	tools.PrintResource(t, roles)
    60  
    61  	project, err := tokens.Get(client, token.ID).ExtractProject()
    62  	th.AssertNoErr(t, err)
    63  	tools.PrintResource(t, project)
    64  
    65  	// prepare create parameters
    66  	var apRoles []applicationcredentials.Role
    67  	for i, role := range roles {
    68  		if i%2 == 0 {
    69  			apRoles = append(apRoles, applicationcredentials.Role{Name: role.Name})
    70  		} else {
    71  			apRoles = append(apRoles, applicationcredentials.Role{ID: role.ID})
    72  		}
    73  		if i > 4 {
    74  			break
    75  		}
    76  	}
    77  	tools.PrintResource(t, apRoles)
    78  
    79  	// restricted, limited TTL, with limited roles, autogenerated secret
    80  	expiresAt := time.Now().Add(time.Minute).Truncate(time.Millisecond).UTC()
    81  	createOpts := applicationcredentials.CreateOpts{
    82  		Name:        "test-ac",
    83  		Description: "test application credential",
    84  		Roles:       apRoles,
    85  		ExpiresAt:   &expiresAt,
    86  	}
    87  
    88  	applicationCredential, err := applicationcredentials.Create(client, user.ID, createOpts).Extract()
    89  	th.AssertNoErr(t, err)
    90  	defer applicationcredentials.Delete(client, user.ID, applicationCredential.ID)
    91  	tools.PrintResource(t, applicationCredential)
    92  
    93  	if applicationCredential.Secret == "" {
    94  		t.Fatalf("Application credential secret was not generated")
    95  	}
    96  
    97  	th.AssertEquals(t, applicationCredential.ExpiresAt, expiresAt)
    98  	th.AssertEquals(t, applicationCredential.Name, createOpts.Name)
    99  	th.AssertEquals(t, applicationCredential.Description, createOpts.Description)
   100  	th.AssertEquals(t, applicationCredential.Unrestricted, false)
   101  	th.AssertEquals(t, applicationCredential.ProjectID, project.ID)
   102  
   103  	checkACroles := rolesToMap(applicationCredential.Roles)
   104  	for i, role := range roles {
   105  		if i%2 == 0 {
   106  			th.AssertEquals(t, checkACroles[role.Name], role.Name)
   107  		} else {
   108  			th.AssertEquals(t, checkACroles[role.ID], role.ID)
   109  		}
   110  		if i > 4 {
   111  			break
   112  		}
   113  	}
   114  
   115  	// Get an application credential
   116  	getApplicationCredential, err := applicationcredentials.Get(client, user.ID, applicationCredential.ID).Extract()
   117  	th.AssertNoErr(t, err)
   118  	tools.PrintResource(t, getApplicationCredential)
   119  
   120  	if getApplicationCredential.Secret != "" {
   121  		t.Fatalf("Application credential secret should not be returned by a GET request")
   122  	}
   123  
   124  	th.AssertEquals(t, getApplicationCredential.ExpiresAt, expiresAt)
   125  	th.AssertEquals(t, getApplicationCredential.Name, createOpts.Name)
   126  	th.AssertEquals(t, getApplicationCredential.Description, createOpts.Description)
   127  	th.AssertEquals(t, getApplicationCredential.Unrestricted, false)
   128  	th.AssertEquals(t, getApplicationCredential.ProjectID, project.ID)
   129  
   130  	checkACroles = rolesToMap(getApplicationCredential.Roles)
   131  	for i, role := range roles {
   132  		if i%2 == 0 {
   133  			th.AssertEquals(t, checkACroles[role.Name], role.Name)
   134  		} else {
   135  			th.AssertEquals(t, checkACroles[role.ID], role.ID)
   136  		}
   137  		if i > 4 {
   138  			break
   139  		}
   140  	}
   141  
   142  	// unrestricted, unlimited TTL, with all possible roles, with a custom secret
   143  	createOpts = applicationcredentials.CreateOpts{
   144  		Name:         "super-test-ac",
   145  		Description:  "test unrestricted application credential",
   146  		Unrestricted: true,
   147  		Secret:       "myprecious",
   148  	}
   149  
   150  	newApplicationCredential, err := applicationcredentials.Create(client, user.ID, createOpts).Extract()
   151  	th.AssertNoErr(t, err)
   152  	defer applicationcredentials.Delete(client, user.ID, newApplicationCredential.ID)
   153  	tools.PrintResource(t, newApplicationCredential)
   154  
   155  	th.AssertEquals(t, newApplicationCredential.ExpiresAt, time.Time{})
   156  	th.AssertEquals(t, newApplicationCredential.Name, createOpts.Name)
   157  	th.AssertEquals(t, newApplicationCredential.Description, createOpts.Description)
   158  	th.AssertEquals(t, newApplicationCredential.Secret, createOpts.Secret)
   159  	th.AssertEquals(t, newApplicationCredential.Unrestricted, true)
   160  	th.AssertEquals(t, newApplicationCredential.ExpiresAt, time.Time{})
   161  	th.AssertEquals(t, newApplicationCredential.ProjectID, project.ID)
   162  
   163  	checkACroles = rolesToMap(newApplicationCredential.Roles)
   164  	for _, role := range roles {
   165  		th.AssertEquals(t, checkACroles[role.Name], role.Name)
   166  		th.AssertEquals(t, checkACroles[role.ID], role.ID)
   167  	}
   168  }
   169  
   170  func TestApplicationCredentialsAccessRules(t *testing.T) {
   171  	clients.RequireAdmin(t)
   172  
   173  	client, err := clients.NewIdentityV3Client()
   174  	th.AssertNoErr(t, err)
   175  
   176  	ao, err := openstack.AuthOptionsFromEnv()
   177  	th.AssertNoErr(t, err)
   178  
   179  	authOptions := tokens.AuthOptions{
   180  		Username:   ao.Username,
   181  		Password:   ao.Password,
   182  		DomainName: ao.DomainName,
   183  		DomainID:   ao.DomainID,
   184  		// We need a scope to get the token roles list
   185  		Scope: tokens.Scope{
   186  			ProjectID:   ao.TenantID,
   187  			ProjectName: ao.TenantName,
   188  			DomainID:    ao.DomainID,
   189  			DomainName:  ao.DomainName,
   190  		},
   191  	}
   192  
   193  	token, err := tokens.Create(client, &authOptions).Extract()
   194  	th.AssertNoErr(t, err)
   195  	tools.PrintResource(t, token)
   196  
   197  	user, err := tokens.Get(client, token.ID).ExtractUser()
   198  	th.AssertNoErr(t, err)
   199  	tools.PrintResource(t, user)
   200  
   201  	// prepare create parameters
   202  	apAccessRules := []applicationcredentials.AccessRule{
   203  		{
   204  			Path:    "/v2.0/metrics",
   205  			Service: "monitoring",
   206  			Method:  "GET",
   207  		},
   208  		{
   209  			Path:    "/v2.0/metrics",
   210  			Service: "monitoring",
   211  			Method:  "PUT",
   212  		},
   213  	}
   214  
   215  	tools.PrintResource(t, apAccessRules)
   216  
   217  	// restricted, limited TTL, with limited roles, autogenerated secret
   218  	expiresAt := time.Now().Add(time.Minute).Truncate(time.Millisecond).UTC()
   219  	createOpts := applicationcredentials.CreateOpts{
   220  		Name:        "test-ac",
   221  		Description: "test application credential",
   222  		AccessRules: apAccessRules,
   223  		ExpiresAt:   &expiresAt,
   224  	}
   225  
   226  	applicationCredential, err := applicationcredentials.Create(client, user.ID, createOpts).Extract()
   227  	th.AssertNoErr(t, err)
   228  	defer applicationcredentials.Delete(client, user.ID, applicationCredential.ID)
   229  	tools.PrintResource(t, applicationCredential)
   230  
   231  	if applicationCredential.Secret == "" {
   232  		t.Fatalf("Application credential secret was not generated")
   233  	}
   234  
   235  	th.AssertEquals(t, applicationCredential.ExpiresAt, expiresAt)
   236  	th.AssertEquals(t, applicationCredential.Name, createOpts.Name)
   237  	th.AssertEquals(t, applicationCredential.Description, createOpts.Description)
   238  	th.AssertEquals(t, applicationCredential.Unrestricted, false)
   239  
   240  	for i, rule := range applicationCredential.AccessRules {
   241  		th.AssertEquals(t, rule.Path, apAccessRules[i].Path)
   242  		th.AssertEquals(t, rule.Service, apAccessRules[i].Service)
   243  		th.AssertEquals(t, rule.Method, apAccessRules[i].Method)
   244  	}
   245  
   246  	// Get an application credential
   247  	getApplicationCredential, err := applicationcredentials.Get(client, user.ID, applicationCredential.ID).Extract()
   248  	th.AssertNoErr(t, err)
   249  	tools.PrintResource(t, getApplicationCredential)
   250  
   251  	if getApplicationCredential.Secret != "" {
   252  		t.Fatalf("Application credential secret should not be returned by a GET request")
   253  	}
   254  
   255  	th.AssertEquals(t, getApplicationCredential.ExpiresAt, expiresAt)
   256  	th.AssertEquals(t, getApplicationCredential.Name, createOpts.Name)
   257  	th.AssertEquals(t, getApplicationCredential.Description, createOpts.Description)
   258  	th.AssertEquals(t, getApplicationCredential.Unrestricted, false)
   259  
   260  	for i, rule := range applicationCredential.AccessRules {
   261  		th.AssertEquals(t, rule.Path, apAccessRules[i].Path)
   262  		th.AssertEquals(t, rule.Service, apAccessRules[i].Service)
   263  		th.AssertEquals(t, rule.Method, apAccessRules[i].Method)
   264  	}
   265  
   266  	// test list
   267  	allPages, err := applicationcredentials.ListAccessRules(client, user.ID).AllPages()
   268  	th.AssertNoErr(t, err)
   269  	actual, err := applicationcredentials.ExtractAccessRules(allPages)
   270  	th.AssertNoErr(t, err)
   271  	th.CheckDeepEquals(t, getApplicationCredential.AccessRules, actual)
   272  
   273  	// test individual get
   274  	for i, rule := range actual {
   275  		getRule, err := applicationcredentials.GetAccessRule(client, user.ID, rule.ID).Extract()
   276  		th.AssertNoErr(t, err)
   277  		th.CheckDeepEquals(t, actual[i], *getRule)
   278  	}
   279  
   280  	res := applicationcredentials.Delete(client, user.ID, applicationCredential.ID)
   281  	th.AssertNoErr(t, res.Err)
   282  
   283  	// test delete
   284  	for _, rule := range actual {
   285  		res := applicationcredentials.DeleteAccessRule(client, user.ID, rule.ID)
   286  		th.AssertNoErr(t, res.Err)
   287  	}
   288  
   289  	allPages, err = applicationcredentials.ListAccessRules(client, user.ID).AllPages()
   290  	th.AssertNoErr(t, err)
   291  	actual, err = applicationcredentials.ExtractAccessRules(allPages)
   292  	th.AssertNoErr(t, err)
   293  	th.AssertEquals(t, len(actual), 0)
   294  }