İçeriğe geç
academia.sh

Ders 22 / 27

Politika ve Uyumluluk Taraması

Dışarıdan gelen kuralların altyapı kaydı üzerinde koşturulması: aynı politika kümesinin bir kez tanım metni üzerinde, bir kez çözülmüş plan üzerinde koşturulması, iki taramanın yakalanan, kaçan ve yanlış alarm sayılarının karşılaştırılması, hesaplanan değerlerin tanım taramasından nasıl kaçtığı, erkenlik ile doğruluk arasındaki değiş tokuş ve muafiyet kaydının rapordan düşürdüğü ihlallerin sayılması.

İçindekiler

Önceki ders kaydın doğruluğunu sınadı: biçimi tutuyor mu, söz dizimi geçerli mi, başvurular çözülüyor mu. Bunların hepsi kaydın kendi kurallarıydı. Ama kusursuz bir kayıt yine de kabul edilemez olabilir — şifrelemesi kapalı bir arşiv, açık ağa bakan bir makine ya da yedeği üç gün olan bir veri deposu söz dizimi bakımından kusursuzdur.

Politika taraması dışarıdan gelen kuralları kayıt üzerinde koşturur. Yakalanan, kaçan ve yanlış alarm üçlüsü daha önce uygunluk işlevi ölçülürken mimari kurallar üzerinde kurulmuştu; mekaniği orada ölçüldüğü için burada tekrarlanmaz, değişen ölçülen nesnedir. Bu dersin sorusu şudur: politika tanım üzerinde mi, yoksa plan üzerinde mi koşmalı? Tanım erkendir ve sağlayıcıya hiç bağlanmaz ama yalnız yazılanı görür; plan geçtir ve sağlayıcı çağrısı ister ama çözülmüş değeri görür. İki tarama aynı politika kümesiyle aynı kayıt üzerinde koşturulur ve dört şey sayılır: yakalanan, kaçan, yanlış alarm ve muafiyetin açtığı yol. Through-line bölgesel ölçüm ağıdır ve kurgudur.

Yazılan Değer ile Çözülen Değer

Bir kayıtta yazılan her değer okunduğu gibi değildir. Dört yerde metin ile gerçek ayrılır: değişken (değer başka satırda tanımlıdır), sağlayıcı varsayılanı (alan bırakılır, değeri sağlayıcı koyar), küme temelli yineleme (tek blok birden çok örneğe açılır) ve koşul (blok belirli bir ortamda hiç yaratılmaz). Politikanın hangi katmanda koşacağı sorusu tam da bu dördü yüzünden vardır.

AD7 — ölçüm ağının üretim ortamı tek bir kayıt dosyasında tutulur ve dördünü de içerir (kurgu). AD8 — sağlayıcı varsayılanları kurgudur: makinenin genel ağ alanı boş bırakılırsa evet, nesne deposunun şifreleme alanı boş bırakılırsa hayir gelir. AD9 — uygulama anında atanan değerler kayıtta @atanacak olarak durur ve planda da çözülmez.

// kayit.mjs — olcum aginin uretim ortami kaydini yazar; degisken, saglayici varsayilani,
// kume temelli yineleme ve kosul icerir (kurgu)
import { writeFileSync } from "node:fs";

