diff --git a/VERSION b/VERSION index ee6cdce..b1d7abc 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.6.1 +0.6.2 \ No newline at end of file diff --git a/app/services/sync_service.py b/app/services/sync_service.py index d65bf6e..bd2ab34 100644 --- a/app/services/sync_service.py +++ b/app/services/sync_service.py @@ -242,7 +242,9 @@ def _sync_vps(session: Session, provider: Provider, adapter: BaseAdapter, accoun existing.currency = vps.currency if expiry: existing.expiry_date = expiry - if account_id: + # 一条资源可能对多个子账号可见:归属只补空,不覆盖已有值, + # 否则每次同步都会按最后同步的账号来回改,手工指定的归属也会被冲掉 + if account_id and not existing.account_id: existing.account_id = account_id session.add(existing) detail = session.exec( @@ -299,7 +301,8 @@ def _sync_domains(session: Session, provider: Provider, adapter: BaseAdapter, ac existing.status = _norm_status(dom.status) if expiry: existing.expiry_date = expiry - if account_id: + # 同 VPS:多子账号可见时保持首次归属,避免同步互相覆盖 + if account_id and not existing.account_id: existing.account_id = account_id session.add(existing) detail = session.exec( diff --git a/tests/test_sync_service.py b/tests/test_sync_service.py index f3bd348..0e6cbf9 100644 --- a/tests/test_sync_service.py +++ b/tests/test_sync_service.py @@ -257,8 +257,30 @@ def test_sync_account_去重_provider_id_external_id(engine, master_key, monkeyp assert detail.ip_address == "9.9.9.9" -# ----------------------------- 场景 3:适配器异常容错 ----------------------------- # +def test_sync_keeps_account_attribution_when_multiple_subaccounts_see_same_asset( + engine, master_key, monkeypatch +): + """一条资源对多个子账号可见时,后同步的账号不能把归属改走。 + 腾讯云 CAM 子账号常见场景:只读子账号也能看到全部实例。归属应在首次 + 同步时确定,之后保持稳定,手工在资产里改过的归属也不能被同步冲掉。 + """ + vps_list = [NormalizedVPS(external_id="vps-shared", name="shared", status="active")] + adapter = MockAdapter(config={"api_key": "fake"}, vps_list=vps_list) + _patch_adapter(monkeypatch, adapter) + + with Session(engine) as s: + _seed_provider(s) + first = _seed_account(s, name="sub-a@example.com") + second = _seed_account(s, name="sub-b@example.com") + sync_service.sync_account(s, first.id) + sync_service.sync_account(s, second.id) + + asset = s.exec(select(Asset).where(Asset.external_id == "vps-shared")).one() + assert asset.account_id == first.id + + +# ----------------------------- 场景 3:适配器异常容错 ----------------------------- # def test_sync_account_vps异常_域名仍可同步(engine, master_key, monkeypatch): """VPS 同步抛异常时,域名同步不受影响,错误记录在结果中"""