discover

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 14, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package discover, sanallaştırma platformundan makine keşfi.

⚠️ KAYNAK ARAYÜZ ARKASINDA ve bu ilk günden böyle. Bugün tek uygulaması Proxmox; vSphere aynı arayüzü dolduracak. Arayüzü sonradan çıkarmak, Proxmox'a özel varsayımların keşif mantığının içine dağılmasından SONRA olurdu — ve o noktada ikinci kaynağı eklemek, birinciyi yeniden yazmak demek olurdu.

⚠️ KEŞİF ERİŞİM VERMEZ, HEDEF VE ROL YARATIR. Bir makinenin postern'de hedef olması, kimsenin oraya girebildiği anlamına gelmiyor: erişim yalnızca rolden geliyor ve rolü insanlara bağlamak ayrı, bilinçli bir adım. Keşif o adımı yapmıyor.

Index

Constants

View Source
const (
	KindProxmox = "proxmox"
	KindVSphere = "vsphere"
)

Kaynak türleri.

View Source
const (
	// MinInterval: bundan sık koşu hipervizörün API'sini ve her makinenin
	// sshd'sini boşuna yoruyor; envanter o hızda değişmiyor.
	MinInterval = 5 * time.Minute
	MaxInterval = 7 * 24 * time.Hour
)
View Source
const UnknownRole = "unknown"

* UnknownRole, rol etiketi olmayan makinelerin düştüğü rol. * * ⚠️ model.UnknownGroup ile AYNI KELİME ve bu kasıtlı: operatör aynı * anlamı iki farklı adla öğrenmek zorunda kalmasın. Orada "kaynak * cevap verdi ama grup söylemedi", burada "makine var ama rolü * söylenmemiş" — ikisi de "bilmiyoruz, ama sakladık" demek.

Variables

View Source
var ErrRunning = errors.New("discover: a run of this source is already in progress")

ErrRunning: kaynağın bir koşusu zaten sürüyor.

Functions

func Fingerprint added in v1.2.0

func Fingerprint(authorized string) string

Fingerprint, authorized_keys biçimindeki anahtarın SHA256 parmak izi; okunamıyorsa boş.

func RoleFromTags

func RoleFromTags(tags []string, key string) (role string, tagged bool)

* RoleFromTags, etiketlerden rol adını çıkarır. * * ⚠️ ANAHTAR ETİKETİN İÇİNDE, ayrı bir alan değil. Proxmox etiketleri * anahtar/değer çifti DEĞİL, düz dizeler ("prod", "role=ops"). Bu * yüzden operatörden bir "etiket anahtarı" istiyoruz ve onu etiketin * içinde arıyoruz: `role=ops` ya da `role:ops`. * * İki ayraç da kabul ediliyor çünkü ikisi de yaygın ve hangisinin * kullanıldığını keşif sırasında öğrenmek, kurulumu yeniden * etiketlemekten ucuz. * * ⚠️ ANAHTARSIZ MAKİNE HATA DEĞİL. Etiketi olmayan ya da anahtarı * taşımayan makine `unknown` rolüne düşüyor — kaynağın hiçbir grup * söylemediği kullanıcının düştüğü yerin aynısı (model.UnknownGroup). * Sebebi aynı: "bilmiyorum" ile "hiçbiri" ayrı şeyler ve bilmediğimiz * makineyi sessizce dışarıda bırakmak, onu envanterden düşürürdü.

* ⚠️ EŞLEŞME ÖN EKLE, "İLK AYIRICIDA BÖL" DEĞİL. * * Alt çizgi hem anahtarın hem değerin İÇİNDE geçebiliyor: * "role_name_os-admins" etiketi, anahtar "role_name" iken değer * "os-admins" demek. İlk ayırıcıda bölen bir uygulama burada anahtarı * "role" sanır, eşleşmez, ve makine sessizce unknown'a düşer — yani * alt çizgiyi desteklemek TEK BAŞINA yetmiyor. * * Anahtar bilindiği için doğru olan onu ön ek olarak aramak; geriye * kalan her şey değerdir ("role_web_prod" + anahtar "role" = * "web_prod").

func SortOutcomes

func SortOutcomes(out []Outcome)

