How to use CallAPI method of client Package

Best K6 code snippet using client.CallAPI

update_test.go

Source:update_test.go Github

copy

Full Screen

...17 // given18 suite := NewBrokerSuiteTest(t)19 defer suite.TearDown()20 iid := uuid.New().String()21 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", iid),22 `{23 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",24 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",25 "context": {26 "sm_platform_credentials": {27 "url": "https://sm.url",28 "credentials": {}29 },30 "globalaccount_id": "g-account-id",31 "subaccount_id": "sub-id",32 "user_id": "john.smith@email.com"33 },34 "parameters": {35 "name": "testing-cluster",36 "oidc": {37 "clientID": "id-initial",38 "signingAlgs": ["PS512"],39 "issuerURL": "https://issuer.url.com"40 }41 }42 }`)43 opID := suite.DecodeOperationID(resp)44 suite.processReconcilingByOperationID(opID)45 // when46 // OSB update:47 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", iid),48 `{49 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",50 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",51 "context": {52 "globalaccount_id": "g-account-id",53 "user_id": "john.smith@email.com"54 },55 "parameters": {56 "oidc": {57 "clientID": "id-ooo",58 "signingAlgs": ["RS256"],59 "issuerURL": "https://issuer.url.com"60 }61 }62 }`)63 assert.Equal(t, http.StatusAccepted, resp.StatusCode)64 upgradeOperationID := suite.DecodeOperationID(resp)65 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)66 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)67 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{68 GardenerConfig: &gqlschema.GardenerUpgradeInput{69 OidcConfig: &gqlschema.OIDCConfigInput{70 ClientID: "id-ooo",71 GroupsClaim: "groups",72 IssuerURL: "https://issuer.url.com",73 SigningAlgs: []string{"RS256"},74 UsernameClaim: "sub",75 UsernamePrefix: "-",76 },77 },78 Administrators: []string{"john.smith@email.com"},79 })80}81func TestUpdateFailedInstance(t *testing.T) {82 // given83 suite := NewBrokerSuiteTest(t)84 defer suite.TearDown()85 iid := uuid.New().String()86 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", iid),87 `{88 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",89 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",90 "context": {91 "sm_platform_credentials": {92 "url": "https://sm.url",93 "credentials": {}94 },95 "globalaccount_id": "g-account-id",96 "subaccount_id": "sub-id",97 "user_id": "john.smith@email.com"98 },99 "parameters": {100 "name": "testing-cluster"101 }102 }`)103 opID := suite.DecodeOperationID(resp)104 suite.failProvisioningByOperationID(opID)105 // when106 // OSB update:107 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", iid),108 `{109 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",110 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",111 "context": {112 "globalaccount_id": "g-account-id",113 "user_id": "john.smith@email.com"114 },115 "parameters": {116 "oidc": {117 "clientID": "id-ooo",118 "signingAlgs": ["RSA256"],119 "issuerURL": "https://issuer.url.com"120 }121 }122 }`)123 assert.Equal(t, http.StatusUnprocessableEntity, resp.StatusCode)124 errResponse := suite.DecodeErrorResponse(resp)125 assert.Equal(t, "Unable to process an update of a failed instance", errResponse.Description)126}127func TestUpdateDeprovisioningInstance(t *testing.T) {128 // given129 suite := NewBrokerSuiteTest(t)130 defer suite.TearDown()131 iid := uuid.New().String()132 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", iid),133 `{134 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",135 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",136 "context": {137 "sm_platform_credentials": {138 "url": "https://sm.url",139 "credentials": {}140 },141 "globalaccount_id": "g-account-id",142 "subaccount_id": "sub-id",143 "user_id": "john.smith@email.com"144 },145 "parameters": {146 "name": "testing-cluster"147 }148 }`)149 opID := suite.DecodeOperationID(resp)150 suite.processReconcilingByOperationID(opID)151 // deprovision152 resp = suite.CallAPI("DELETE", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", iid),153 ``)154 depOpID := suite.DecodeOperationID(resp)155 suite.WaitForOperationState(depOpID, domain.InProgress)156 // when157 // OSB update:158 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", iid),159 `{160 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",161 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",162 "context": {163 "globalaccount_id": "g-account-id",164 "user_id": "john.smith@email.com"165 },166 "parameters": {167 "oidc": {168 "clientID": "id-ooo",169 "signingAlgs": ["RSA256"],170 "issuerURL": "https://issuer.url.com"171 }172 }173 }`)174 assert.Equal(t, http.StatusUnprocessableEntity, resp.StatusCode)175 errResponse := suite.DecodeErrorResponse(resp)176 assert.Equal(t, "Unable to process an update of a deprovisioned instance", errResponse.Description)177}178func TestUpdateWithNoOIDCParams(t *testing.T) {179 // given180 suite := NewBrokerSuiteTest(t)181 defer suite.TearDown()182 iid := uuid.New().String()183 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", iid),184 `{185 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",186 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",187 "context": {188 "sm_platform_credentials": {189 "url": "https://sm.url",190 "credentials": {}191 },192 "globalaccount_id": "g-account-id",193 "subaccount_id": "sub-id",194 "user_id": "john.smith@email.com"195 },196 "parameters": {197 "name": "testing-cluster"198 }199 }`)200 opID := suite.DecodeOperationID(resp)201 suite.processReconcilingByOperationID(opID)202 // when203 // OSB update:204 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", iid),205 `{206 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",207 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",208 "context": {209 "globalaccount_id": "g-account-id",210 "user_id": "john.smith@email.com"211 },212 "parameters": {213 }214 }`)215 assert.Equal(t, http.StatusAccepted, resp.StatusCode)216 upgradeOperationID := suite.DecodeOperationID(resp)217 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)218 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)219 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{220 GardenerConfig: &gqlschema.GardenerUpgradeInput{221 OidcConfig: defaultOIDCConfig(),222 },223 Administrators: []string{"john.smith@email.com"},224 })225}226func TestUpdateWithNoOidcOnUpdate(t *testing.T) {227 // given228 suite := NewBrokerSuiteTest(t)229 defer suite.TearDown()230 iid := uuid.New().String()231 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", iid),232 `{233 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",234 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",235 "context": {236 "sm_platform_credentials": {237 "url": "https://sm.url",238 "credentials": {}239 },240 "globalaccount_id": "g-account-id",241 "subaccount_id": "sub-id",242 "user_id": "john.smith@email.com"243 },244 "parameters": {245 "name": "testing-cluster",246 "oidc": {247 "clientID": "id-ooo",248 "signingAlgs": ["RS256"],249 "issuerURL": "https://issuer.url.com"250 }251 }252 }`)253 opID := suite.DecodeOperationID(resp)254 suite.processReconcilingByOperationID(opID)255 // when256 // OSB update:257 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", iid),258 `{259 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",260 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",261 "context": {262 "globalaccount_id": "g-account-id",263 "user_id": "john.smith@email.com"264 },265 "parameters": {266 267 }268 }`)269 assert.Equal(t, http.StatusAccepted, resp.StatusCode)270 upgradeOperationID := suite.DecodeOperationID(resp)271 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)272 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)273 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{274 GardenerConfig: &gqlschema.GardenerUpgradeInput{275 OidcConfig: &gqlschema.OIDCConfigInput{276 ClientID: "id-ooo",277 GroupsClaim: "groups",278 IssuerURL: "https://issuer.url.com",279 SigningAlgs: []string{"RS256"},280 UsernameClaim: "sub",281 UsernamePrefix: "-",282 },283 },284 Administrators: []string{"john.smith@email.com"},285 })286}287func TestUpdateContext(t *testing.T) {288 // given289 suite := NewBrokerSuiteTest(t)290 defer suite.TearDown()291 iid := uuid.New().String()292 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", iid),293 `{294 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",295 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",296 "context": {297 "sm_platform_credentials": {298 "url": "https://sm.url",299 "credentials": {}300 },301 "globalaccount_id": "g-account-id",302 "subaccount_id": "sub-id",303 "user_id": "john.smith@email.com"304 },305 "parameters": {306 "name": "testing-cluster",307 "oidc": {308 "clientID": "id-ooo",309 "signingAlgs": ["RS384"],310 "issuerURL": "https://issuer.url.com"311 }312 }313 }`)314 opID := suite.DecodeOperationID(resp)315 suite.processReconcilingByOperationID(opID)316 // when317 // OSB update318 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s", iid),319 `{320 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",321 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",322 "context": {323 "globalaccount_id": "g-account-id",324 "user_id": "john.smith@email.com"325 }326 }`)327 assert.Equal(t, http.StatusOK, resp.StatusCode)328}329func TestUnsuspensionTrialKyma20(t *testing.T) {330 suite := NewBrokerSuiteTest(t)331 defer suite.TearDown()332 iid := uuid.New().String()333 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", iid),334 `{335 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",336 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",337 "context": {338 "sm_platform_credentials": {339 "url": "https://sm.url",340 "credentials": {}341 },342 "globalaccount_id": "g-account-id",343 "subaccount_id": "sub-id",344 "user_id": "john.smith@email.com"345 },346 "parameters": {347 "name": "testing-cluster",348 "kymaVersion":"2.0"349 }350 }`)351 opID := suite.DecodeOperationID(resp)352 suite.processReconcilingByOperationID(opID)353 suite.Log("*** Suspension ***")354 // Process Suspension355 // OSB context update (suspension)356 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/v2/service_instances/%s?accepts_incomplete=true", iid),357 `{358 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",359 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",360 "context": {361 "globalaccount_id": "g-account-id",362 "user_id": "john.smith@email.com",363 "active": false364 }365 }`)366 assert.Equal(t, http.StatusOK, resp.StatusCode)367 suspensionOpID := suite.WaitForLastOperation(iid, domain.InProgress)368 suite.MarkClustertConfigurationDeleted(iid)369 suite.FinishDeprovisioningOperationByProvisioner(suspensionOpID)370 suite.WaitForOperationState(suspensionOpID, domain.Succeeded)371 suite.RemoveFromReconcilerByInstanceID(iid)372 // OSB update373 suite.Log("*** Unsuspension ***")374 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/v2/service_instances/%s?accepts_incomplete=true", iid),375 `{376 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",377 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",378 "context": {379 "globalaccount_id": "g-account-id",380 "user_id": "john.smith@email.com",381 "active": true382 }383 384 }`)385 assert.Equal(t, http.StatusOK, resp.StatusCode)386 suite.processReconciliationByInstanceID(iid)387}388func TestUnsuspensionTrialWithDefaultProviderChangedForNonDefaultRegion(t *testing.T) {389 suite := NewBrokerSuiteTest(t)390 defer suite.TearDown()391 iid := uuid.New().String()392 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-us10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", iid),393 `{394 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",395 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",396 "context": {397 "sm_platform_credentials": {398 "url": "https://sm.url",399 "credentials": {}400 },401 "globalaccount_id": "g-account-id",402 "subaccount_id": "sub-id",403 "user_id": "john.smith@email.com"404 },405 "parameters": {406 "name": "testing-cluster"407 }408 }`)409 opID := suite.DecodeOperationID(resp)410 suite.processReconcilingByOperationID(opID)411 suite.Log("*** Suspension ***")412 // Process Suspension413 // OSB context update (suspension)414 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-us10/v2/service_instances/%s?accepts_incomplete=true", iid),415 `{416 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",417 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",418 "context": {419 "globalaccount_id": "g-account-id",420 "user_id": "john.smith@email.com",421 "active": false422 }423 }`)424 assert.Equal(t, http.StatusOK, resp.StatusCode)425 suspensionOpID := suite.WaitForLastOperation(iid, domain.InProgress)426 suite.FinishDeprovisioningByReconciler(suspensionOpID)427 suite.FinishDeprovisioningOperationByProvisioner(suspensionOpID)428 suite.WaitForOperationState(suspensionOpID, domain.Succeeded)429 // WHEN430 suite.ChangeDefaultTrialProvider(internal.AWS)431 // OSB update432 suite.Log("*** Unsuspension ***")433 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-us10/v2/service_instances/%s?accepts_incomplete=true", iid),434 `{435 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",436 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",437 "context": {438 "globalaccount_id": "g-account-id",439 "user_id": "john.smith@email.com",440 "active": true441 }442 443 }`)444 assert.Equal(t, http.StatusOK, resp.StatusCode)445 suite.processReconciliationByInstanceID(iid)446 // check that the region and zone is set447 suite.AssertAWSRegionAndZone("us-east-1")448}449func TestUpdateOidcForSuspendedInstance(t *testing.T) {450 // given451 suite := NewBrokerSuiteTest(t)452 // uncomment to see graphql queries453 //suite.EnableDumpingProvisionerRequests()454 defer suite.TearDown()455 iid := uuid.New().String()456 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", iid),457 `{458 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",459 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",460 "context": {461 "sm_platform_credentials": {462 "url": "https://sm.url",463 "credentials": {}464 },465 "globalaccount_id": "g-account-id",466 "subaccount_id": "sub-id",467 "user_id": "john.smith@email.com"468 },469 "parameters": {470 "name": "testing-cluster",471 "oidc": {472 "clientID": "id-ooo",473 "signingAlgs": ["RS256"],474 "issuerURL": "https://issuer.url.com"475 }476 }477 }`)478 opID := suite.DecodeOperationID(resp)479 suite.processReconcilingByOperationID(opID)480 suite.Log("*** Suspension ***")481 // Process Suspension482 // OSB context update (suspension)483 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", iid),484 `{485 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",486 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",487 "context": {488 "globalaccount_id": "g-account-id",489 "user_id": "john.smith@email.com",490 "active": false491 }492 }`)493 assert.Equal(t, http.StatusOK, resp.StatusCode)494 suspensionOpID := suite.WaitForLastOperation(iid, domain.InProgress)495 suite.FinishDeprovisioningByReconciler(suspensionOpID)496 suite.FinishDeprovisioningOperationByProvisioner(suspensionOpID)497 suite.WaitForOperationState(suspensionOpID, domain.Succeeded)498 // WHEN499 // OSB update500 suite.Log("*** Update ***")501 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", iid),502 `{503 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",504 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",505 "context": {506 "globalaccount_id": "g-account-id",507 "user_id": "john.smith@email.com"508 },509 "parameters": {510 "oidc": {511 "clientID": "id-oooxx",512 "signingAlgs": ["RS256"],513 "issuerURL": "https://issuer.url.com"514 }515 }516 }`)517 assert.Equal(t, http.StatusAccepted, resp.StatusCode)518 updateOpID := suite.DecodeOperationID(resp)519 suite.WaitForOperationState(updateOpID, domain.Succeeded)520 // THEN521 instance := suite.GetInstance(iid)522 assert.Equal(t, "id-oooxx", instance.Parameters.Parameters.OIDC.ClientID)523 // Start unsuspension524 // OSB update (unsuspension)525 suite.Log("*** Update (unsuspension) ***")526 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s", iid),527 `{528 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",529 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",530 "context": {531 "globalaccount_id": "g-account-id",532 "user_id": "john.smith@email.com",533 "active": true534 }535 }`)536 assert.Equal(t, http.StatusOK, resp.StatusCode)537 suite.DecodeOperationID(resp)538 // WHEN539 suite.processReconciliationByInstanceID(iid)540 // THEN541 instance = suite.GetInstance(iid)542 assert.Equal(t, "id-oooxx", instance.Parameters.Parameters.OIDC.ClientID)543 input := suite.LastProvisionInput(iid)544 assert.Equal(t, "id-oooxx", input.ClusterConfig.GardenerConfig.OidcConfig.ClientID)545}546func TestUpdateNotExistingInstance(t *testing.T) {547 // given548 suite := NewBrokerSuiteTest(t)549 defer suite.TearDown()550 iid := uuid.New().String()551 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", iid),552 `{553 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",554 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",555 "context": {556 "sm_platform_credentials": {557 "url": "https://sm.url",558 "credentials": {}559 },560 "globalaccount_id": "g-account-id",561 "subaccount_id": "sub-id",562 "user_id": "john.smith@email.com"563 },564 "parameters": {565 "name": "testing-cluster",566 "oidc": {567 "clientID": "id-ooo",568 "signingAlgs": ["RS256"],569 "issuerURL": "https://issuer.url.com"570 }571 }572 }`)573 opID := suite.DecodeOperationID(resp)574 suite.processReconcilingByOperationID(opID)575 // provisioning done, let's start an update576 // when577 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/not-existing"),578 `{579 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",580 "plan_id": "4deee563-e5ec-4731-b9b1-53b42d855f0c",581 "context": {582 "globalaccount_id": "g-account-id",583 "user_id": "john.smith@email.com"584 }585 }`)586 assert.Equal(t, http.StatusNotFound, resp.StatusCode)587}588func TestUpdateDefaultAdminNotChanged(t *testing.T) {589 // given590 suite := NewBrokerSuiteTest(t)591 defer suite.TearDown()592 id := uuid.New().String()593 expectedAdmins := []string{"john.smith@email.com"}594 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", id),595 `{596 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",597 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",598 "context": {599 "sm_platform_credentials": {600 "url": "https://sm.url",601 "credentials": {}602 },603 "globalaccount_id": "g-account-id",604 "subaccount_id": "sub-id",605 "user_id": "john.smith@email.com"606 },607 "parameters": {608 "name": "testing-cluster"609 }610 }`)611 opID := suite.DecodeOperationID(resp)612 suite.processReconcilingByOperationID(opID)613 // when614 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id),615 `{616 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",617 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",618 "context": {619 "globalaccount_id": "g-account-id",620 "user_id": "jack.anvil@email.com"621 },622 "parameters": {623 }624 }`)625 // then626 assert.Equal(t, http.StatusAccepted, resp.StatusCode)627 // when628 upgradeOperationID := suite.DecodeOperationID(resp)629 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)630 // then631 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)632 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{633 GardenerConfig: &gqlschema.GardenerUpgradeInput{634 OidcConfig: &gqlschema.OIDCConfigInput{635 ClientID: "client-id-oidc",636 GroupsClaim: "groups",637 IssuerURL: "https://issuer.url",638 SigningAlgs: []string{"RS256"},639 UsernameClaim: "sub",640 UsernamePrefix: "-",641 },642 },643 Administrators: expectedAdmins,644 })645}646func TestUpdateDefaultAdminNotChangedWithCustomOIDC(t *testing.T) {647 // given648 suite := NewBrokerSuiteTest(t)649 defer suite.TearDown()650 id := uuid.New().String()651 expectedAdmins := []string{"john.smith@email.com"}652 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", id),653 `{654 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",655 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",656 "context": {657 "sm_platform_credentials": {658 "url": "https://sm.url",659 "credentials": {}660 },661 "globalaccount_id": "g-account-id",662 "subaccount_id": "sub-id",663 "user_id": "john.smith@email.com"664 },665 "parameters": {666 "name": "testing-cluster",667 "oidc": {668 "clientID": "id-ooo",669 "issuerURL": "https://issuer.url.com"670 }671 }672 }`)673 opID := suite.DecodeOperationID(resp)674 suite.processReconcilingByOperationID(opID)675 // when676 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id),677 `{678 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",679 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",680 "context": {681 "globalaccount_id": "g-account-id",682 "user_id": "jack.anvil@email.com"683 },684 "parameters": {685 }686 }`)687 // then688 assert.Equal(t, http.StatusAccepted, resp.StatusCode)689 // when690 upgradeOperationID := suite.DecodeOperationID(resp)691 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)692 // then693 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)694 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{695 GardenerConfig: &gqlschema.GardenerUpgradeInput{696 OidcConfig: &gqlschema.OIDCConfigInput{697 ClientID: "id-ooo",698 GroupsClaim: "groups",699 IssuerURL: "https://issuer.url.com",700 SigningAlgs: []string{"RS256"},701 UsernameClaim: "sub",702 UsernamePrefix: "-",703 },704 },705 Administrators: expectedAdmins,706 })707}708func TestUpdateDefaultAdminNotChangedWithOIDCUpdate(t *testing.T) {709 // given710 suite := NewBrokerSuiteTest(t)711 defer suite.TearDown()712 id := uuid.New().String()713 expectedAdmins := []string{"john.smith@email.com"}714 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", id),715 `{716 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",717 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",718 "context": {719 "sm_platform_credentials": {720 "url": "https://sm.url",721 "credentials": {}722 },723 "globalaccount_id": "g-account-id",724 "subaccount_id": "sub-id",725 "user_id": "john.smith@email.com"726 },727 "parameters": {728 "name": "testing-cluster"729 }730 }`)731 opID := suite.DecodeOperationID(resp)732 suite.processReconcilingByOperationID(opID)733 // when734 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id),735 `{736 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",737 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",738 "context": {739 "globalaccount_id": "g-account-id",740 "user_id": "jack.anvil@email.com"741 },742 "parameters": {743 "oidc": {744 "clientID": "id-ooo",745 "signingAlgs": ["RS384"],746 "issuerURL": "https://issuer.url.com",747 "groupsClaim": "new-groups-claim",748 "usernameClaim": "new-username-claim",749 "usernamePrefix": "->"750 }751 }752 }`)753 // then754 assert.Equal(t, http.StatusAccepted, resp.StatusCode)755 // when756 upgradeOperationID := suite.DecodeOperationID(resp)757 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)758 // then759 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)760 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{761 GardenerConfig: &gqlschema.GardenerUpgradeInput{762 OidcConfig: &gqlschema.OIDCConfigInput{763 ClientID: "id-ooo",764 GroupsClaim: "new-groups-claim",765 IssuerURL: "https://issuer.url.com",766 SigningAlgs: []string{"RS384"},767 UsernameClaim: "new-username-claim",768 UsernamePrefix: "->",769 },770 },771 Administrators: expectedAdmins,772 })773}774func TestUpdateDefaultAdminOverwritten(t *testing.T) {775 // given776 suite := NewBrokerSuiteTest(t)777 defer suite.TearDown()778 id := uuid.New().String()779 expectedAdmins := []string{"newAdmin1@kyma.cx", "newAdmin2@kyma.cx"}780 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", id),781 `{782 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",783 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",784 "context": {785 "sm_platform_credentials": {786 "url": "https://sm.url",787 "credentials": {}788 },789 "globalaccount_id": "g-account-id",790 "subaccount_id": "sub-id",791 "user_id": "john.smith@email.com"792 },793 "parameters": {794 "name": "testing-cluster"795 }796 }`)797 opID := suite.DecodeOperationID(resp)798 suite.processReconcilingByOperationID(opID)799 // when800 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id),801 `{802 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",803 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",804 "context": {805 "globalaccount_id": "g-account-id",806 "user_id": "jack.anvil@email.com"807 },808 "parameters": {809 "administrators":["newAdmin1@kyma.cx", "newAdmin2@kyma.cx"]810 }811 }`)812 // then813 assert.Equal(t, http.StatusAccepted, resp.StatusCode)814 // when815 upgradeOperationID := suite.DecodeOperationID(resp)816 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)817 // then818 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)819 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{820 GardenerConfig: &gqlschema.GardenerUpgradeInput{821 OidcConfig: &gqlschema.OIDCConfigInput{822 ClientID: "client-id-oidc",823 GroupsClaim: "groups",824 IssuerURL: "https://issuer.url",825 SigningAlgs: []string{"RS256"},826 UsernameClaim: "sub",827 UsernamePrefix: "-",828 },829 },830 Administrators: expectedAdmins,831 })832 suite.AssertInstanceRuntimeAdmins(id, expectedAdmins)833}834func TestUpdateCustomAdminsNotChanged(t *testing.T) {835 // given836 suite := NewBrokerSuiteTest(t)837 defer suite.TearDown()838 id := uuid.New().String()839 expectedAdmins := []string{"newAdmin1@kyma.cx", "newAdmin2@kyma.cx"}840 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", id),841 `{842 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",843 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",844 "context": {845 "sm_platform_credentials": {846 "url": "https://sm.url",847 "credentials": {}848 },849 "globalaccount_id": "g-account-id",850 "subaccount_id": "sub-id",851 "user_id": "john.smith@email.com"852 },853 "parameters": {854 "name": "testing-cluster",855 "administrators":["newAdmin1@kyma.cx", "newAdmin2@kyma.cx"]856 }857 }`)858 opID := suite.DecodeOperationID(resp)859 suite.processReconcilingByOperationID(opID)860 // when861 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id),862 `{863 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",864 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",865 "context": {866 "globalaccount_id": "g-account-id",867 "user_id": "jack.anvil@email.com"868 },869 "parameters": {870 }871 }`)872 // then873 assert.Equal(t, http.StatusAccepted, resp.StatusCode)874 // when875 upgradeOperationID := suite.DecodeOperationID(resp)876 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)877 // then878 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)879 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{880 GardenerConfig: &gqlschema.GardenerUpgradeInput{881 OidcConfig: &gqlschema.OIDCConfigInput{882 ClientID: "client-id-oidc",883 GroupsClaim: "groups",884 IssuerURL: "https://issuer.url",885 SigningAlgs: []string{"RS256"},886 UsernameClaim: "sub",887 UsernamePrefix: "-",888 },889 },890 Administrators: expectedAdmins,891 })892 suite.AssertInstanceRuntimeAdmins(id, expectedAdmins)893}894func TestUpdateCustomAdminsNotChangedWithOIDCUpdate(t *testing.T) {895 // given896 suite := NewBrokerSuiteTest(t)897 defer suite.TearDown()898 id := uuid.New().String()899 expectedAdmins := []string{"newAdmin1@kyma.cx", "newAdmin2@kyma.cx"}900 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", id),901 `{902 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",903 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",904 "context": {905 "sm_platform_credentials": {906 "url": "https://sm.url",907 "credentials": {}908 },909 "globalaccount_id": "g-account-id",910 "subaccount_id": "sub-id",911 "user_id": "john.smith@email.com"912 },913 "parameters": {914 "name": "testing-cluster",915 "administrators":["newAdmin1@kyma.cx", "newAdmin2@kyma.cx"]916 }917 }`)918 opID := suite.DecodeOperationID(resp)919 suite.processReconcilingByOperationID(opID)920 // when921 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id),922 `{923 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",924 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",925 "context": {926 "globalaccount_id": "g-account-id"927 },928 "parameters": {929 "oidc": {930 "clientID": "id-ooo",931 "signingAlgs": ["ES256"],932 "issuerURL": "https://newissuer.url.com"933 }934 }935 }`)936 // then937 assert.Equal(t, http.StatusAccepted, resp.StatusCode)938 // when939 upgradeOperationID := suite.DecodeOperationID(resp)940 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)941 // then942 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)943 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{944 GardenerConfig: &gqlschema.GardenerUpgradeInput{945 OidcConfig: &gqlschema.OIDCConfigInput{946 ClientID: "id-ooo",947 GroupsClaim: "groups",948 IssuerURL: "https://newissuer.url.com",949 SigningAlgs: []string{"ES256"},950 UsernameClaim: "sub",951 UsernamePrefix: "-",952 },953 },954 Administrators: expectedAdmins,955 })956 suite.AssertInstanceRuntimeAdmins(id, expectedAdmins)957}958func TestUpdateCustomAdminsOverwritten(t *testing.T) {959 // given960 suite := NewBrokerSuiteTest(t)961 defer suite.TearDown()962 id := uuid.New().String()963 expectedAdmins := []string{"newAdmin3@kyma.cx", "newAdmin4@kyma.cx"}964 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", id),965 `{966 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",967 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",968 "context": {969 "sm_platform_credentials": {970 "url": "https://sm.url",971 "credentials": {}972 },973 "globalaccount_id": "g-account-id",974 "subaccount_id": "sub-id",975 "user_id": "john.smith@email.com"976 },977 "parameters": {978 "name": "testing-cluster",979 "administrators":["newAdmin1@kyma.cx", "newAdmin2@kyma.cx"]980 }981 }`)982 opID := suite.DecodeOperationID(resp)983 suite.processReconcilingByOperationID(opID)984 // when985 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id),986 `{987 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",988 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",989 "context": {990 "globalaccount_id": "g-account-id",991 "user_id": "jack.anvil@email.com"992 },993 "parameters": {994 "administrators":["newAdmin3@kyma.cx", "newAdmin4@kyma.cx"]995 }996 }`)997 // then998 assert.Equal(t, http.StatusAccepted, resp.StatusCode)999 // when1000 upgradeOperationID := suite.DecodeOperationID(resp)1001 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)1002 // then1003 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)1004 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{1005 GardenerConfig: &gqlschema.GardenerUpgradeInput{1006 OidcConfig: &gqlschema.OIDCConfigInput{1007 ClientID: "client-id-oidc",1008 GroupsClaim: "groups",1009 IssuerURL: "https://issuer.url",1010 SigningAlgs: []string{"RS256"},1011 UsernameClaim: "sub",1012 UsernamePrefix: "-",1013 },1014 },1015 Administrators: expectedAdmins,1016 })1017 suite.AssertInstanceRuntimeAdmins(id, expectedAdmins)1018}1019func TestUpdateCustomAdminsOverwrittenWithOIDCUpdate(t *testing.T) {1020 // given1021 suite := NewBrokerSuiteTest(t)1022 defer suite.TearDown()1023 id := uuid.New().String()1024 expectedAdmins := []string{"newAdmin3@kyma.cx", "newAdmin4@kyma.cx"}1025 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", id),1026 `{1027 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1028 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1029 "context": {1030 "sm_platform_credentials": {1031 "url": "https://sm.url",1032 "credentials": {}1033 },1034 "globalaccount_id": "g-account-id",1035 "subaccount_id": "sub-id",1036 "user_id": "john.smith@email.com"1037 },1038 "parameters": {1039 "name": "testing-cluster",1040 "administrators":["newAdmin1@kyma.cx", "newAdmin2@kyma.cx"]1041 }1042 }`)1043 opID := suite.DecodeOperationID(resp)1044 suite.processReconcilingByOperationID(opID)1045 // when1046 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id),1047 `{1048 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1049 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1050 "context": {1051 "globalaccount_id": "g-account-id",1052 "user_id": "john.smith@email.com"1053 },1054 "parameters": {1055 "oidc": {1056 "clientID": "id-ooo",1057 "signingAlgs": ["ES384"],1058 "issuerURL": "https://issuer.url.com",1059 "groupsClaim": "new-groups-claim"1060 },1061 "administrators":["newAdmin3@kyma.cx", "newAdmin4@kyma.cx"]1062 }1063 }`)1064 // then1065 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1066 // when1067 upgradeOperationID := suite.DecodeOperationID(resp)1068 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)1069 // then1070 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)1071 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{1072 GardenerConfig: &gqlschema.GardenerUpgradeInput{1073 OidcConfig: &gqlschema.OIDCConfigInput{1074 ClientID: "id-ooo",1075 GroupsClaim: "new-groups-claim",1076 IssuerURL: "https://issuer.url.com",1077 SigningAlgs: []string{"ES384"},1078 UsernameClaim: "sub",1079 UsernamePrefix: "-",1080 },1081 },1082 Administrators: expectedAdmins,1083 })1084 suite.AssertInstanceRuntimeAdmins(id, expectedAdmins)1085}1086func TestUpdateCustomAdminsOverwrittenTwice(t *testing.T) {1087 // given1088 suite := NewBrokerSuiteTest(t)1089 defer suite.TearDown()1090 id := uuid.New().String()1091 expectedAdmins1 := []string{"newAdmin3@kyma.cx", "newAdmin4@kyma.cx"}1092 expectedAdmins2 := []string{"newAdmin5@kyma.cx", "newAdmin6@kyma.cx"}1093 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", id),1094 `{1095 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1096 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1097 "context": {1098 "sm_platform_credentials": {1099 "url": "https://sm.url",1100 "credentials": {}1101 },1102 "globalaccount_id": "g-account-id",1103 "subaccount_id": "sub-id",1104 "user_id": "john.smith@email.com"1105 },1106 "parameters": {1107 "name": "testing-cluster",1108 "administrators":["newAdmin1@kyma.cx", "newAdmin2@kyma.cx"]1109 }1110 }`)1111 opID := suite.DecodeOperationID(resp)1112 suite.processReconcilingByOperationID(opID)1113 // when1114 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id),1115 `{1116 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1117 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1118 "context": {1119 "globalaccount_id": "g-account-id",1120 "user_id": "jack.anvil@email.com"1121 },1122 "parameters": {1123 "administrators":["newAdmin3@kyma.cx", "newAdmin4@kyma.cx"]1124 }1125 }`)1126 // then1127 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1128 // when1129 upgradeOperationID := suite.DecodeOperationID(resp)1130 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)1131 // then1132 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)1133 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{1134 GardenerConfig: &gqlschema.GardenerUpgradeInput{1135 OidcConfig: &gqlschema.OIDCConfigInput{1136 ClientID: "client-id-oidc",1137 GroupsClaim: "groups",1138 IssuerURL: "https://issuer.url",1139 SigningAlgs: []string{"RS256"},1140 UsernameClaim: "sub",1141 UsernamePrefix: "-",1142 },1143 },1144 Administrators: expectedAdmins1,1145 })1146 suite.AssertInstanceRuntimeAdmins(id, expectedAdmins1)1147 // when1148 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id),1149 `{1150 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1151 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1152 "context": {1153 "globalaccount_id": "g-account-id"1154 },1155 "parameters": {1156 "oidc": {1157 "clientID": "id-ooo",1158 "signingAlgs": ["PS256"],1159 "issuerURL": "https://newissuer.url.com",1160 "usernamePrefix": "->"1161 },1162 "administrators":["newAdmin5@kyma.cx", "newAdmin6@kyma.cx"]1163 }1164 }`)1165 // then1166 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1167 // when1168 upgradeOperationID = suite.DecodeOperationID(resp)1169 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)1170 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{1171 GardenerConfig: &gqlschema.GardenerUpgradeInput{1172 OidcConfig: &gqlschema.OIDCConfigInput{1173 ClientID: "id-ooo",1174 GroupsClaim: "groups",1175 IssuerURL: "https://newissuer.url.com",1176 SigningAlgs: []string{"PS256"},1177 UsernameClaim: "sub",1178 UsernamePrefix: "->",1179 },1180 },1181 Administrators: expectedAdmins2,1182 })1183 suite.AssertInstanceRuntimeAdmins(id, expectedAdmins2)1184}1185func TestUpdateAutoscalerParams(t *testing.T) {1186 // given1187 suite := NewBrokerSuiteTest(t)1188 defer suite.TearDown()1189 id := uuid.New().String()1190 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", id), `1191{1192 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1193 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1194 "context": {1195 "sm_platform_credentials": {1196 "url": "https://sm.url",1197 "credentials": {}1198 },1199 "globalaccount_id": "g-account-id",1200 "subaccount_id": "sub-id",1201 "user_id": "john.smith@email.com"1202 },1203 "parameters": {1204 "name": "testing-cluster",1205 "autoScalerMin":5,1206 "autoScalerMax":7,1207 "maxSurge":3,1208 "maxUnavailable":41209 }1210}`)1211 opID := suite.DecodeOperationID(resp)1212 suite.processReconcilingByOperationID(opID)1213 // when1214 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1215{1216 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1217 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1218 "context": {1219 "globalaccount_id": "g-account-id",1220 "user_id": "jack.anvil@email.com"1221 },1222 "parameters": {1223 "autoScalerMin":15,1224 "autoScalerMax":25,1225 "maxSurge":10,1226 "maxUnavailable":71227 }1228}`)1229 // then1230 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1231 // when1232 upgradeOperationID := suite.DecodeOperationID(resp)1233 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)1234 min, max, surge, unav := 15, 25, 10, 71235 // then1236 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)1237 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{1238 GardenerConfig: &gqlschema.GardenerUpgradeInput{1239 OidcConfig: &gqlschema.OIDCConfigInput{1240 ClientID: "client-id-oidc",1241 GroupsClaim: "groups",1242 IssuerURL: "https://issuer.url",1243 SigningAlgs: []string{"RS256"},1244 UsernameClaim: "sub",1245 UsernamePrefix: "-",1246 },1247 AutoScalerMin: &min,1248 AutoScalerMax: &max,1249 MaxSurge: &surge,1250 MaxUnavailable: &unav,1251 },1252 Administrators: []string{"john.smith@email.com"},1253 })1254}1255func TestUpdateAutoscalerWrongParams(t *testing.T) {1256 // given1257 suite := NewBrokerSuiteTest(t)1258 defer suite.TearDown()1259 id := uuid.New().String()1260 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", id), `1261{1262 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1263 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1264 "context": {1265 "sm_platform_credentials": {1266 "url": "https://sm.url",1267 "credentials": {}1268 },1269 "globalaccount_id": "g-account-id",1270 "subaccount_id": "sub-id",1271 "user_id": "john.smith@email.com"1272 },1273 "parameters": {1274 "name": "testing-cluster",1275 "autoScalerMin":5,1276 "autoScalerMax":7,1277 "maxSurge":3,1278 "maxUnavailable":41279 }1280}`)1281 opID := suite.DecodeOperationID(resp)1282 suite.processReconcilingByOperationID(opID)1283 // when1284 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1285{1286 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1287 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1288 "context": {1289 "globalaccount_id": "g-account-id",1290 "user_id": "jack.anvil@email.com"1291 },1292 "parameters": {1293 "autoScalerMin":26,1294 "autoScalerMax":25,1295 "maxSurge":10,1296 "maxUnavailable":71297 }1298}`)1299 // then1300 assert.Equal(t, http.StatusUnprocessableEntity, resp.StatusCode)1301}1302func TestUpdateAutoscalerPartialSequence(t *testing.T) {1303 // given1304 suite := NewBrokerSuiteTest(t)1305 defer suite.TearDown()1306 id := uuid.New().String()1307 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", id), `1308{1309 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1310 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1311 "context": {1312 "sm_platform_credentials": {1313 "url": "https://sm.url",1314 "credentials": {}1315 },1316 "globalaccount_id": "g-account-id",1317 "subaccount_id": "sub-id",1318 "user_id": "john.smith@email.com"1319 },1320 "parameters": {1321 "name": "testing-cluster"1322 }1323}`)1324 opID := suite.DecodeOperationID(resp)1325 suite.processReconcilingByOperationID(opID)1326 // when1327 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1328{1329 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1330 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1331 "context": {1332 "globalaccount_id": "g-account-id",1333 "user_id": "jack.anvil@email.com"1334 },1335 "parameters": {1336 "autoScalerMin":151337 }1338}`)1339 // then1340 assert.Equal(t, http.StatusUnprocessableEntity, resp.StatusCode)1341 // when1342 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1343{1344 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1345 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1346 "context": {1347 "globalaccount_id": "g-account-id",1348 "user_id": "jack.anvil@email.com"1349 },1350 "parameters": {1351 "autoScalerMax":151352 }1353}`)1354 // then1355 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1356 upgradeOperationID := suite.DecodeOperationID(resp)1357 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)1358 max := 151359 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)1360 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{1361 GardenerConfig: &gqlschema.GardenerUpgradeInput{1362 OidcConfig: &gqlschema.OIDCConfigInput{1363 ClientID: "client-id-oidc",1364 GroupsClaim: "groups",1365 IssuerURL: "https://issuer.url",1366 SigningAlgs: []string{"RS256"},1367 UsernameClaim: "sub",1368 UsernamePrefix: "-",1369 },1370 AutoScalerMax: &max,1371 },1372 Administrators: []string{"john.smith@email.com"},1373 })1374 // when1375 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1376{1377 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1378 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1379 "context": {1380 "globalaccount_id": "g-account-id",1381 "user_id": "jack.anvil@email.com"1382 },1383 "parameters": {1384 "autoScalerMin":141385 }1386}`)1387 // then1388 suite.WaitForOperationState(upgradeOperationID, domain.Succeeded)1389 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1390 upgradeOperationID = suite.DecodeOperationID(resp)1391 suite.FinishUpdatingOperationByProvisioner(upgradeOperationID)1392 min := 141393 suite.AssertShootUpgrade(upgradeOperationID, gqlschema.UpgradeShootInput{1394 GardenerConfig: &gqlschema.GardenerUpgradeInput{1395 OidcConfig: &gqlschema.OIDCConfigInput{1396 ClientID: "client-id-oidc",1397 GroupsClaim: "groups",1398 IssuerURL: "https://issuer.url",1399 SigningAlgs: []string{"RS256"},1400 UsernameClaim: "sub",1401 UsernamePrefix: "-",1402 },1403 AutoScalerMin: &min,1404 },1405 Administrators: []string{"john.smith@email.com"},1406 })1407 // when1408 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1409{1410 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1411 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1412 "context": {1413 "globalaccount_id": "g-account-id",1414 "user_id": "jack.anvil@email.com"1415 },1416 "parameters": {1417 "autoScalerMin":161418 }1419}`)1420 // then1421 assert.Equal(t, http.StatusUnprocessableEntity, resp.StatusCode)1422}1423func TestUpdateWhenBothErsContextAndUpdateParametersProvided(t *testing.T) {1424 // given1425 suite := NewBrokerSuiteTest(t)1426 // uncomment to see graphql queries1427 //suite.EnableDumpingProvisionerRequests()1428 defer suite.TearDown()1429 iid := uuid.New().String()1430 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", iid),1431 `{1432 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1433 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1434 "context": {1435 "sm_platform_credentials": {1436 "url": "https://sm.url",1437 "credentials": {}1438 },1439 "globalaccount_id": "g-account-id",1440 "subaccount_id": "sub-id",1441 "user_id": "john.smith@email.com"1442 },1443 "parameters": {1444 "name": "testing-cluster",1445 "oidc": {1446 "clientID": "id-ooo",1447 "signingAlgs": ["RS256"],1448 "issuerURL": "https://issuer.url.com"1449 }1450 }1451 }`)1452 opID := suite.DecodeOperationID(resp)1453 suite.processReconcilingByOperationID(opID)1454 suite.Log("*** Suspension ***")1455 // when1456 // Process Suspension1457 // OSB context update (suspension)1458 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", iid),1459 `{1460 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1461 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1462 "context": {1463 "globalaccount_id": "g-account-id",1464 "user_id": "john.smith@email.com",1465 "active": false1466 },1467 "parameters": {1468 "name": "testing-cluster"1469 }1470 }`)1471 assert.Equal(t, http.StatusOK, resp.StatusCode)1472 suspensionOpID := suite.WaitForLastOperation(iid, domain.InProgress)1473 suite.FinishDeprovisioningByReconciler(suspensionOpID)1474 suite.FinishDeprovisioningOperationByProvisioner(suspensionOpID)1475 suite.WaitForOperationState(suspensionOpID, domain.Succeeded)1476 // THEN1477 lastOp, err := suite.db.Operations().GetLastOperation(iid)1478 require.NoError(t, err)1479 assert.Equal(t, internal.OperationTypeDeprovision, lastOp.Type, "last operation should be type deprovision")1480 updateOps, err := suite.db.Operations().ListUpdatingOperationsByInstanceID(iid)1481 require.NoError(t, err)1482 assert.Len(t, updateOps, 0, "should not create any update operations")1483}1484func TestUpdateSCMigrationSuccess(t *testing.T) {1485 // given1486 suite := NewBrokerSuiteTest(t)1487 mockBTPOperatorClusterID()1488 defer suite.TearDown()1489 id := "InstanceID-SCMigration"1490 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true&plan_id=7d55d31d-35ae-4438-bf13-6ffdfa107d9f&service_id=47c9dcbf-ff30-448e-ab36-d3bad66ba281", id), `1491{1492 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1493 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1494 "context": {1495 "sm_platform_credentials": {1496 "url": "https://sm.url",1497 "credentials": {1498 "basic": {1499 "username": "u-name",1500 "password": "pass"1501 }1502 }1503 },1504 "globalaccount_id": "g-account-id",1505 "subaccount_id": "sub-id",1506 "user_id": "john.smith@email.com"1507 },1508 "parameters": {1509 "name": "testing-cluster",1510 "kymaVersion": "2.0"1511 }1512}`)1513 opID := suite.DecodeOperationID(resp)1514 suite.processReconcilingByOperationID(opID)1515 suite.WaitForOperationState(opID, domain.Succeeded)1516 i, err := suite.db.Instances().GetByID(id)1517 assert.NoError(t, err, "getting instance after provisioning, before update")1518 rs, err := suite.db.RuntimeStates().GetLatestWithReconcilerInputByRuntimeID(i.RuntimeID)1519 if rs.ClusterSetup == nil {1520 t.Fatal("expected cluster setup post provisioning kyma 2.0 cluster")1521 }1522 if rs.ClusterSetup.KymaConfig.Version != "2.0" {1523 t.Fatalf("expected cluster setup kyma config version to match 2.0, got %v", rs.ClusterSetup.KymaConfig.Version)1524 }1525 assert.Equal(t, opID, rs.OperationID, "runtime state provisioning operation ID")1526 assert.NoError(t, err, "getting runtime state after provisioning, before update")1527 assert.ElementsMatch(t, rs.KymaConfig.Components, []*gqlschema.ComponentConfigurationInput{})1528 assert.ElementsMatch(t, componentNames(rs.ClusterSetup.KymaConfig.Components), []string{"ory", "monitoring"})1529 // when1530 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1531{1532 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1533 "context": {1534 "globalaccount_id": "g-account-id",1535 "user_id": "john.smith@email.com",1536 "sm_operator_credentials": {1537 "clientid": "testClientID",1538 "clientsecret": "testClientSecret",1539 "sm_url": "https://service-manager.kyma.com",1540 "url": "https://test.auth.com",1541 "xsappname": "testXsappname"1542 },1543 "isMigration": true1544 }1545}`)1546 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1547 updateOperationID := suite.DecodeOperationID(resp)1548 time.Sleep(5 * time.Millisecond)1549 rsu1, err := suite.db.RuntimeStates().GetLatestWithReconcilerInputByRuntimeID(i.RuntimeID)1550 assert.NoError(t, err, "getting runtime mid update")1551 suite.FinishUpdatingOperationByReconciler(updateOperationID)1552 // check first call to reconciler installing BTP-Operator and sc-migration, disabling SVCAT1553 assert.Equal(t, updateOperationID, rsu1.OperationID, "runtime state update operation ID")1554 assert.ElementsMatch(t, rsu1.KymaConfig.Components, []*gqlschema.ComponentConfigurationInput{})1555 assert.ElementsMatch(t, componentNames(rs.ClusterSetup.KymaConfig.Components), []string{"ory", "monitoring", "btp-operator", "sc-migration"})1556 // check second call to reconciler and see that sc-migration is no longer present and svcat related components are gone as well1557 time.Sleep(5 * time.Millisecond)1558 suite.FinishUpdatingOperationByReconciler(updateOperationID)1559 i, err = suite.db.Instances().GetByID(id)1560 assert.NoError(t, err, "getting instance after update")1561 assert.True(t, i.InstanceDetails.SCMigrationTriggered, "instance SCMigrationTriggered after update")1562 rsu2, err := suite.db.RuntimeStates().GetLatestWithReconcilerInputByRuntimeID(i.RuntimeID)1563 assert.NoError(t, err, "getting runtime after update")1564 assert.NotEqual(t, rsu1.ID, rsu2.ID, "runtime_state ID from first call should differ runtime_state ID from second call")1565 assert.Equal(t, updateOperationID, rsu2.OperationID, "runtime state update operation ID")1566 assert.ElementsMatch(t, rsu2.KymaConfig.Components, []*gqlschema.ComponentConfigurationInput{})1567 assert.ElementsMatch(t, componentNames(rsu2.ClusterSetup.KymaConfig.Components), []string{"ory", "monitoring", "btp-operator"})1568 for _, c := range rsu2.ClusterSetup.KymaConfig.Components {1569 if c.Component == "btp-operator" {1570 exp := reconcilerApi.Component{1571 Component: "btp-operator",1572 Namespace: "kyma-system",1573 URL: "https://btp-operator",1574 Configuration: []reconcilerApi.Configuration{1575 {Key: "manager.secret.clientid", Value: "testClientID", Secret: true},1576 {Key: "manager.secret.clientsecret", Value: "testClientSecret", Secret: true},1577 {Key: "manager.secret.url", Value: "https://service-manager.kyma.com"},1578 {Key: "manager.secret.sm_url", Value: "https://service-manager.kyma.com"},1579 {Key: "manager.secret.tokenurl", Value: "https://test.auth.com"},1580 {Key: "cluster.id", Value: "cluster_id"},1581 },1582 }1583 assert.Equal(t, exp, c)1584 }1585 }1586 // finalize second call to reconciler and wait for the operation to finish1587 //suite.AssertReconcilerStartedReconcilingWhenUpgrading(instanceID)1588 time.Sleep(5 * time.Millisecond)1589 suite.FinishUpdatingOperationByReconciler(updateOperationID)1590 suite.WaitForOperationState(updateOperationID, domain.Succeeded)1591 // change component input (additional components) and see if it works with update operation1592 suite.componentProvider.decorator["btp-operator"] = runtime.KymaComponent{1593 Name: "btp-operator",1594 Namespace: "kyma-system",1595 Source: &runtime.ComponentSource{URL: "https://btp-operator/updated"},1596 }1597 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1598{1599 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1600 "context": {1601 "globalaccount_id": "g-account-id",1602 "user_id": "john.smith@email.com",1603 "sm_operator_credentials": {1604 "clientid": "testClientID",1605 "clientsecret": "testClientSecret",1606 "sm_url": "https://service-manager.kyma.com",1607 "url": "https://test.auth.com",1608 "xsappname": "testXsappname"1609 },1610 "isMigration": true1611 }1612}`)1613 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1614 update2OperationID := suite.DecodeOperationID(resp)1615 time.Sleep(5 * time.Millisecond)1616 suite.FinishUpdatingOperationByReconciler(update2OperationID)1617 i, err = suite.db.Instances().GetByID(id)1618 assert.NoError(t, err, "getting instance after second update")1619 assert.True(t, i.InstanceDetails.SCMigrationTriggered, "instance SCMigrationTriggered after second update")1620 rsu3, err := suite.db.RuntimeStates().GetLatestWithReconcilerInputByRuntimeID(i.RuntimeID)1621 assert.NoError(t, err, "getting runtime after second update")1622 assert.NotEqual(t, rsu2.ID, rsu3.ID, "runtime_state ID from second call should differ runtime_state ID from third call")1623 assert.Equal(t, update2OperationID, rsu3.OperationID, "runtime state second update operation ID")1624 assert.ElementsMatch(t, rsu3.KymaConfig.Components, []*gqlschema.ComponentConfigurationInput{})1625 assert.ElementsMatch(t, componentNames(rsu3.ClusterSetup.KymaConfig.Components), []string{"ory", "monitoring", "btp-operator", "sc-migration"})1626 for _, c := range rsu3.ClusterSetup.KymaConfig.Components {1627 if c.Component == "btp-operator" {1628 exp := reconcilerApi.Component{1629 Component: "btp-operator",1630 Namespace: "kyma-system",1631 URL: "https://btp-operator/updated",1632 Configuration: []reconcilerApi.Configuration{1633 {Key: "manager.secret.clientid", Value: "testClientID", Secret: true},1634 {Key: "manager.secret.clientsecret", Value: "testClientSecret", Secret: true},1635 {Key: "manager.secret.url", Value: "https://service-manager.kyma.com"},1636 {Key: "manager.secret.sm_url", Value: "https://service-manager.kyma.com"},1637 {Key: "manager.secret.tokenurl", Value: "https://test.auth.com"},1638 {Key: "cluster.id", Value: "cluster_id"},1639 },1640 }1641 assert.Equal(t, exp, c)1642 }1643 }1644}1645func TestUpdateNetworkFilterPersisted(t *testing.T) {1646 // given1647 suite := NewBrokerSuiteTest(t, "2.0")1648 defer suite.TearDown()1649 id := uuid.New().String()1650 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/v2/service_instances/%s?accepts_incomplete=true", id),1651 `{1652 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1653 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1654 "context": {1655 "sm_operator_credentials": {1656 "clientid": "testClientID",1657 "clientsecret": "testClientSecret",1658 "sm_url": "https://service-manager.kyma.com",1659 "url": "https://test.auth.com",1660 "xsappname": "testXsappname"1661 },1662 "license_type": "CUSTOMER",1663 "globalaccount_id": "g-account-id",1664 "subaccount_id": "sub-id",1665 "user_id": "john.smith@email.com"1666 },1667 "parameters": {1668 "name": "testing-cluster"1669 }1670 }`)1671 opID := suite.DecodeOperationID(resp)1672 suite.processReconcilingByOperationID(opID)1673 suite.WaitForOperationState(opID, domain.Succeeded)1674 instance := suite.GetInstance(id)1675 // then1676 disabled := true1677 suite.AssertDisabledNetworkFilterForProvisioning(&disabled)1678 assert.Equal(suite.t, "CUSTOMER", *instance.Parameters.ErsContext.LicenseType)1679 // when1680 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1681 {1682 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1683 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1684 "context": {1685 "globalaccount_id": "g-account-id",1686 "user_id": "john.smith@email.com",1687 "sm_operator_credentials": {1688 "clientid": "testClientID",1689 "clientsecret": "testClientSecret",1690 "sm_url": "https://service-manager.kyma.com",1691 "url": "https://test.auth.com",1692 "xsappname": "testXsappname"1693 }1694 },1695 "parameters": {1696 "name": "testing-cluster"1697 }1698 }`)1699 // then1700 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1701 updateOperationID := suite.DecodeOperationID(resp)1702 suite.FinishUpdatingOperationByProvisionerAndReconciler(updateOperationID)1703 suite.WaitForOperationState(updateOperationID, domain.Succeeded)1704 updateOp, _ := suite.db.Operations().GetUpdatingOperationByID(updateOperationID)1705 assert.NotNil(suite.t, updateOp.ProvisioningParameters.ErsContext.LicenseType)1706 suite.AssertDisabledNetworkFilterRuntimeState(instance.RuntimeID, updateOperationID, &disabled)1707 instance2 := suite.GetInstance(id)1708 assert.Equal(suite.t, "CUSTOMER", *instance2.Parameters.ErsContext.LicenseType)1709}1710/* test disabled due to flakiness1711func TestUpdateStoreNetworkFilterWhileSVCATMigration(t *testing.T) {1712 // given1713 suite := NewBrokerSuiteTest(t, "2.0")1714 mockBTPOperatorClusterID()1715 defer suite.TearDown()1716 id := uuid.New().String()1717 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/v2/service_instances/%s?accepts_incomplete=true", id),1718 `{1719 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1720 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1721 "context": {1722 "sm_platform_credentials": {1723 "url": "https://sm.url",1724 "credentials": {1725 "basic": {1726 "username": "u-name",1727 "password": "pass"1728 }1729 }1730 },1731 "globalaccount_id": "g-account-id",1732 "subaccount_id": "sub-id",1733 "user_id": "john.smith@email.com"1734 },1735 "parameters": {1736 "name": "testing-cluster"1737 }1738 }`)1739 opID := suite.DecodeOperationID(resp)1740 suite.processReconcilingByOperationID(opID)1741 suite.WaitForOperationState(opID, domain.Succeeded)1742 instance := suite.GetInstance(id)1743 // then1744 suite.AssertDisabledNetworkFilterForProvisioning(nil)1745 suite.AssertDisabledNetworkFilterRuntimeState(instance.RuntimeID, opID, nil)1746 assert.Nil(suite.t, instance.Parameters.ErsContext.LicenseType)1747 // when1748 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1749 {1750 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1751 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1752 "context": {1753 "globalaccount_id": "g-account-id",1754 "user_id": "john.smith@email.com",1755 "sm_operator_credentials": {1756 "clientid": "testClientID",1757 "clientsecret": "testClientSecret",1758 "sm_url": "https://service-manager.kyma.com",1759 "url": "https://test.auth.com",1760 "xsappname": "testXsappname2"1761 },1762 "license_type": "CUSTOMER",1763 "isMigration": true1764 }1765 }`)1766 // then1767 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1768 updateOperationID := suite.DecodeOperationID(resp)1769 suite.FinishUpdatingOperationByReconcilerBoth(updateOperationID)1770 suite.WaitForOperationState(updateOperationID, domain.Succeeded)1771 instance2 := suite.GetInstance(id)1772 // license_type should be stored in the instance table for ERS context and future upgrades1773 // but shouldn't be sent to provisioner when migration is triggered1774 suite.AssertDisabledNetworkFilterForProvisioning(nil)1775 assert.Equal(suite.t, "CUSTOMER", *instance2.Parameters.ErsContext.LicenseType)1776 // when1777 // second update without triggering migration1778 // it should be fine if ERS omits license_type and KEB should reuse the last applied value1779 // because migration wasn't triggered, KEB should send payload to provisioner with network filter disabled1780 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1781 {1782 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1783 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1784 "context": {1785 "globalaccount_id": "g-account-id",1786 "user_id": "john.smith@email.com",1787 "sm_operator_credentials": {1788 "clientid": "testClientID",1789 "clientsecret": "testClientSecret",1790 "sm_url": "https://service-manager.kyma.com",1791 "url": "https://test.auth.com",1792 "xsappname": "testXsappname2"1793 }1794 }1795 }`)1796 // then1797 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1798 updateOperation2ID := suite.DecodeOperationID(resp)1799 suite.FinishUpdatingOperationByProvisioner(updateOperation2ID)1800 suite.WaitForOperationState(updateOperation2ID, domain.Succeeded)1801 instance3 := suite.GetInstance(id)1802 assert.Equal(suite.t, "CUSTOMER", *instance3.Parameters.ErsContext.LicenseType)1803 disabled := true1804 suite.AssertDisabledNetworkFilterRuntimeState(instance.RuntimeID, updateOperation2ID, &disabled)1805}1806*/1807func TestUpdateStoreNetworkFilterAndUpdate(t *testing.T) {1808 // given1809 suite := NewBrokerSuiteTest(t, "2.0")1810 mockBTPOperatorClusterID()1811 defer suite.TearDown()1812 id := uuid.New().String()1813 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/v2/service_instances/%s?accepts_incomplete=true", id),1814 `{1815 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1816 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1817 "context": {1818 "sm_operator_credentials": {1819 "clientid": "testClientID",1820 "clientsecret": "testClientSecret",1821 "sm_url": "https://service-manager.kyma.com",1822 "url": "https://test.auth.com",1823 "xsappname": "testXsappname2"1824 },1825 "globalaccount_id": "g-account-id",1826 "subaccount_id": "sub-id",1827 "user_id": "john.smith@email.com"1828 },1829 "parameters": {1830 "name": "testing-cluster"1831 }1832 }`)1833 opID := suite.DecodeOperationID(resp)1834 suite.processReconcilingByOperationID(opID)1835 suite.WaitForOperationState(opID, domain.Succeeded)1836 instance := suite.GetInstance(id)1837 // then1838 suite.AssertDisabledNetworkFilterForProvisioning(nil)1839 assert.Nil(suite.t, instance.Parameters.ErsContext.LicenseType)1840 // when1841 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1842 {1843 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1844 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1845 "context": {1846 "globalaccount_id": "g-account-id",1847 "user_id": "john.smith@email.com",1848 "sm_operator_credentials": {1849 "clientid": "testClientID",1850 "clientsecret": "testClientSecret",1851 "sm_url": "https://service-manager.kyma.com",1852 "url": "https://test.auth.com",1853 "xsappname": "testXsappname"1854 },1855 "license_type": "CUSTOMER"1856 }1857 }`)1858 // then1859 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1860 updateOperationID := suite.DecodeOperationID(resp)1861 updateOp, _ := suite.db.Operations().GetUpdatingOperationByID(updateOperationID)1862 assert.NotNil(suite.t, updateOp.ProvisioningParameters.ErsContext.LicenseType)1863 instance2 := suite.GetInstance(id)1864 // license_type should be stored in the instance table for ERS context and future upgrades1865 // as well as sent to provisioner because the migration has not been triggered1866 disabled := true1867 suite.AssertDisabledNetworkFilterRuntimeState(instance.RuntimeID, updateOperationID, &disabled)1868 assert.Equal(suite.t, "CUSTOMER", *instance2.Parameters.ErsContext.LicenseType)1869 suite.FinishUpdatingOperationByProvisionerAndReconciler(updateOperationID)1870 suite.WaitForOperationState(updateOperationID, domain.Succeeded)1871}1872func TestMultipleUpdateNetworkFilterPersisted(t *testing.T) {1873 // given1874 suite := NewBrokerSuiteTest(t, "2.0")1875 mockBTPOperatorClusterID()1876 defer suite.TearDown()1877 id := uuid.New().String()1878 resp := suite.CallAPI("PUT", fmt.Sprintf("oauth/v2/service_instances/%s?accepts_incomplete=true", id),1879 `{1880 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1881 "plan_id": "7d55d31d-35ae-4438-bf13-6ffdfa107d9f",1882 "context": {1883 "sm_operator_credentials": {1884 "clientid": "testClientID",1885 "clientsecret": "testClientSecret",1886 "sm_url": "https://service-manager.kyma.com",1887 "url": "https://test.auth.com",1888 "xsappname": "testXsappname2"1889 },1890 "globalaccount_id": "g-account-id",1891 "subaccount_id": "sub-id",1892 "user_id": "john.smith@email.com"1893 },1894 "parameters": {1895 "name": "testing-cluster"1896 }1897 }`)1898 opID := suite.DecodeOperationID(resp)1899 suite.processReconcilingByOperationID(opID)1900 suite.WaitForOperationState(opID, domain.Succeeded)1901 instance := suite.GetInstance(id)1902 // then1903 suite.AssertDisabledNetworkFilterForProvisioning(nil)1904 suite.AssertDisabledNetworkFilterRuntimeState(instance.RuntimeID, opID, nil)1905 assert.Nil(suite.t, instance.Parameters.ErsContext.LicenseType)1906 // when1907 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1908 {1909 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1910 "context": {1911 "license_type": "CUSTOMER"1912 }1913 }`)1914 // then1915 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1916 updateOperationID := suite.DecodeOperationID(resp)1917 suite.WaitForOperationState(updateOperationID, domain.Succeeded)1918 instance2 := suite.GetInstance(id)1919 assert.Equal(suite.t, "CUSTOMER", *instance2.Parameters.ErsContext.LicenseType)1920 // when1921 resp = suite.CallAPI("PATCH", fmt.Sprintf("oauth/cf-eu10/v2/service_instances/%s?accepts_incomplete=true", id), `1922 {1923 "service_id": "47c9dcbf-ff30-448e-ab36-d3bad66ba281",1924 "context":{},1925 "parameters":{1926 "name":"$instance",1927 "administrators":["jan.wozniak@sap.com", "wozniak.jan@gmail.com", "jan@kubermatic.com"]1928 }1929 }`)1930 // then1931 assert.Equal(t, http.StatusAccepted, resp.StatusCode)1932 updateOperation2ID := suite.DecodeOperationID(resp)1933 suite.FinishUpdatingOperationByProvisioner(updateOperation2ID)1934 suite.WaitForOperationState(updateOperation2ID, domain.Succeeded)1935 instance3 := suite.GetInstance(id)...

