loadAndMigrateTidbManagedState function

Future<TidbManagedStateLoadResult> loadAndMigrateTidbManagedState(
  1. Map<String, dynamic> secrets, {
  2. String environment = "prod",
})

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,
  );
}