SortOutcomes, raporu okunur bir sıraya koyar: önce atlananlar (asıl bakılacak olan onlar), sonra rol, sonra ad.

func ValidRoleName

func ValidRoleName(name string) error

* ValidRoleName, etiketten gelen değerin rol adı olarak kullanılabilir * olduğu. * * ⚠️ ETİKET GÜVENİLMEYEN GİRDİ. Hipervizöre makine ekleyebilen herkes * etiket yazabiliyor ve o değer burada bir ROL ADINA dönüşüyor — * yani erişim modelinin bir parçasına. Boşluk, virgül ya da yol * ayracı taşıyan bir ad, sonradan liste ayrıştıran her yerde * belirsizlik üretir.

func ValidTargetName added in v1.2.0

func ValidTargetName(name string) error

* ValidTargetName, platformun verdiği adın hedef adı olabilmesi. * * ⚠️ AD GÜVENİLMEYEN GİRDİ ve SSH kullanıcı adının parçası oluyor * (`kişi:hedef`). vCenter'da "Web Server 01" ya da iki nokta taşıyan bir * ad yazılabiliyor; öyle bir hedef ya bağlanılamaz ya da ayrıştırıcıya * başka bir şey söyler. Rol adıyla aynı dar küme, biraz daha uzun.

func ValidateSource added in v1.2.0

func ValidateSource(src store.DiscoverySource, secret string, creating bool) error

* ValidateSource, kaynağı yazmadan önce denetler. creating=false iken * boş sır "değişmedi" demek. * * ⚠️ HEM CA HEM "DOĞRULAMA" OLMAZ. İkisi birden işaretliyse hangisinin * geçerli olduğu kodun sırasına kalırdı; operatör sertifikayı yapıştırıp * doğrulamanın açık olduğunu sanarken kapalı olabilirdi.

Types

type Machine

type Machine struct {
	// Name, platformdaki adı. Hedef adı olarak kullanılıyor.
	Name string

	/*
	 * Host, SSH için kullanılacak adres.
	 *
	 * Boş olabilir: Proxmox'ta adresi öğrenmek konuk aracısına
	 * (guest agent) bağlı ve o her makinede kurulu değil. Boşken
	 * makinenin ADI adres olarak deneniyor — kurumların çoğunda
	 * makine adı zaten çözülüyor. Çözülmezse makine ATLANIYOR ve
	 * sebebi raporda yazıyor; uydurma bir adres yazmak, bir gün
	 * başka bir makineye açılan bir hedef bırakırdı.
	 */
	Host string

	// Tags, platformdaki etiketler. Rol bunlardan çıkarılıyor.
	Tags []string

	// Running, makine çalışıyor mu. Kapalı makinenin host anahtarı
	// taranamaz; rapor bunu ayrı bir sebep olarak söylüyor.
	Running bool

	// Ref, platformdaki kimliği (teşhis için: "qemu/101").
	Ref string

	/*
	 * Key, makinenin platformdaki KARARLI kimliği ("qemu/101",
	 * "vsphere/vm-42"). Paneldeki keşif satırı bununla anahtarlanıyor.
	 *
	 * ⚠️ Ref DEĞİL. Proxmox'ta Ref düğümü de taşıyor ("qemu/101@pve2") ve
	 * kümede canlı taşınan bir VM'in düğümü değişiyor: Ref'le
	 * anahtarlasaydık her taşımada makine "yeni" görünür, eskisi "kayıp"
	 * düşerdi. VMID küme içinde tekil; ad da değil, kimlik o — adla
	 * anahtarlamak, VM'i yeniden adlandıranın yeni bir hedef yaratıp
	 * eskisini öksüz bırakması demek.
	 */
	Key string
}

Machine, bir kaynağın bildirdiği tek bir makine.

type MachineRef added in v1.2.0

type MachineRef struct {
	SourceID string `json:"source_id"`
	Ref      string `json:"ref"`
}

MachineRef, paneldeki bir satırın kimliği.

type Opener added in v1.2.0

type Opener func(store.DiscoverySource, string) (Source, error)

Opener, kayıtlı kaynağı ve açılmış sırrını bir Source'a çevirir.

type Outcome