Full Screen

Full Screen

websocket.go

Source:websocket.go Github

copy

Full Screen

...82 historyAPIID int83 broadcastAPIID int84}85func (p *websocketAPI) getAPIID(identifier string) (int, error) {86 resp, err := p.wsClient.CallAPI(1, identifier, types.EmptyParams)87 if err != nil {88 return InvalidApiID, errors.Annotatef(err, "CallAPI %s", identifier)89 }90 logging.DDumpJSON("getApiID <", resp)91 var id int92 if err := ffjson.Unmarshal(*resp, &id); err != nil {93 return InvalidApiID, errors.Annotate(err, "Unmarshal [id]")94 }95 return id, nil96}97// login98func (p *websocketAPI) login() (bool, error) {99 resp, err := p.wsClient.CallAPI(1, "login", p.username, p.password)100 if err != nil {101 return false, errors.Annotate(err, "CallAPI")102 }103 logging.DDumpJSON("login <", resp)104 var success bool105 if err := ffjson.Unmarshal(*resp, &success); err != nil {106 return false, errors.Annotate(err, "Unmarshal [success]")107 }108 return success, nil109}110// SetSubscribeCallback - To simplify development a global subscription callback can be registered.111// Every notification initiated by the full node will carry a particular id as defined by the user with the identifier parameter.112func (p *websocketAPI) SetSubscribeCallback(ID uint64, clearFilter bool) error {113 _, err := p.wsClient.CallAPI(p.databaseAPIID, "set_subscribe_callback", ID, clearFilter)114 if err != nil {115 return errors.Annotate(err, "CallAPI")116 }117 return nil118}119// SubscribeToPendingTransactions - Notifications for incoming unconfirmed transactions.120func (p *websocketAPI) SubscribeToPendingTransactions(onPendingTransaction api.SubscribeCallback) error {121 _, err := p.wsClient.Subscribe(p.databaseAPIID, "set_pending_transaction_callback",122 onPendingTransaction,123 )124 return err125}126// SubscribeToBlockApplied gives a notification whenever the block blockid is applied to the blockchain.127func (p *websocketAPI) SubscribeToBlockApplied(onBlockApplied api.BlockAppliedCallback) error {128 _, err := p.wsClient.Subscribe(p.databaseAPIID, "set_block_applied_callback",129 func(in interface{}) error {130 for _, id := range in.([]interface{}) {131 if err := onBlockApplied(id.(string)); err != nil {132 return err133 }134 }135 return nil136 },137 )138 return err139}140// SubscribeToMarket subscribes to market changes in market base:quote and sends notifications by callback.141func (p *websocketAPI) SubscribeToMarket(base, quote types.GrapheneObject, onMarketData api.SubscribeCallback) error {142 _, err := p.wsClient.Subscribe(p.databaseAPIID, "subscribe_to_market",143 onMarketData, base.ID(), quote.ID(),144 )145 return err146}147// UnsubscribeFromMarket148func (p *websocketAPI) UnsubscribeFromMarket(base types.GrapheneObject, quote types.GrapheneObject) error {149 // returns nil if successful150 _, err := p.wsClient.CallAPI(p.databaseAPIID, "unsubscribe_from_market", base.ID(), quote.ID())151 if err != nil {152 return errors.Annotate(err, "CallAPI")153 }154 return nil155}156// CancelAllSubscriptions157func (p *websocketAPI) CancelAllSubscriptions() error {158 // returns nil159 _, err := p.wsClient.CallAPI(p.databaseAPIID, "cancel_all_subscriptions", types.EmptyParams)160 if err != nil {161 return errors.Annotate(err, "CallAPI")162 }163 return nil164}165// BroadcastTransaction broadcasts a transaction to the network.166// The transaction will be checked for validity prior to broadcasting. If it fails to apply at the connected node,167// an error will be thrown and the transaction will not be broadcast.168func (p *websocketAPI) BroadcastTransaction(tx *types.SignedTransaction) error {169 _, err := p.wsClient.CallAPI(p.broadcastAPIID, "broadcast_transaction", tx)170 if err != nil {171 return errors.Annotate(err, "CallAPI")172 }173 return nil174}175// BroadcastTransactionSynchronous broadcasts a transaction to the network.176// The transaction will be checked for validity prior to broadcasting. If it fails to apply at the connected node,177// an error will be thrown and the transaction will not be broadcast. This version of broadcast transaction registers a callback method178// that will be called when the transaction is included into a block. The callback method includes the transaction id, block number, and transaction number in the block.179func (p *websocketAPI) BroadcastTransactionSynchronous(tx *types.SignedTransaction) (*types.BroadcastResponse, error) {180 resp, err := p.wsClient.CallAPI(p.broadcastAPIID, "broadcast_transaction_synchronous", tx)181 if err != nil {182 return nil, errors.Annotate(err, "CallAPI")183 }184 var ret types.BroadcastResponse185 if err := ffjson.Unmarshal(*resp, &ret); err != nil {186 return nil, errors.Annotate(err, "Unmarshal [BroadcastResponse]")187 }188 return &ret, nil189}190//SignTransaction signs a given transaction.191//Required signing keys get selected by API and have to be in keyBag.192func (p *websocketAPI) SignTransaction(keyBag *crypto.KeyBag, tx *types.SignedTransaction) error {193 reqPk, err := p.RequiredSigningKeys(tx)194 if err != nil {195 return errors.Annotate(err, "RequiredSigningKeys")196 }197 signer := crypto.NewTransactionSigner(tx)198 privKeys := keyBag.PrivatesByPublics(reqPk)199 if len(privKeys) == 0 {200 return types.ErrNoSigningKeyFound201 }202 if err := signer.Sign(privKeys, config.Current()); err != nil {203 return errors.Annotate(err, "Sign")204 }205 return nil206}207//BuildSignedTransaction builds a new transaction by given operation(s),208//applies fees, current block data and signs the transaction.209func (p *websocketAPI) BuildSignedTransaction(keyBag *crypto.KeyBag, feeAsset types.GrapheneObject, ops ...types.Operation) (*types.SignedTransaction, error) {210 operations := types.Operations(ops)211 fees, err := p.GetRequiredFees(operations, feeAsset)212 if err != nil {213 return nil, errors.Annotate(err, "GetRequiredFees")214 }215 if err := operations.ApplyFees(fees); err != nil {216 return nil, errors.Annotate(err, "ApplyFees")217 }218 props, err := p.GetDynamicGlobalProperties()219 if err != nil {220 return nil, errors.Annotate(err, "GetDynamicGlobalProperties")221 }222 tx, err := types.NewSignedTransactionWithBlockData(props)223 if err != nil {224 return nil, errors.Annotate(err, "NewTransaction")225 }226 tx.Operations = operations227 reqPk, err := p.RequiredSigningKeys(tx)228 if err != nil {229 return nil, errors.Annotate(err, "RequiredSigningKeys")230 }231 signer := crypto.NewTransactionSigner(tx)232 privKeys := keyBag.PrivatesByPublics(reqPk)233 if len(privKeys) == 0 {234 return nil, types.ErrNoSigningKeyFound235 }236 if err := signer.Sign(privKeys, config.Current()); err != nil {237 return nil, errors.Annotate(err, "Sign")238 }239 return tx, nil240}241//RequiredSigningKeys is a convenience call to retrieve the minimum subset of public keys to sign a transaction.242//If the transaction is already signed, the result is empty.243func (p *websocketAPI) RequiredSigningKeys(tx *types.SignedTransaction) (types.PublicKeys, error) {244 potPk, err := p.GetPotentialSignatures(tx)245 if err != nil {246 return nil, errors.Annotate(err, "GetPotentialSignatures")247 }248 logging.DDumpJSON("potential pubkeys <", potPk)249 reqPk, err := p.GetRequiredSignatures(tx, potPk)250 if err != nil {251 return nil, errors.Annotate(err, "GetRequiredSignatures")252 }253 logging.DDumpJSON("required pubkeys <", reqPk)254 return reqPk, nil255}256//GetPotentialSignatures will return the set of all public keys that could possibly sign for a given transaction.257//This call can be used by wallets to filter their set of public keys to just the relevant subset prior to calling258//GetRequiredSignatures to get the minimum subset.259func (p *websocketAPI) GetPotentialSignatures(tx *types.SignedTransaction) (types.PublicKeys, error) {260 resp, err := p.wsClient.CallAPI(p.databaseAPIID, "get_potential_signatures", tx)261 if err != nil {262 return nil, errors.Annotate(err, "CallAPI")263 }264 logging.DDumpJSON("get_potential_signatures <", resp)265 ret := types.PublicKeys{}266 if err := ffjson.Unmarshal(*resp, &ret); err != nil {267 return nil, errors.Annotate(err, "Unmarshal [PublicKeys]")268 }269 return ret, nil270}271// GetTransaction used to fetch an individual transaction.272func (p *websocketAPI) GetTransaction(blockNum uint64, trxInBlock uint32) (*types.SignedTransaction, error) {273 resp, err := p.wsClient.CallAPI(p.databaseAPIID, "get_transaction", blockNum, trxInBlock)274 if err != nil {275 return nil, errors.Annotate(err, "CallAPI")276 }277 logging.DDumpJSON("get_transaction <", resp)278 ret := types.SignedTransaction{}279 if err := ffjson.Unmarshal(*resp, &ret); err != nil {280 return nil, errors.Annotate(err, "Unmarshal [Transaction]")281 }282 return &ret, nil283}284// GetRecentTransactionByID285// If the transaction has not expired, this method will return the transaction for the given ID or286// it will return nil if it is not known. Just because it is not known does not mean287// it wasn’t included in the blockchain.288func (p *websocketAPI) GetRecentTransactionByID(transactionID uint32) (*types.SignedTransaction, error) {289 resp, err := p.wsClient.CallAPI(p.databaseAPIID, "get_recent_transaction_by_id", transactionID)290 if err != nil {291 return nil, errors.Annotate(err, "CallAPI")292 }293 logging.DDumpJSON("get_recent_transaction_by_id <", resp)294 ret := types.SignedTransaction{}295 if err := ffjson.Unmarshal(*resp, &ret); err != nil {296 return nil, errors.Annotate(err, "Unmarshal [Transaction]")297 }298 return &ret, nil299}300//GetRequiredSignatures returns the minimum subset of public keys to sign a transaction.301func (p *websocketAPI) GetRequiredSignatures(tx *types.SignedTransaction, potKeys types.PublicKeys) (types.PublicKeys, error) {302 resp, err := p.wsClient.CallAPI(p.databaseAPIID, "get_required_signatures", tx, potKeys)303 if err != nil {304 return nil, errors.Annotate(err, "CallAPI")305 }306 logging.DDumpJSON("get_required_signatures <", resp)307 ret := types.PublicKeys{}308 if err := ffjson.Unmarshal(*resp, &ret); err != nil {309 return nil, errors.Annotate(err, "Unmarshal [PublicKeys]")310 }311 return ret, nil312}313//GetBlock returns a Block by number.314func (p *websocketAPI) GetBlock(block uint64) (*types.Block, error) {315 resp, err := p.wsClient.CallAPI(0, "get_block", block)316 if err != nil {317 return nil, errors.Annotate(err, "CallAPI")318 }319 logging.DDumpJSON("get_block <", resp)320 ret := types.Block{}321 if err := ffjson.Unmarshal(*resp, &ret); err != nil {322 return nil, errors.Annotate(err, "Unmarshal [Block]")323 }324 return &ret, nil325}326// GetBlockHeader returns block header by number.327func (p *websocketAPI) GetBlockHeader(block uint64) (*types.BlockHeader, error) {328 resp, err := p.wsClient.CallAPI(0, "get_block_header", block)329 if err != nil {330 return nil, errors.Annotate(err, "CallAPI")331 }332 logging.DDumpJSON("get_block_header <", resp)333 ret := types.BlockHeader{}334 if err := ffjson.Unmarshal(*resp, &ret); err != nil {335 return nil, errors.Annotate(err, "Unmarshal [BlockHeader]")336 }337 return &ret, nil338}339// GetTicker returns the ticker for the market base:quote for the last 24 h340func (p *websocketAPI) GetTicker(base, quote types.GrapheneObject) (*types.MarketTicker, error) {341 resp, err := p.wsClient.CallAPI(0, "get_ticker", base.ID(), quote.ID())342 if err != nil {343 return nil, errors.Annotate(err, "CallAPI")344 }345 logging.DDumpJSON("get_ticker <", resp)346 ret := types.MarketTicker{}347 if err := ffjson.Unmarshal(*resp, &ret); err != nil {348 return nil, errors.Annotate(err, "Unmarshal [MarketTicker]")349 }350 return &ret, nil351}352//GetAccountByName returns a Account object by username353func (p *websocketAPI) GetAccountByName(name string) (*types.Account, error) {354 resp, err := p.wsClient.CallAPI(0, "get_account_by_name", name)355 if err != nil {356 return nil, errors.Annotate(err, "CallAPI")357 }358 logging.DDumpJSON("get_account_by_name <", resp)359 ret := types.Account{}360 if err := ffjson.Unmarshal(*resp, &ret); err != nil {361 return nil, errors.Annotate(err, "Unmarshal [Account]")362 }363 return &ret, nil364}365// GetAccountHistory returns OperationHistory object(s).366// account: The account whose history should be queried367// stop: ID of the earliest operation to retrieve368// limit: Maximum number of operations to retrieve (must not exceed 100)369// start: ID of the most recent operation to retrieve370func (p *websocketAPI) GetAccountHistory(account types.GrapheneObject, stop types.GrapheneObject, limit int, start types.GrapheneObject) (types.OperationHistories, error) {371 if limit > GetAccountHistoryLimit {372 limit = GetAccountHistoryLimit373 }374 resp, err := p.wsClient.CallAPI(p.historyAPIID, "get_account_history", account.ID(), stop.ID(), limit, start.ID())375 if err != nil {376 return nil, errors.Annotate(err, "CallAPI")377 }378 logging.DDumpJSON("get_account_history <", resp)379 ret := types.OperationHistories{}380 if err := ffjson.Unmarshal(*resp, &ret); err != nil {381 return nil, errors.Annotate(err, "Unmarshal [Histories]")382 }383 return ret, nil384}385//GetAccounts returns a list of accounts by accountID(s).386func (p *websocketAPI) GetAccounts(accounts ...types.GrapheneObject) (types.Accounts, error) {387 ids := types.GrapheneObjects(accounts).ToStrings()388 resp, err := p.wsClient.CallAPI(0, "get_accounts", ids)389 if err != nil {390 return nil, errors.Annotate(err, "CallAPI")391 }392 logging.DDumpJSON("get_accounts <", resp)393 ret := types.Accounts{}394 if err := ffjson.Unmarshal(*resp, &ret); err != nil {395 return nil, errors.Annotate(err, "Unmarshal [Accounts]")396 }397 return ret, nil398}399//GetDynamicGlobalProperties returns essential runtime properties of bitshares network400func (p *websocketAPI) GetDynamicGlobalProperties() (*types.DynamicGlobalProperties, error) {401 resp, err := p.wsClient.CallAPI(0, "get_dynamic_global_properties", types.EmptyParams)402 if err != nil {403 return nil, errors.Annotate(err, "CallAPI")404 }405 logging.DDumpJSON("get_dynamic_global_properties <", resp)406 ret := types.DynamicGlobalProperties{}407 if err := ffjson.Unmarshal(*resp, &ret); err != nil {408 return nil, errors.Annotate(err, "Unmarshal [DynamicGlobalProperties]")409 }410 return &ret, nil411}412//GetAccountBalances retrieves AssetAmounts by given AccountID413func (p *websocketAPI) GetAccountBalances(account types.GrapheneObject, assets ...types.GrapheneObject) (types.AssetAmounts, error) {414 ids := types.GrapheneObjects(assets).ToStrings()415 resp, err := p.wsClient.CallAPI(0, "get_account_balances", account.ID(), ids)416 if err != nil {417 return nil, errors.Annotate(err, "CallAPI")418 }419 logging.DDumpJSON("get_account_balances <", resp)420 ret := types.AssetAmounts{}421 if err := ffjson.Unmarshal(*resp, &ret); err != nil {422 return nil, errors.Annotate(err, "Unmarshal [AssetAmounts]")423 }424 return ret, nil425}426// GetFullAccounts retrieves full account information by given AccountIDs427func (p *websocketAPI) GetFullAccounts(accounts ...types.GrapheneObject) (types.FullAccountInfos, error) {428 ids := types.GrapheneObjects(accounts).ToStrings()429 resp, err := p.wsClient.CallAPI(0, "get_full_accounts", ids, false) //do not subscribe for now430 if err != nil {431 return nil, errors.Annotate(err, "CallAPI")432 }433 logging.DDumpJSON("get_full_accounts <", resp)434 ret := types.FullAccountInfos{}435 if err := ffjson.Unmarshal(*resp, &ret); err != nil {436 return nil, errors.Annotate(err, "Unmarshal [FullAccountInfos]")437 }438 return ret, nil439}440// Get24Volume returns the base:quote assets 24h volume441func (p *websocketAPI) Get24Volume(base, quote types.GrapheneObject) (*types.Volume24, error) {442 resp, err := p.wsClient.CallAPI(p.databaseAPIID, "get_24_volume", base.ID(), quote.ID())443 if err != nil {444 return nil, errors.Annotate(err, "CallAPI")445 }446 logging.DDumpJSON("get_24_volume <", resp)447 ret := types.Volume24{}448 if err = ffjson.Unmarshal(*resp, &ret); err != nil {449 return nil, errors.Annotate(err, "Unmarshal [Volume24]")450 }451 return &ret, nil452}453// ListAssets retrieves assets454// lowerBoundSymbol: Lower bound of symbol names to retrieve455// limit: Maximum number of assets to fetch, if the constant AssetsListAll is passed, all existing assets will be retrieved.456func (p *websocketAPI) ListAssets(lowerBoundSymbol string, limit int) (types.Assets, error) {457 if limit > AssetsMaxBatchSize {458 limit = AssetsMaxBatchSize459 }460 resp, err := p.wsClient.CallAPI(0, "list_assets", lowerBoundSymbol, limit)461 if err != nil {462 return nil, errors.Annotate(err, "CallAPI")463 }464 logging.DDumpJSON("list_assets <", resp)465 ret := types.Assets{}466 if err := ffjson.Unmarshal(*resp, &ret); err != nil {467 return nil, errors.Annotate(err, "Unmarshal [Assets]")468 }469 return ret, nil470}471// LookupAssetSymbols get assets corresponding to the provided symbols or IDs472func (p *websocketAPI) LookupAssetSymbols(symbols ...string) (types.Assets, error) {473 resp, err := p.wsClient.CallAPI(0, "lookup_asset_symbols", symbols)474 if err != nil {475 return nil, errors.Annotate(err, "CallAPI")476 }477 logging.DDumpJSON("lookup_asset_symbols <", resp)478 ret := types.Assets{}479 if err := ffjson.Unmarshal(*resp, &ret); err != nil {480 return nil, errors.Annotate(err, "Unmarshal [Assets]")481 }482 return ret, nil483}484//GetRequiredFees calculates the required fee for each operation by the specified asset type.485func (p *websocketAPI) GetRequiredFees(ops types.Operations, feeAsset types.GrapheneObject) (types.AssetAmounts, error) {486 resp, err := p.wsClient.CallAPI(0, "get_required_fees", ops.Envelopes(), feeAsset.ID())487 if err != nil {488 return nil, errors.Annotate(err, "CallAPI")489 }490 logging.DDumpJSON("get_required_fees <", resp)491 ret := types.AssetAmounts{}492 if err := ffjson.Unmarshal(*resp, &ret); err != nil {493 return nil, errors.Annotate(err, "Unmarshal [AssetAmounts]")494 }495 return ret, nil496}497//GetLimitOrders returns LimitOrders type.498func (p *websocketAPI) GetLimitOrders(base, quote types.GrapheneObject, limit int) (types.LimitOrders, error) {499 if limit > GetLimitOrdersLimit {500 limit = GetLimitOrdersLimit501 }502 resp, err := p.wsClient.CallAPI(0, "get_limit_orders", base.ID(), quote.ID(), limit)503 if err != nil {504 return nil, errors.Annotate(err, "CallAPI")505 }506 logging.DDumpJSON("get_limit_orders <", resp)507 ret := types.LimitOrders{}508 if err := ffjson.Unmarshal(*resp, &ret); err != nil {509 return nil, errors.Annotate(err, "Unmarshal [LimitOrders]")510 }511 return ret, nil512}513// LimitOrderCancel cancels a certain limit order given by orderID. Fees are paid in feeAsset.514// The transaction is signed with private keys in keyBag.515func (p *websocketAPI) LimitOrderCancel(keyBag *crypto.KeyBag, feePayingAccount, orderID, feeAsset types.GrapheneObject) error {516 op := operations.LimitOrderCancelOperation{517 FeePayingAccount: types.AccountIDFromObject(feePayingAccount),518 Order: types.LimitOrderIDFromObject(orderID),519 Extensions: types.Extensions{},520 }521 trx, err := p.BuildSignedTransaction(keyBag, feeAsset, &op)522 if err != nil {523 return errors.Annotate(err, "BuildSignedTransaction")524 }525 if err := p.BroadcastTransaction(trx); err != nil {526 return errors.Annotate(err, "BroadcastTransaction")527 }528 return nil529}530//GetOrderBook returns the OrderBook for the market base:quote.531func (p *websocketAPI) GetOrderBook(base, quote types.GrapheneObject, depth int) (*types.OrderBook, error) {532 resp, err := p.wsClient.CallAPI(0, "get_order_book", base.ID(), quote.ID(), depth)533 if err != nil {534 return nil, errors.Annotate(err, "CallAPI")535 }536 logging.DDumpJSON("get_order_book <", resp)537 ret := types.OrderBook{}538 if err = ffjson.Unmarshal(*resp, &ret); err != nil {539 return nil, errors.Annotate(err, "Unmarshal [OrderBook]")540 }541 return &ret, nil542}543//GetForceSettlementOrders returns ForceSettlementOrders type.544func (p *websocketAPI) GetForceSettlementOrders(assetID types.GrapheneObject, limit int) (types.ForceSettlementOrders, error) {545 if limit > GetForceSettlementOrdersLimit {546 limit = GetForceSettlementOrdersLimit547 }548 resp, err := p.wsClient.CallAPI(0, "get_settle_orders", assetID.ID(), limit)549 if err != nil {550 return nil, errors.Annotate(err, "CallAPI")551 }552 logging.DDumpJSON("get_settle_orders <", resp)553 ret := types.ForceSettlementOrders{}554 if err := ffjson.Unmarshal(*resp, &ret); err != nil {555 return nil, errors.Annotate(err, "Unmarshal [ForceSettlementOrders]")556 }557 return ret, nil558}559//GetCallOrders returns CallOrders type.560func (p *websocketAPI) GetCallOrders(assetID types.GrapheneObject, limit int) (types.CallOrders, error) {561 if limit > GetCallOrdersLimit {562 limit = GetCallOrdersLimit563 }564 resp, err := p.wsClient.CallAPI(0, "get_call_orders", assetID.ID(), limit)565 if err != nil {566 return nil, errors.Annotate(err, "CallAPI")567 }568 logging.DDumpJSON("get_call_orders <", resp)569 ret := types.CallOrders{}570 if err := ffjson.Unmarshal(*resp, &ret); err != nil {571 return nil, errors.Annotate(err, "Unmarshal [CallOrders]")572 }573 return ret, nil574}575//GetMarginPositions returns CallOrders type.576func (p *websocketAPI) GetMarginPositions(accountID types.GrapheneObject) (types.CallOrders, error) {577 resp, err := p.wsClient.CallAPI(0, "get_margin_positions", accountID.ID())578 if err != nil {579 return nil, errors.Annotate(err, "CallAPI")580 }581 logging.DDumpJSON("get_margin_positions <", resp)582 ret := types.CallOrders{}583 if err := ffjson.Unmarshal(*resp, &ret); err != nil {584 return nil, errors.Annotate(err, "Unmarshal [CallOrders]")585 }586 return ret, nil587}588//GetTradeHistory returns MarketTrades type.589func (p *websocketAPI) GetTradeHistory(base, quote types.GrapheneObject, toTime, fromTime time.Time, limit int) (types.MarketTrades, error) {590 if limit > GetTradeHistoryLimit {591 limit = GetTradeHistoryLimit592 }593 resp, err := p.wsClient.CallAPI(0, "get_trade_history", base.ID(), quote.ID(), toTime, fromTime, limit)594 if err != nil {595 return nil, errors.Annotate(err, "CallAPI")596 }597 logging.DDumpJSON("get_trade_history <", resp)598 ret := types.MarketTrades{}599 if err := ffjson.Unmarshal(*resp, &ret); err != nil {600 return nil, errors.Annotate(err, "Unmarshal [MarketTrades]")601 }602 return ret, nil603}604//GetChainID returns the ID of the chain we are connected to.605func (p *websocketAPI) GetChainID() (string, error) {606 resp, err := p.wsClient.CallAPI(p.databaseAPIID, "get_chain_id", types.EmptyParams)607 if err != nil {608 return "", errors.Annotate(err, "CallAPI")609 }610 logging.DDumpJSON("get_chain_id <", resp)611 var id string612 if err := ffjson.Unmarshal(*resp, &id); err != nil {613 return "", errors.Annotate(err, "Unmarshal [id]")614 }615 return id, nil616}617//GetObjects returns a list of Graphene Objects by ID.618func (p *websocketAPI) GetObjects(ids ...types.GrapheneObject) ([]interface{}, error) {619 params := types.GrapheneObjects(ids).ToStrings()620 resp, err := p.wsClient.CallAPI(0, "get_objects", params)621 if err != nil {622 return nil, errors.Annotate(err, "CallAPI")623 }624 logging.DDumpJSON("get_objects <", resp)625 var data []interface{}626 if err := ffjson.Unmarshal(*resp, &data); err != nil {627 return nil, errors.Annotate(err, "Unmarshal [data]")628 }629 ret := make([]interface{}, 0)630 id := types.ObjectID{}631 for _, obj := range data {632 if obj == nil {633 continue634 }635 if err := id.FromRawData(obj); err != nil {636 return nil, errors.Annotate(err, "from raw data")637 }638 b := util.ToBytes(obj)639 //TODO: implement640 // ObjectTypeBase641 // ObjectTypeWitness642 // ObjectTypeCustom643 // ObjectTypeProposal644 // ObjectTypeWithdrawPermission645 // ObjectTypeWorker646 switch id.SpaceType() {647 case types.SpaceTypeProtocol:648 switch id.ObjectType() {649 case types.ObjectTypeVestingBalance:650 t := types.VestingBalance{}651 if err := t.UnmarshalJSON(b); err != nil {652 return nil, errors.Annotate(err, "Unmarshal [VestingBalance]")653 }654 ret = append(ret, t)655 case types.ObjectTypeAccount:656 t := types.Account{}657 if err := t.UnmarshalJSON(b); err != nil {658 return nil, errors.Annotate(err, "Unmarshal [Account]")659 }660 ret = append(ret, t)661 case types.ObjectTypeAsset:662 t := types.Asset{}663 if err := t.UnmarshalJSON(b); err != nil {664 return nil, errors.Annotate(err, "Unmarshal [Asset]")665 }666 ret = append(ret, t)667 case types.ObjectTypeForceSettlement:668 t := types.ForceSettlementOrder{}669 if err := t.UnmarshalJSON(b); err != nil {670 return nil, errors.Annotate(err, "Unmarshal [ForceSettlementOrder]")671 }672 ret = append(ret, t)673 case types.ObjectTypeLimitOrder:674 t := types.LimitOrder{}675 if err := t.UnmarshalJSON(b); err != nil {676 return nil, errors.Annotate(err, "Unmarshal [LimitOrder]")677 }678 ret = append(ret, t)679 case types.ObjectTypeCallOrder:680 t := types.CallOrder{}681 if err := t.UnmarshalJSON(b); err != nil {682 return nil, errors.Annotate(err, "Unmarshal [CallOrder]")683 }684 ret = append(ret, t)685 case types.ObjectTypeCommitteeMember:686 t := types.CommitteeMember{}687 if err := t.UnmarshalJSON(b); err != nil {688 return nil, errors.Annotate(err, "Unmarshal [CommitteeMember]")689 }690 ret = append(ret, t)691 case types.ObjectTypeOperationHistory:692 t := types.OperationHistory{}693 if err := t.UnmarshalJSON(b); err != nil {694 return nil, errors.Annotate(err, "Unmarshal [OperationHistory]")695 }696 ret = append(ret, t)697 case types.ObjectTypeBalance:698 t := types.Balance{}699 if err := t.UnmarshalJSON(b); err != nil {700 return nil, errors.Annotate(err, "Unmarshal [Balance]")701 }702 ret = append(ret, t)703 default:704 logging.DDumpUnmarshaled(id.ObjectType().String(), b)705 return nil, errors.Errorf("unable to parse Object with ID %s", id)706 }707 // TODO: implement708 // ObjectTypeGlobalProperty709 // ObjectTypeAssetDynamicData710 // ObjectTypeBlockSummary711 // ObjectTypeAccountTransactionHistory712 // ObjectTypeBlindedBalance713 // ObjectTypeChainProperty714 // ObjectTypeWitnessSchedule715 // ObjectTypeBudgetRecord716 case types.SpaceTypeImplementation:717 switch id.ObjectType() {718 case types.ObjectTypeSpecialAuthority:719 t := types.SpecialAuthority{}720 if err := t.UnmarshalJSON(b); err != nil {721 return nil, errors.Annotate(err, "Unmarshal [SpecialAuthority]")722 }723 ret = append(ret, t)724 case types.ObjectTypeTransaction:725 t := types.Transaction{}726 if err := t.UnmarshalJSON(b); err != nil {727 return nil, errors.Annotate(err, "Unmarshal [Transaction]")728 }729 ret = append(ret, t)730 case types.ObjectTypeDynamicGlobalProperty:731 t := types.DynamicGlobalProperties{}732 if err := t.UnmarshalJSON(b); err != nil {733 return nil, errors.Annotate(err, "Unmarshal [DynamicGlobalProperties]")734 }735 ret = append(ret, t)736 case types.ObjectTypeAccountStatistics:737 t := types.AccountStatistics{}738 if err := t.UnmarshalJSON(b); err != nil {739 return nil, errors.Annotate(err, "Unmarshal [AccountStatistics]")740 }741 ret = append(ret, t)742 case types.ObjectTypeAccountBalance:743 t := types.AccountBalance{}744 if err := t.UnmarshalJSON(b); err != nil {745 return nil, errors.Annotate(err, "Unmarshal [AccountBalance]")746 }747 ret = append(ret, t)748 case types.ObjectTypeAssetBitAssetData:749 t := types.BitAssetData{}750 if err := t.UnmarshalJSON(b); err != nil {751 return nil, errors.Annotate(err, "Unmarshal [BitAssetData]")752 }753 ret = append(ret, t)754 default:755 logging.DDumpUnmarshaled(id.ObjectType().String(), b)756 return nil, errors.Errorf("unable to parse Object with ID %s", id)757 }758 }759 }760 return ret, nil761}762// Transfer transfers a certain amount between two accounts. Fees are paid in feeAsset.763// The transaction is signed with private keys in keyBag.764func (p *websocketAPI) Transfer(keyBag *crypto.KeyBag, from, to, feeAsset types.GrapheneObject, amount types.AssetAmount, memo string) error {765 op := operations.TransferOperation{766 Amount: amount,767 Extensions: types.Extensions{},768 From: types.AccountIDFromObject(from),769 To: types.AccountIDFromObject(to),770 }771 if memo != "" {772 builder := p.NewMemoBuilder(from, to, memo)773 m, err := builder.Encrypt(keyBag)774 if err != nil {775 return errors.Annotate(err, "Encrypt [memo]")776 }777 op.Memo = m778 }779 trx, err := p.BuildSignedTransaction(keyBag, feeAsset, &op)780 if err != nil {781 return errors.Annotate(err, "BuildSignedTransaction")782 }783 if err := p.BroadcastTransaction(trx); err != nil {784 return errors.Annotate(err, "BroadcastTransaction")785 }786 return nil787}788//DatabaseAPIID returns the database API ID789func (p *websocketAPI) DatabaseAPIID() int {790 return p.databaseAPIID791}792//BroadcastAPIID returns the broadcast API ID793func (p *websocketAPI) BroadcastAPIID() int {794 return p.broadcastAPIID795}796//HistoryAPIID returns the history API ID797func (p *websocketAPI) HistoryAPIID() int {798 return p.historyAPIID799}800//CallWsAPI invokes a websocket API call801func (p *websocketAPI) CallWsAPI(apiID int, method string, args ...interface{}) (*json.RawMessage, error) {802 return p.wsClient.CallAPI(apiID, method, args...)803}804//Subscribe - hook your subscribe callback here805func (p *websocketAPI) Subscribe(apiID int, method string, fn api.SubscribeCallback, args ...interface{}) (*json.RawMessage, error) {806 return p.wsClient.Subscribe(apiID, method, fn, args...)807}808//OnError - hook your error callback here809func (p *websocketAPI) OnError(errorFn api.ErrorFunc) {810 p.wsClient.OnError(errorFn)811}812//SetCredentials defines username and password for Websocket API login.813func (p *websocketAPI) SetCredentials(username, password string) {814 p.username = username815 p.password = password816}...