const KAYIT = `degisken ortam = uretim
degisken sahip = olcum-ekibi
degisken yedek = 3

kaynak ag/omurga-bati:
  bolge = bati
  blok  = 10.20.0.0/16
  sahip = $sahip

kaynak ag/omurga-dis:
  bolge = bati
  blok  = 198.51.100.0/24
  sahip = $sahip

kaynak makine/toplayici:
  yinele      = bati,dogu,kuzey
  bolge       = $yinele
  genel_ip    = evet
  genel_adres = @atanacak
  sahip       = $sahip

kaynak makine/gecit:
  bolge       = bati
  genel_ip    = evet
  genel_adres = @atanacak
  sahip       = $sahip
  muafiyet    = P2:2026-03-31

kaynak makine/arsivci:
  bolge       = bati
  genel_ip    = @varsayilan
  genel_adres = @atanacak
  sahip       = $sahip

kaynak makine/deneme:
  kosul       = ortam=hazirlik
  bolge       = bati
  genel_ip    = evet
  genel_adres = @atanacak
  sahip       = $sahip

kaynak veri_deposu/olcum-deposu:
  bolge    = bati
  yedek    = $yedek
  sahip    = $sahip
  muafiyet = *:2026-06-30

kaynak kuyruk/olcum-kuyrugu:
  bolge   = bati
  saklama = 720

kaynak kuyruk/deneme-kuyrugu:
  kosul   = ortam=hazirlik
  bolge   = bati
  saklama = 720
  sahip   = $sahip

kaynak nesne_deposu/olcum-arsiv:
  bolge    = bati
  sifreli  = @varsayilan
  sahip    = $sahip
  muafiyet = P1:2025-11-30
`;

writeFileSync("kayit.tanim", KAYIT);
const say = (k) => (KAYIT.match(k) ?? []).length;
console.log(`kayit.tanim: ${KAYIT.split("\n").length - 1} satir, ${say(/^degisken /gm)} degisken, ` +
  `${say(/^kaynak /gm)} blok\n`);
console.log(`cozulmesi gereken deger: ${say(/= \$/gm)} degisken basvurusu, ` +
  `${say(/@varsayilan/g)} saglayici varsayilani, ${say(/@atanacak/g)} uygulamada atanan; ` +
  `${say(/^  yinele /gm)} yinelemeli blok, ${say(/^  kosul /gm)} kosullu blok, ` +
  `${say(/^  muafiyet /gm)} muafiyet kaydi`);
kayit.tanim: 62 satir, 3 degisken, 10 blok

cozulmesi gereken deger: 11 degisken basvurusu, 2 saglayici varsayilani, 4 uygulamada atanan; 1 yinelemeli blok, 2 kosullu blok, 3 muafiyet kaydi

On blok yazılıdır ama plana on blok girmez: biri yinelemeyle üç örneğe açılır, ikisi koşulu tutmadığı için hiç girmez. Tanım katmanında on yedi değer henüz çözülmemiş durumdadır.

İki Tarama

AD10 — politika kümesi yedi kuraldır ve ekipçe kabul edilmiştir (kurgu). P1 nesne deposu şifreli olmalı, P2 makine açık ağa bakmamalı, P3 veri deposu yedeği en az yedi gün olmalı, P4 kuyruk saklaması en çok 168 saat olmalı, P5 her kaynağın sahibi yazılmalı, P6 ağ bloğu özel aralıkta olmalı, P7 makinenin genel adresi kayıtlı aralıkta olmalı. AD11 — muafiyet kaydı bir politika koduna (ya da * jokerine) ve bir bitiş tarihine bağlıdır; bugün 2026-02-15 kabul edilir (kurgu). AD12 — plan üretimi sağlayıcıya tür başına bir çağrı yapar; çağrı dört, örnek başına plan hesabı bir saniyedir (kurgu).

Her politika okuduğu alanı bildirir. Bir tarama o alanın değerini çözemiyorsa — değer $ ya da @ ile başlıyorsa — kural kararsız kalır ve ne ihlal ne uygun sayılır. Plan taraması gerçeği görür; tanım taraması onunla karşılaştırılır.

// tara.mjs — ayni politika kumesi once tanim uzerinde, sonra plan uzerinde kosturulur (model)
import { readFileSync } from "node:fs";

const BUGUN = "2026-02-15";
const VARSAYILAN = { "makine.genel_ip": "evet", "nesne_deposu.sifreli": "hayir" }; // kurgu
// [kod, kural, kuralin okudugu alan (null: degere bakmaz)]
const POLITIKA = [
  ["P1", (t, a) => t !== "nesne_deposu" || a.sifreli === "evet", "sifreli"],
  ["P2", (t, a) => t !== "makine" || a.genel_ip === "hayir", "genel_ip"],
  ["P3", (t, a) => t !== "veri_deposu" || Number(a.yedek) >= 7, "yedek"],
  ["P4", (t, a) => t !== "kuyruk" || Number(a.saklama) <= 168, "saklama"],
  ["P5", (t, a) => a.sahip !== undefined, null],
  ["P6", (t, a) => t !== "ag" || a.blok.startsWith("10."), "blok"],
  ["P7", (t, a) => t !== "makine" || a.genel_adres.startsWith("10."), "genel_adres"],
];

const DEGISKEN = {}, BLOK = [];
let c = null;
for (const s of readFileSync("kayit.tanim", "utf8").split("\n")) {
  const d = /^degisken (\w+) = (.+)$/.exec(s), h = /^kaynak ([a-z_]+)\/([a-z0-9-]+):$/.exec(s);
  const a = /^\s+(\w+)\s*=\s*(.+)$/.exec(s);
  if (d) DEGISKEN[d[1]] = d[2];
  else if (h) BLOK.push((c = { tur: h[1], ad: h[2], alan: {} }));
  else if (a && c) c.alan[a[1]] = a[2].trim();
}

// plan: kosul degerlendirilir, yineleme acilir, degisken ve saglayici varsayilani cozulur;
// "@atanacak" cozulmez, cunku degeri uygulama aninda atanir
const PLAN = [];
for (const b of BLOK) {
  const [k, v] = (b.alan.kosul ?? "=").split("=");
  if (b.alan.kosul && DEGISKEN[k] !== v) continue;
  for (const oge of b.alan.yinele ? b.alan.yinele.split(",") : [null]) {
    const alan = {};
    for (const [ad, deger] of Object.entries(b.alan)) {
      if (["yinele", "kosul", "muafiyet"].includes(ad)) continue;
      alan[ad] = deger === "@varsayilan" ? VARSAYILAN[`${b.tur}.${ad}`]
        : deger === "$yinele" ? oge
          : deger.startsWith("$") ? DEGISKEN[deger.slice(1)] : deger;
    }
    PLAN.push({ tur: b.tur, blok: b.ad, ad: oge ? `${b.ad}-${oge}` : b.ad, alan,
      muafiyet: b.alan.muafiyet });
  }
}

const cozulmemis = (v) => v !== undefined && /^[$@]/.test(v);
const muafMi = (n, kod) => {
  const [p, tarih] = (n.muafiyet ?? ":").split(":");
  return (p === "*" || p === kod) && tarih >= BUGUN;
};
function tara(nesneler) {
  const bulgu = [];
  let kararsiz = 0;
  for (const n of nesneler) for (const [kod, kural, alan] of POLITIKA) {
    if (alan && cozulmemis(n.alan[alan])) { kararsiz += 1; continue; }
    if (!kural(n.tur, n.alan)) bulgu.push({ ad: n.ad, blok: n.blok, kod, muaf: muafMi(n, kod) });
  }
  return { bulgu, kararsiz };
}

const tanimNesnesi = BLOK.map((b) => ({ tur: b.tur, ad: b.ad, blok: b.ad, alan: b.alan,
  muafiyet: b.alan.muafiyet }));
const T = tara(tanimNesnesi), P = tara(PLAN);
const esit = (x, y) => x.blok === y.blok && x.kod === y.kod;
const yakalanan = P.bulgu.filter((p) => T.bulgu.some((t) => esit(t, p)));
const yanlis = T.bulgu.filter((t) => !P.bulgu.some((p) => esit(t, p)));
const SURE = new Set(BLOK.map((b) => b.tur)).size * 4 + PLAN.length; // AD12: kurgu saniye

console.log(`${"tarama".padEnd(9)}${"gordugu deger".padEnd(15)}${"bulgu".padStart(6)}` +
  `${"yakalanan".padStart(11)}${"kacan".padStart(7)}${"yanlis alarm".padStart(14)}` +
  `${"muaf".padStart(6)}${"raporlanan".padStart(12)}${"kararsiz".padStart(10)}${"hazir".padStart(8)}`);
for (const [ad, deger, S, yak, yan, sure] of [
  ["tanim", "yazili", T, yakalanan.length, yanlis.length, 0],
  ["plan", "cozulmus", P, P.bulgu.length, 0, SURE]]) {
  const muaf = S.bulgu.filter((b) => b.muaf).length;
  console.log(`${ad.padEnd(9)}${deger.padEnd(15)}${String(S.bulgu.length).padStart(6)}` +
    `${`${yak}/${P.bulgu.length}`.padStart(11)}${String(P.bulgu.length - yak).padStart(7)}` +
    `${String(yan).padStart(14)}${String(muaf).padStart(6)}` +
    `${String(S.bulgu.length - muaf).padStart(12)}${String(S.kararsiz).padStart(10)}` +
    `${`${sure} sn`.padStart(8)}`);
}

console.log(`\nyalniz planin gordugu ihlaller:`);
for (const p of P.bulgu.filter((p) => !T.bulgu.some((t) => esit(t, p)))) {
  const alan = POLITIKA.find(([k]) => k === p.kod)[2];
  console.log(`  ${p.kod}  ${p.ad.padEnd(16)}${alan.padEnd(12)}tanimda ` +
    `"${BLOK.find((b) => b.ad === p.blok).alan[alan]}", planda "${PLAN.find((n) => n.ad === p.ad).alan[alan]}"`);
}

const M = BLOK.filter((b) => b.alan.muafiyet).map((b) => ({ ad: `${b.tur}/${b.ad}`,
  kayit: b.alan.muafiyet, yururlukte: b.alan.muafiyet.split(":")[1] >= BUGUN }));
console.log(`\n${"muafiyet".padEnd(28)}${"kayit".padEnd(16)}${"durum".padEnd(14)}` +
  `${"kapattigi politika".padStart(19)}${"dusurdugu ihlal".padStart(17)}`);
for (const m of M) {
  const d = P.bulgu.filter((b) => b.muaf && `${PLAN.find((n) => n.ad === b.ad).tur}/${b.blok}` === m.ad);
  const kapsam = m.yururlukte ? (m.kayit.startsWith("*") ? POLITIKA.length : 1) : 0;
  console.log(`${m.ad.padEnd(28)}${m.kayit.padEnd(16)}` +
    `${(m.yururlukte ? "yururlukte" : "suresi dolmus").padEnd(14)}` +
    `${String(kapsam).padStart(19)}${String(d.length).padStart(17)}`);
}
console.log(`\ntanim taramasinin yanlis alarmi: ` +
  yanlis.map((y) => `${y.kod} ${y.ad}`).join(", ") + ` (kosulu yanlis, plana hic girmiyor); ` +
  `her iki taramanin da karar veremedigi politika P7 — genel_adres uygulama aninda atanir`);
tarama   gordugu deger   bulgu  yakalanan  kacan  yanlis alarm  muaf  raporlanan  kararsiz   hazir
tanim    yazili              7       7/10      3             2     1           6         7    0 sn
plan     cozulmus           10      10/10      0             0     2           8         5   30 sn

yalniz planin gordugu ihlaller:
  P2  arsivci         genel_ip    tanimda "@varsayilan", planda "evet"
  P3  olcum-deposu    yedek       tanimda "$yedek", planda "3"
  P1  olcum-arsiv     sifreli     tanimda "@varsayilan", planda "hayir"

muafiyet                    kayit           durum          kapattigi politika  dusurdugu ihlal
makine/gecit                P2:2026-03-31   yururlukte                      1                1
veri_deposu/olcum-deposu    *:2026-06-30    yururlukte                      7                1
nesne_deposu/olcum-arsiv    P1:2025-11-30   suresi dolmus                   0                0