type Outcome struct {
	Machine Machine
	Role    string
	// Tagged: rol etiketten mi geldi (yoksa unknown'a mı düştü).
	Tagged bool

	// Skipped doluysa makine için hiçbir şey yazılmadı ve sebebi bu.
	Skipped string

	/*
	 * KeyUnchecked doluysa makine ZATEN KAYITLIYDI ama host anahtarı bu
	 * turda doğrulanamadı (ağ). Rol bağı yine de yenilendi.
	 *
	 * ⚠️ SESSİZ GEÇMİYOR: "kontrol ettim ve aynıydı" ile "kontrol
	 * edemedim" farklı şeyler, ve ikincisini birincisi gibi göstermek
	 * değişmiş bir makineyi değişmemiş sanmaya yol açar.
	 */
	KeyUnchecked string

	// Aşağıdakiler yalnızca uygulama (apply) turunda dolar.
	CreatedRole   bool
	CreatedTarget bool
	Granted       bool
	// Existing: hedef zaten vardı ve DOKUNULMADI.
	Existing bool
}

Outcome, tek bir makine için keşfin sonucu.

type Planner

type Planner struct {
	DB *store.Store
	// TagKey, rol adını taşıyan etiket anahtarı ("role").
	TagKey string
	// Port, hedeflerin SSH portu.
	Port int
	// Actor, denetim kaydına yazılacak kim.
	Actor string
}

Planner, keşfi postern'e uygular.

func (Planner) Run

func (p Planner) Run(ctx context.Context, machines []Machine, apply bool) ([]Outcome, error)

* Run, makineleri işler. * * apply=false ise HİÇBİR yazma yapılmıyor; dönen Outcome listesi yine * de "ne olurdu"yu tam olarak anlatıyor — host anahtarı taraması dahil, * çünkü taramanın başarısız olması bir makinenin atlanmasının en sık * sebebi ve onu önizlemede göstermemek, önizlemeyi yalancı yapardı.

type Probe added in v1.2.0

type Probe struct {
	Machines    int `json:"machines"`
	Running     int `json:"running"`
	WithAddress int `json:"with_address"`
	// Matching, ad kalıbına uyan makine sayısı (kalıp boşsa hepsi).
	Matching int `json:"matching"`
	// Tagged, etiket anahtarını taşıyan makine sayısı; Roles onlardan
	// çıkan rol adlarının örneği, Tags görülen etiketlerin örneği.
	Tagged int      `json:"tagged"`
	Roles  []string `json:"roles"`
	Tags   []string `json:"tags"`
	TookMS int64    `json:"took_ms"`
}

Probe, "Test connection"ın cevabı: platformun ne bildirdiği.

type Proxmox

type Proxmox struct {
	// contains filtered or unexported fields
}

Proxmox, ProxmoxConfig ile konuşan Source.

func NewProxmox

func NewProxmox(cfg ProxmoxConfig) (*Proxmox, error)

NewProxmox, yapılandırmayı doğrular ve istemciyi kurar.

func (*Proxmox) Machines

func (p *Proxmox) Machines(ctx context.Context) ([]Machine, error)

Machines, kümedeki sanal makineleri ve konteynerleri döner.

func (*Proxmox) Name

func (p *Proxmox) Name() string

Name, Source arayüzü.

type ProxmoxConfig

type ProxmoxConfig struct {
	// BaseURL, "https://pve.example:8006" biçiminde.
	BaseURL string

	/*
	 * TokenID ve TokenSecret, API jetonu ("user@pam!keşif").
	 *
	 * ⚠️ PAROLA/TICKET YOLU BİLEREK YOK. Jeton kapsamı daraltılabiliyor
	 * ve iptali tek tıklık; kullanıcı parolası ise hipervizörün tamamına
	 * açılan bir anahtar. postern'in kendi kapısında verdiği kararın
	 * aynısı: makine işi için makine kimliği.
	 */
	TokenID     string
	TokenSecret string

	// CAFile, hipervizörün sertifikasını doğrulayacak kök. Boşsa
	// sistemin kök deposu.
	CAFile string

	// CAPEM, aynı kök PEM metni olarak: panelde kaydedilen kaynak dosya
	// yolu değil metin taşıyor. CAFile doluysa o geçerli.
	CAPEM string

	/*
	 * Insecure, TLS doğrulamasını KAPATIR.
	 *
	 * ⚠️ VARSAYILAN DEĞİL VE OLMAYACAK. Proxmox kurulumlarının çoğu
	 * kendi imzaladığı sertifikayla geliyor, dolayısıyla bunu tamamen
	 * yasaklamak özelliği kullanılamaz yapardı. Ama açık olduğunda
	 * araya giren biri hipervizörün cevabını — yani hangi makinenin
	 * hangi role gideceğini — yazabilir. Bu yüzden açan kişi bunu
	 * komut satırında yazmak zorunda ve denetim kaydına düşüyor.
	 * Doğru yol CAFile.
	 */
	Insecure bool

	// Node boşsa küme genelinde arıyor.
	Node string

	Timeout time.Duration
}

ProxmoxConfig, Proxmox'a bağlanmak için gerekenler.

type RegisterRequest added in v1.2.0

type RegisterRequest struct {
	Machines []MachineRef
	// Roles, her makinenin bağlanacağı var olan roller.
	Roles []string
	// TagRoles: makinenin etiketinin söylediği role de bağla (yoksa aç).
	TagRoles bool
	Labels   map[string]string
	Actor    string
}

RegisterRequest, seçili makineleri hedef yapma isteği.

type Registered added in v1.2.0

type Registered struct {
	SourceID     string   `json:"source_id"`
	Ref          string   `json:"ref"`
	Name         string   `json:"name"`
	Target       string   `json:"target,omitempty"`
	Roles        []string `json:"roles,omitempty"`
	CreatedRoles []string `json:"created_roles,omitempty"`
	Error        string   `json:"error,omitempty"`
}

Registered, tek makinenin kayıt sonucu.

type Service added in v1.2.0

type Service struct {
	// contains filtered or unexported fields
}

* Service, panelden kaydedilen keşif kaynaklarını koşturur: zamanlayıcıyla * ya da elle, her koşu bir satır bırakarak. * * ⚠️ KOŞU HEDEF YAZMIYOR, ROL BAĞLAMIYOR. CLI'daki `--apply` bunu yapıyor, * çünkü orada önizlemeyi bir insan okuyup onaylıyor. Zamanlayıcının okuru * yok: Proxmox'ta `role_prod` etiketiyle VM açabilen biri, o role bağlı * insanların girebileceği bir makine yaratmış olurdu — sanallaştırma * platformu üzerinden yetki yükseltme. Koşu bulduğunu discovered_machines'e * yazıyor; makine hedef ancak bir yönetici Register dediğinde oluyor. * Otomasyon envanteri büyütebilir, insanların erişebildiği makineleri * genişletemez.

func NewService added in v1.2.0

func NewService(db *store.Store, logger *slog.Logger, open Opener) *Service

NewService kurar; open nil ise gerçek Proxmox/vSphere istemcileri (OpenSource). Host anahtarı taraması her zaman gerçek.

func (*Service) Loop added in v1.2.0

func (s *Service) Loop(ctx context.Context)

Loop, zamanı gelen kaynakları dakikada bir koşturur; ctx bitene kadar.

func (*Service) Probe added in v1.2.0

func (s *Service) Probe(ctx context.Context, src store.DiscoverySource, secret string) (Probe, error)

* Probe, formdaki değerlerle kaynağa bağlanıp makineleri sayar. * * ⚠️ HİÇBİR ŞEY YAZMIYOR — ne kaynak, ne makine satırı, ne koşu. Amaç * kaydetmeden önce adresin, sırrın ve ETİKET ANAHTARININ doğru olduğunu * görmek. CLI'da ölçülen arıza burada da geçerli: yanlış anahtar hata * vermiyor, her makineyi sessizce etiketsiz bırakıyor. "0 makine etiketli, * görülen etiketler şunlar" cümlesi bunu kaydetmeden önce söylüyor.

func (*Service) Register added in v1.2.0

func (s *Service) Register(ctx context.Context, req RegisterRequest) ([]Registered, error)