Full Screen

Full Screen

main.go

Source:main.go Github

copy

Full Screen

1package gonotion2import (3 "bytes"4 "encoding/json"5 "fmt"6 "io"7 "io/ioutil"8 "net/http"9 "github.com/pkg/errors"10)11type NotionClient struct {12 Token string13}14type Property struct {15 Id *string `json:"id,omitempty"`16 Type *string `json:"type,omitempty"`17 Name *string `json:"name,omitempty"`18 Formula *FormulaProp `json:"formula,omitempty"`19 Title *[]TitleProp `json:"title,omitempty"`20 Date *DateProp `json:"date,omitempty"`21 Number *int `json:"number,omitempty"`22 Checkbox *bool `json:"checkbox,omitempty"`23}24type DateProp struct {25 Start *string `json:"start,omitempty"`26 End *string `json:"end,omitempty"`27}28type TitleProp struct {29 Type *string `json:"type,omitempty"`30 Text *TextProp `json:"text,omitempty"`31 PlainText *string `json:"plain_text,omitempty"`32 Href *string `json:"href,omitempty"`33}34type TextProp struct {35 Content *string `json:"content,omitempty"`36 Link *Link `json:"link,omitempty"`37}38type Link struct {39 Url *string `json:"url,omitempty"`40}41type FormulaProp struct {42 Type *string `json:"type,omitempty"`43 String *string `json:"string,omitempty"`44 Number *int `json:"number,omitempty"`45}46type FileObject struct {47 Type *string `json:"type,omitempty"`48 File *FileUrlWrapper `json:"file,omitempty"`49}50type FileUrlWrapper struct {51 Url *string `json:"url,omitempty"`52 ExpiryTime *string `json:"expiry_time,omitempty"`53}54type QueryResult struct {55 Object *string `json:"object,omitempty"`56 Results *[]Page `json:"results,omitempty"`57 Code string `json:"code"`58 Message string `json:"message"`59}60func (c *NotionClient) callApi(path string, method string, headers *map[string]string, body io.Reader) ([]byte, error) {61 url := fmt.Sprintf("https://api.notion.com/v1%v", path)62 req, err := http.NewRequest(method, url, body)63 if err != nil {64 return nil, errors.Wrap(err, "(callApi) create request")65 }66 req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", c.Token))67 req.Header.Set("Notion-Version", "2021-05-13")68 if headers != nil {69 for idx, el := range *headers {70 req.Header.Set(idx, el)71 }72 }73 client := &http.Client{}74 res, err := client.Do(req)75 if err != nil {76 return nil, errors.Wrap(err, "(callApi) exec request")77 }78 defer res.Body.Close()79 if res.StatusCode < 200 || res.StatusCode > 299 {80 out, _ := ioutil.ReadAll(res.Body)81 return nil, errors.New(fmt.Sprintf("Failed to call %v with status %v, response: %v", path, res.StatusCode, string(out)))82 }83 out, err := ioutil.ReadAll(res.Body)84 if err != nil {85 return nil, errors.Wrap(err, "(callApi) ioutil.readall")86 }87 return out, nil88}89func (c *NotionClient) QueryDatabase(databaseId string, queryFilter *QueryFilter) (*QueryResult, error) {90 headers := map[string]string{91 "Content-Type": "application/json",92 }93 var qr QueryResult94 var body *bytes.Buffer95 if queryFilter != nil {96 jsonData, err := json.Marshal(queryFilter)97 if err != nil {98 return nil, errors.Wrap(err, "(QueryDatabase) marshal json")99 }100 body = bytes.NewBuffer(jsonData)101 }102 path := fmt.Sprintf("/databases/%v/query", databaseId)103 bytes, err := c.callApi(path, "POST", &headers, body)104 if err != nil {105 return nil, errors.Wrap(err, "(QueryDatabase) callApi")106 }107 err = json.Unmarshal(bytes, &qr)108 if err != nil {109 return nil, errors.Wrap(err, "(QueryDatabase) unmarshal response")110 }111 return &qr, nil112}113func (c *NotionClient) UpdatePage(pageId string, updates Page) error {114 jsonData, err := json.Marshal(updates)115 if err != nil {116 return errors.Wrap(err, "(UpdatePage) marshal json")117 }118 body := bytes.NewBuffer(jsonData)119 headers := map[string]string{120 "Content-Type": "application/json",121 }122 path := fmt.Sprintf("/pages/%v", pageId)123 _, err = c.callApi(path, "PATCH", &headers, body)124 return err125}126func (c *NotionClient) FetchPage(pageId string) (*Page, error) {127 path := fmt.Sprintf("/pages/%v", pageId)128 bytes, err := c.callApi(path, "GET", nil, nil)129 if err != nil {130 return nil, errors.Wrap(err, "(FetchPage) callApi")131 }132 var page Page133 err = json.Unmarshal(bytes, &page)134 if err != nil {135 return nil, errors.Wrap(err, "(FetchPage) unmarshal json")136 }137 return &page, nil138}...

Full Screen

Full Screen

CallAPI

Using AI Code Generation

copy

Full Screen

1func main() {2 client := &Client{}3 client.CallAPI()4}5func main() {6 client := &Client{}7 client.CallAPI()8}9func main() {10 client := &Client{}11 client.CallAPI()12}13func main() {14 client := &Client{}15 client.CallAPI()16}17func main() {18 client := &Client{}19 client.CallAPI()20}21func main() {22 client := &Client{}23 client.CallAPI()24}25func main() {26 client := &Client{}27 client.CallAPI()28}29func main() {30 client := &Client{}31 client.CallAPI()32}33func main() {34 client := &Client{}35 client.CallAPI()36}37func main() {38 client := &Client{}39 client.CallAPI()40}41func main() {42 client := &Client{}43 client.CallAPI()44}45func main() {46 client := &Client{}47 client.CallAPI()48}49func main() {50 client := &Client{}51 client.CallAPI()52}53func main() {54 client := &Client{}55 client.CallAPI()56}57func main() {58 client := &Client{}59 client.CallAPI()60}

Full Screen

Full Screen

CallAPI

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 c.CallAPI()4}5import (6func main() {7 c.CallAPI()8}9import (10func main() {11 c.CallAPI()12}13import (14func main() {15 c.CallAPI()16}17import (18func main() {19 c.CallAPI()20}21import (22func main() {23 c.CallAPI()24}25import (26func main() {27 c.CallAPI()28}29import (30func main() {31 c.CallAPI()32}33import (34func main() {35 c.CallAPI()36}37import (38func main() {39 c.CallAPI()40}41import (42func main() {43 c.CallAPI()44}

Full Screen

Full Screen

CallAPI

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 client := client.Client{}4 client.CallAPI()5}6import (7type Client struct {8}9func (c *Client) CallAPI() {10 fmt.Println("API called")11}12import (13type Client struct {14}15func (c *Client) CallAPI() {16 fmt.Println("API called")17}18import (19type Client struct {20}21func (c *Client) CallAPI() {22 fmt.Println("API called")23}24import (25type Client struct {26}27func (c *Client) CallAPI() {28 fmt.Println("API called")29}30import (31type Client struct {32}33func (c *Client) CallAPI() {34 fmt.Println("API called")35}36import (37type Client struct {38}39func (c *Client) CallAPI() {40 fmt.Println("API called")41}42import (43type Client struct {44}45func (c *Client) CallAPI() {46 fmt.Println("API called")47}48import (49type Client struct {50}51func (c *Client) CallAPI() {52 fmt.Println("API called")53}54import (55type Client struct {56}57func (c *Client) CallAPI() {58 fmt.Println("API called")59}60import (61type Client struct {62}63func (c *Client) CallAPI() {64 fmt.Println("API called")65}66import (67type Client struct {68}69func (c *Client) CallAPI() {70 fmt.Println("API called")71}72import (73type Client struct {74}75func (c *Client) CallAPI() {76 fmt.Println("API called")77}78import (

Full Screen

Full Screen

CallAPI

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 if err != nil {4 fmt.Println("Error in calling API")5 }6 fmt.Println(response)7}8import (9type Client struct {10}11func NewClient(baseURL string) *Client {12 return &Client{13 }14}15func (c *Client) CallAPI(path string) (string, error) {16 resp, err := http.Get(path)17 if err != nil {18 }19 defer resp.Body.Close()20 body, err := ioutil.ReadAll(resp.Body)21 if err != nil {22 }23 return string(body), nil24}

Full Screen

Full Screen

CallAPI

Using AI Code Generation

copy

Full Screen

12017/02/28 12:08:16 Unable to locate package for import: github.com/abc/client2import "fmt"3type Client interface {4 CallAPI() error5}6func NewClient() Client {7 return &client{}8}9type client struct{}10func (c *client) CallAPI() error {11 fmt.Println("Calling API")12}13import (14type MockClient struct {15}16func (m *MockClient) CallAPI() error {17 args := m.Called()18 return args.Error(0)19}20func TestClient(t *testing.T) {21 c := NewClient()22 assert.NotNil(t, c)23}24import (25type MockClient struct {26}27func (m *MockClient) CallAPI() error {28 args := m.Called()29 return args.Error(0)30}31import (32func main() {33 c := client.NewClient()

Full Screen

Full Screen

CallAPI

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 client := test.NewClient()4 if err != nil {5 fmt.Println(err.Error())6 }7 fmt.Println(resp)8}9 /usr/local/go/src/github.com/username/test (from $GOROOT)10 /home/user/go/src/github.com/username/test (from $GOPATH)11 /home/user/go/src/github.com/username/test (from $GOROOT)12 /home/user/go/src/github.com/username/test (from $GOPATH)

Full Screen

Full Screen

CallAPI

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 var client = new(client.Client)4 client.CallAPI()5 fmt.Println("Hello World")6}7import (8func main() {9 var client = new(client.Client)10 client.CallAPI()11 fmt.Println("Hello World")12}13import (14func main() {15 var client = new(client.Client)16 client.CallAPI()17 fmt.Println("Hello World")18}19import (20func main() {21 var client = new(client.Client)22 client.CallAPI()23 fmt.Println("Hello World")24}25import (26func main() {27 var client = new(client.Client)28 client.CallAPI()29 fmt.Println("Hello World")30}31import (32func main() {33 var client = new(client.Client)34 client.CallAPI()35 fmt.Println("Hello World")36}37import (38func main() {39 var client = new(client.Client)40 client.CallAPI()41 fmt.Println("Hello World")42}43import (44func main() {45 var client = new(client.Client)46 client.CallAPI()47 fmt.Println("Hello World")48}49import (50func main() {

Full Screen

Full Screen

CallAPI

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 client := client.Client{}4 client.CallAPI()5 fmt.Println("Hello")6}7import (8type Client struct {9}10func (c *Client) CallAPI() {11 fmt.Println("Calling API")12 service := service.Service{}13 service.DoSomething()14}15import "fmt"16type Service struct {17}18func (s *Service) DoSomething() {19 fmt.Println("Doing something")20}

Full Screen

Full Screen

CallAPI

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 clientObj := client.Client{}4 if err != nil {5 fmt.Println("Error occurred while calling API")6 } else {7 fmt.Println(response)8 }9}10{1 1 sunt aut facere repellat provident occaecati excepturi optio reprehenderit 1}

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run K6 automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful