loadAndMigrateTidbManagedState function
Loads TiDB state and migrates legacy automatically managed secrets.
Implementation
Future<TidbManagedStateLoadResult> loadAndMigrateTidbManagedState(
Map<String, dynamic> secrets,
{String environment = "prod"}) async {
final statePath = tidbManagedStatePathFor(environment);
final file = File(statePath);
final legacyFile = File(tidbLegacyManagedStatePath);
final source = file.existsSync()
? file
: environment == "prod" && legacyFile.existsSync()
? legacyFile
: null;
final loaded = source != null
? Map<String, dynamic>.from(
modifize(loadYaml(await source.readAsString())) as Map? ?? {},
)
: <String, dynamic>{};
final state = _stringMap(loaded);
final cloudflare = _nested(secrets, ["cloudflare"]);
final tidbSecrets = _nested(cloudflare, ["tidb"]);
var secretsChanged = false;
var stateChanged = !file.existsSync();
for (final key in const ["data_service", "cutover"]) {
final legacy = environment == "prod"
? _meaningfulMap(tidbSecrets[key])
: <String, dynamic>{};
final current = _meaningfulMap(state[key]);
if (legacy.isNotEmpty) {
final merged = _mergeManagedState(
current,
legacy,
key,
statePath,
);
if (!_deepEqual(current, merged)) {
state[key] = merged;
stateChanged = true;
}
} else if (current.isNotEmpty) {
state[key] = current;
}
if (environment == "prod" && tidbSecrets.containsKey(key)) {
tidbSecrets.remove(key);
secretsChanged = true;
}
}
if (tidbSecrets.containsKey("connection_url")) {
tidbSecrets.remove("connection_url");
secretsChanged = true;
}
if (state["version"] != 1) {
state["version"] = 1;
stateChanged = true;
}
for (final key in const ["data_service", "cutover"]) {
if (!state.containsKey(key)) {
state[key] = <String, dynamic>{};
stateChanged = true;
}
}
return TidbManagedStateLoadResult(
state: state,
secretsChanged: secretsChanged,
stateChanged: stateChanged,
);
}