* Register, seçili makineleri hedef yapar, rollere bağlar ve etiketler. * * ⚠️ ANAHTAR YENİDEN TARANMIYOR, KOŞUNUN OKUDUĞU SABİTLENİYOR. Yönetici * özet ekranında o parmak izini gördü ve onu onayladı; tıklama anında * başka bir anahtar okuyup onu sabitlemek, onaylanmayanı yazmak olurdu. * Bayat bir anahtar en fazla bağlantının reddedilmesine yol açıyor — * sabitlenen anahtarı proxy her bağlantıda doğruluyor. * * Makine başına hatalar sonuca yazılıyor ve sıradakine geçiliyor; yalnızca * veritabanı ya da denetim defteri yazılamazsa parti duruyor — kaydı * düşmeyen bir erişim vermeye devam etmemek için.

func (*Service) Run added in v1.2.0

func (s *Service) Run(ctx context.Context, sourceID, trigger, actor string) (store.DiscoveryRun, error)

Run, kaynağı bu goroutine'de koşturur ve koşunun satırını döner.

func (*Service) RunNow added in v1.2.0

func (s *Service) RunNow(ctx context.Context, sourceID, actor string) error

* RunNow, kaynağı arka planda koşturur (panelin "Run now" düğmesi). * * ⚠️ İSTEĞİN BAĞLAMINDA DEĞİL. Yüz makinenin anahtarını taramak bir * dakikayı geçebiliyor; istek bağlamına bağlı bir koşu, sekmesini kapatan * yöneticiyle birlikte yarıda kesilir ve yarım bir rapor bırakırdı.

func (*Service) Running added in v1.2.0

func (s *Service) Running(id string) bool

Running, kaynağın bir koşusu bu süreçte sürüyor mu.

func (*Service) SetIgnored added in v1.2.0

func (s *Service) SetIgnored(ctx context.Context, keys []MachineRef, ignored bool, actor string) (int, error)

SetIgnored, makineleri yok sayar ya da yok saymayı kaldırır; kaç satırın değiştiğini döner.

func (*Service) Tick added in v1.2.0

func (s *Service) Tick(ctx context.Context)

Tick, zamanı gelmiş etkin kaynakları sırayla koşturur.

type Source

type Source interface {
	// Name, raporda ve denetim kaydında görünen ad ("proxmox").
	Name() string
	// Machines, platformdaki makineleri döner.
	Machines(ctx context.Context) ([]Machine, error)
}

Source, makineleri sayabilen bir platform.

func OpenSource added in v1.2.0

func OpenSource(src store.DiscoverySource, secret string) (Source, error)

OpenSource, kayıtlı kaynağı ve açılmış sırrını bir Source'a çevirir.

type VSphere

type VSphere struct {
	// contains filtered or unexported fields
}

VSphere, VSphereConfig ile konuşan Source.

func NewVSphere

func NewVSphere(cfg VSphereConfig) (*VSphere, error)

NewVSphere, yapılandırmayı doğrular ve istemciyi kurar.

func (*VSphere) Close

func (v *VSphere) Close(ctx context.Context)

Close, vCenter oturumunu kapatır.

func (*VSphere) Machines

func (v *VSphere) Machines(ctx context.Context) ([]Machine, error)

Machines, vCenter'daki sanal makineleri döner.

func (*VSphere) Name

func (v *VSphere) Name() string

Name, Source arayüzü.

type VSphereConfig

type VSphereConfig struct {
	// BaseURL, "https://vcenter.example" biçiminde.
	BaseURL string

	/*
	 * Username ve Password.
	 *
	 * ⚠️ PROXMOX'TAN FARKLI OLARAK JETON YOK ve bu bir tercih değil:
	 * vCenter'ın API jetonu diye ayrı bir kavramı yok, oturum kullanıcı
	 * kimliğiyle açılıyor. Karşılığında kullanılacak hesabın
	 * YALNIZCA OKUMA yetkisi olmalı — bu koddaki hiçbir çağrı
	 * değiştirmiyor, ama yetkiyi daraltmak koda değil operatöre bağlı.
	 */
	Username string
	Password string

	CAFile string

	// CAPEM, aynı kök PEM metni olarak (bkz. ProxmoxConfig.CAPEM).
	CAPEM string
	// Insecure, TLS doğrulamasını kapatır. Gerekçesi ProxmoxConfig'te.
	Insecure bool

	Timeout time.Duration
}

VSphereConfig, vCenter'a bağlanmak için gerekenler.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL