Reconcile the simulated cloud
This guide runs reconciliation against the cloud a simulated month serves. A run answers the OpenStack listings a sync reads out of the same oracle a comparison holds an export to, so the projection is corrected against the month the generator built, which is described in the simulated OpenStack world.
Before you start
- A dev cluster from
make upwith a month publishing on the compose stack, which run a simulated month starts. The fake API is up for exactly as long as therunpublishes or holds. kubectlwith thekind-tallycontext, pluscurlandjqon the machine the loop runs on.tally-dev-internal-token, the internal token of the dev overlay, which the internal sync route is guarded by.- The simulator command line page, which lists the routes of the fake OpenStack API a run serves.
- The simulator settings page, which names
TALLY_SIM_HTTP_ADDRandTALLY_SIM_HTTP_PORT, the two the fake API and the control endpoint are served on.
Wire the dev overlay to the fake API
Read the wiring the dev overlay ships.
deploy/kubernetes/overlays/dev/reconciliation/holds the clouds config and the clouds.yaml the pod reads. The clouds config is generated into a ConfigMap and the clouds.yaml into a Secret, because that one carries the cloud's password, and the two are projected together at/etc/tally/clouds. The clouds file example is the entry that directory carries.Take the three values the overlay sets. It sets
TALLY_REPORTING_SYNC_ALLOW_ATto true, so theatmember of a sync body is taken. It setsTALLY_REPORTING_SYNC_SETTLE_Sto 0, so the settle window is off there and a run defers nothing for a recent change: the window would be measured against the told instant of a month that runs faster than the wall clock. The cloud isos-sim, theSIM_CLOUDdefault, reached from the pod in the kind node athttp://tally-openstack-simulator:8080/v3.Edit both files of that directory for a drill under another cloud name. What an entry holds, and what the adapter needs of the account behind it, is in reconcile a cloud.
Run the sync loop
Start the port-forward and the loop in a second shell right after the stack's URLs print. It posts one sync per minute and tells each one where the month stands, which
GET /clockanswers undervirtual_now, held at theperiod_toof the same document:shkubectl --context kind-tally -n tally port-forward svc/reporting-api 8082:80 & while true; do doc="$(curl -sS --max-time 30 http://127.0.0.1:8091/clock)" \ || echo "clock read failed at $(date -u +%FT%TZ)" >&2 at="$(jq -r 'if .virtual_now > .period_to then .period_to else .virtual_now end' <<<"$doc")" body="$(jq -nc --arg at "$at" '{at: $at}')" curl -sS --max-time 65 -X POST \ -H "Authorization: Bearer tally-dev-internal-token" \ -H 'Content-Type: application/json' -d "$body" \ http://127.0.0.1:8082/internal/sync/os-sim \ || echo "sync post failed at $(date -u +%FT%TZ) (at=$at)" >&2 echo sleep 60 doneSixty wall seconds are about 12.4 virtual hours at factor 744.
Stop the loop when
publishedreachestotal: Ctrl-C on the loop, thenkill %1on the port-forward it started. What goes into a write-up is the totals the answers carried:created,updatedanddeleted.
Check the result
Read the answer of an iteration that reached the Reporting API. One of four comes back. The first is the document below, with the counts the sync found:
json{"sync_run_id": "...", "stats": {"created": 0, "updated": 0, "deleted": 0}}At factor 744 a sync corrects the resources whose notifications the collector has consumed and not posted yet: its outbox goes out every 5 seconds (
TALLY_OSC_FLUSH_INTERVAL_S, 62 virtual minutes at this factor). Such a correction is async.createdated at the platform's instant, which is the instant the collector's own create carries, async.updatedated at the told instant, or async.deletefound by absence and dated there as well. A load balancer needs no lost notification to be corrected: the first sync after a balancer'soctavia.loadbalancer.update.endbooks async.updatewith its listener and pool counts, and the sync after the dayapi-prodgets its third listener books one more.0, 0, 0is what a sync answers when the outbox was empty at its instant and no balancer changed since the sync before.Read a
409witha sync for this cloud is already runningas the previous iteration's run still holding the cloud. The next iteration waits it out.Read a
500withthe sync run failedas a sync that was running when the fake API went away. A loop stopped after the run has ended gets the400below instead.Read a
400withthe request does not match the API contractandbody.atin itserrorsas/clocknot answering: before the run listens and after it has ended. Theatthejqderives is the empty string there, and the OpenAPI validation of the Reporting API refuses the body before the handler sees it.