tanim taramasinin yanlis alarmi: P2 deneme, P4 deneme-kuyrugu (kosulu yanlis, plana hic girmiyor); her iki taramanin da karar veremedigi politika P7 — genel_adres uygulama aninda atanir

Kimin Ne Gördüğü

Plan taraması on ihlal bulur; tanım taraması bunların yedisini yakalar, üçünü kaçırır ve üstüne iki yanlış alarm verir. Kaçan üçünün ortak yanı çıktının ikinci bölümünde tek tek yazılıdır: hepsi hesaplanan değerdir. Arşivci makinesinin genel ağ alanı tanımda @varsayilan yazar, planda evet olur; veri deposunun yedeği tanımda $yedek yazar, planda 3 olur; arşivin şifreleme alanı tanımda @varsayilan yazar, planda hayir olur. Üçünde de kayıt metni ihlali saklamaz, yalnız göstermez — değer kaydın başka bir yerinde ya da sağlayıcıdadır.

İki yanlış alarmın nedeni de aynı asimetrinin öteki ucudur: koşulu tutmayan iki blok plana hiç girmez, ama tanım metninde ihlalli değerleriyle dururlar. Tanım taraması bunları raporlar ve raporlanan altı bulgunun ikisi, yani üçte biri, hiç yaratılmayacak kaynaklara aittir.

İki taramayı birlikte koşturmak da bedelsiz değildir. Tanım raporunun altı satırından dördü ile plan raporunun sekiz satırından altısı aynı dört kusuru anlatır; ekip aynı ihlali iki ayrı raporda görür ve hangisinin kapatıldığını izlemek için üçüncü bir kayıt tutar. Kapıya yalnız birini koymak zorunda olan bir hat içinse soru “hangisi daha doğru” değil, hangi hata biçiminin daha pahalı olduğudur: yanlış alarm insan zamanı harcar ve sonunda kuralın kapatılmasıyla biter, kaçan ihlal ise üretime iner.

Bir üçüncü fark sayıda saklıdır. Tanım taraması yedi bulgu üretir ama bunların beşi gerçek ihlaldir; o beş bulgu planın yedi ihlalini kapsar, çünkü yinelemeli tek blok üç örneğe açılır. Aynı kusur tanımda bir kez, planda üç kez raporlanır. Düzeltme her iki durumda da tek satırdadır; fark raporun uzunluğunda ve sayının nasıl okunacağındadır.

Erkenlik ile Doğruluk

Tabloda son iki sütun bu dersin değiş tokuşudur. Tanım taraması sıfır saniyede hazırdır: tek dosyayı okur, sağlayıcıya bağlanmaz, kayıt her değiştiğinde koşabilir. Plan taraması otuz saniye bekler — beş kaynak türü için birer sağlayıcı çağrısı, sonra on plan örneği için hesap — ve ancak plan üretilebilen bir ortamda koşar; yetkisi olmayan bir katkı hattında hiç koşamaz.

Pratikte ikisinin yeri de farklıdır. Tanım taraması kaydın yazıldığı yerde, katkı daha birleşmeden koşabilir; yanlış alarmı orada en ucuzdur, çünkü bloğun koşullu olduğunu bilen kişi raporu okuyan kişidir. Plan taraması ise planın üretildiği kapıda durur ve orada verdiği karar bağlayıcıdır.

Karşılığında aldığı şey doğruluktur: kaçan sıfır, yanlış alarm sıfır. Buradan çıkan sonuç “hangisi daha iyi” değildir, ikisinin farklı hata biçimleri olduğudur. Tanım taraması yanlış alarm üretir ve hesaplanan değeri kaçırır; plan taraması geç gelir ve bir sağlayıcı bağlantısına bağımlıdır. Kararsız sütunu ikisinin ortak sınırını gösterir: tanım yedi, plan beş kuralda karar veremez, ve ikisinin de karar veremediği P7’nin nedeni aynıdır — genel adres uygulama anında atanır, iki katmanda da yazılı değildir.

Muafiyetin Açtığı Yol

Üç muafiyet kaydı var ve üçü üç ayrı davranış gösteriyor. Geçidin muafiyeti bir politikaya bağlıdır ve yürürlüktedir: tek bir ihlali rapordan düşürür, geçidin öteki altı politikası açık kalır. Veri deposunun muafiyeti jokerdir: bugün yine tek bir ihlali düşürür, ama kapattığı politika sayısı yedidir — o kaynağa sonradan eklenecek her ihlal de sessizce geçer, muafiyet süresi dolana dek. Arşivin muafiyetinin süresi dolmuştur ve düşürdüğü ihlal sıfırdır; şifrelemenin kapalı olması rapora geri dönmüştür.

Muafiyetin kendisi de bir kayıttır ve bakımı kimsede değildir. Üç kayıttan biri süresi dolmuş hâlde durmaktadır; kimse silmemiştir. Süresi dolmuş muafiyet görünürdür — ihlali rapora geri getirir ve kendini duyurur. Tehlikeli olan öteki uçtur: süresi dolmamış ve unutulmuş bir muafiyet sessizdir, raporu kısaltır ve ihlali yerinde bırakır. Muafiyet kaydını denetleyen tek şey tarihtir; joker kaydın kapsamını denetleyen bir kural yoktur.

Sayı olarak: plan taraması on ihlal buldu, ikisi muafiyetle düştü, sekizi raporlandı. Muafiyetin açtığı yol iki ihlal genişliğindedir ve bunun biri joker kaydın açtığı yoldur. Muafiyetin bedeli düşürdüğü ihlal sayısıyla değil, kapattığı politika sayısıyla ölçülür: bir politikaya bağlı muafiyet bir kapı açar, joker muafiyet yedi kapı birden.

Özet

  • Aynı yedi kurallık politika kümesi kurgu ölçüm ağı kaydının iki katmanında koşturuldu: yazılı tanım metni ve çözülmüş plan.
  • Plan taraması 10 ihlal buldu; tanım taraması 7’sini yakaladı, 3’ünü kaçırdı ve 2 yanlış alarm verdi — raporladığı 6 bulgunun 2’si hiç yaratılmayacak kaynaklara aitti.
  • Kaçan üç ihlalin üçü de hesaplanan değerdir: ikisi sağlayıcı varsayılanı (@varsayilanevet ve hayir), biri değişken ($yedek3); tanım metni bunları göstermez.
  • Erkenlik ile doğruluk takas edilir: tanım taraması 0 saniyede ve sağlayıcıya bağlanmadan hazırdır, plan taraması 30 saniye ve beş sağlayıcı çağrısı ister; ikisinin de karar veremediği P7’nin değeri uygulama anında atanır (tanımda 7, planda 5 kural kararsız kalır).
  • Üç muafiyet kaydının ikisi yürürlüktedir ve 10 ihlalin 2’sini rapordan düşürür; joker muafiyet tek başına 7 politikayı birden kapatırken politikaya bağlı muafiyet 1 politikayı kapatır, süresi dolmuş muafiyet ise ihlali rapora geri getirir.

Sonraki Adım

İki tarama da kaydı okudu — biri yazıldığı gibi, öteki çözüldüğü gibi. İkisinin de göremediği şey kaynağın koştuğu hâlidir: P7 kararsız kaldı çünkü genel adres uygulama anında atanır, ve politika kümesinin hiçbir kuralı “bu makine gerçekten açılıyor mu, kuyruğa yazılan ileti veri deposuna ulaşıyor mu” diye sormaz. Sonraki ders bu soruyu üç seviyede sorar: altyapı tanımına bakan birim doğrulaması, iki kaynağın arasındaki anlaşmayı sınayan sözleşme doğrulaması ve gerçek kaynak yaratan uçtan uca doğrulama. Aynı kusur kümesinde üçünün tuttuğu, süresi ve maliyeti sayılır — ve üçünün birden kaçırdığı ortak boşluk adıyla yazılır.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat