Yedek Depolama

1.7k görüntülenme Markdown

Yedeklerin gönderileceği depolama hedeflerini kuran, sınayan ve kaldıran dokuz uç.

Genel Bakış

Depolama hedefi, yedeklerin nereye gönderileceğini tanımlar. Dokuz uç bu hedefleri kurar, sınar ve kaldırır. Yedeklerin ne zaman alınacağı ayrı bir konudur.

Sağlayıcılar iki gruba ayrılır. Sunucu tipi olanlar adres ve şifreyle kurulur. Bulut tipi olanlar ise kullanıcının tarayıcıda onay vermesini bekler. O yolda üç adım vardır: onay adresi al, kullanıcıyı gönder, dönen belirteçle hedefi oluştur.

Bir hedef kaydedilmeden önce gerçekten bağlanılır. Yanlış şifre yedek gecesinde değil, hedefi yazdığınız anda ortaya çıkar.

Referans

Sağlayıcıları Listeleme

get/api/v1/admin/settings/backup/storage/providers
Settings/GetBackupStorageProviders admin

Yedeklerin gönderilebileceği kurulu depolama sağlayıcılarını döndürür.

Dönen alanlar data[] — 5
keystringSağlayıcının anahtarı. Hedef oluştururken bu kullanılır.
namestringSağlayıcının adı.
descriptionstringNe yaptığı.
oauthboolKullanıcı onayı gerektirip gerektirmediği. Doğruysa yalnız ayar yazmak yetmez.
fieldsarraySağlayıcının istediği ayarların tanımı.
Hatalar 1
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl 'https://panel.ornek.com/api/v1/admin/settings/backup/storage/providers' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.ornek.com/api/v1/admin/settings/backup/storage/providers', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/storage/providers');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Sunucu-tipi saglayici ayarla kurulur; bulut saglayici KULLANICI ONAYI ister.
$providers = Api::Settings()->GetBackupStorageProviders()['data'];
$simple    = array_filter($providers, fn ($p) => ! $p['oauth']);

Bağlantıyı Sınama

post/api/v1/admin/settings/backup/storage/validate
Settings/ValidateBackupStorage admin

Bir yapılandırmayı kaydetmeden bağlantı sınamasından geçirir.

Gövde 3
typestringreqSınanacak sağlayıcı. Hedef kimliği vermezseniz zorunludur.
idintVar olan hedefin kimliği. Ayarları ondan alınır.
configobjectSağlayıcının ayarları. Gizli alanlar maskeyle korunur.
Dönen alanlar data — 2
validatedboolBağlantı kuruldu mu.
messagestringSonucun açıklaması.
Hatalar 3
unknown_provider422Sağlayıcı tanınmıyor.
module_not_loadable422Sağlayıcı yüklenemedi.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl -X POST 'https://panel.ornek.com/api/v1/admin/settings/backup/storage/validate' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"type":"FTP","config":{"host":"ftp.ornek.com","username":"backup","password":"gizli"}}'
const res = await fetch('https://panel.ornek.com/api/v1/admin/settings/backup/storage/validate', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    type: 'FTP',
    config: { host: 'ftp.example.com', username: 'backup', password: secret },
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/storage/validate');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'type'   => 'FTP',
        'config' => ['host' => 'ftp.example.com', 'username' => 'backup', 'password' => $secret],
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Sinama HICBIR SEY KAYDETMEZ: gecmesi hedefin olustugu anlamina gelmez.
$check = Api::Settings()->ValidateBackupStorage([
    'type'   => 'FTP',
    'config' => $config,
])['data'];

if ($check['validated']) Api::Settings()->CreateBackupStorage($payload);

Onay Adresi Alma

post/api/v1/admin/settings/backup/storage/oauth-url
Settings/GetBackupOauthUrl admin

Bulut sağlayıcılar için kullanıcının onay vereceği adresi üretir.

Gövde 3
typestringreqOnay isteyen sağlayıcı.
idintVar olan hedefin kimliği.
configobjectSağlayıcının ayarları.
Dönen alanlar data — 2
authorize_urlstringKullanıcının yönlendirileceği adres.
statestringİmzalı durum değeri. Dönüşte bunun eşleşmesi beklenir.
Hatalar 4
unknown_provider422Sağlayıcı tanınmıyor.
oauth_unsupported422Sağlayıcı onay akışı kullanmıyor.
oauth_url_failed422Adres üretilemedi.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl -X POST 'https://panel.ornek.com/api/v1/admin/settings/backup/storage/oauth-url' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"type":"GoogleDrive"}'
const res = await fetch('https://panel.ornek.com/api/v1/admin/settings/backup/storage/oauth-url', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ type: 'GoogleDrive' }),
});

const { data } = await res.json();
window.location.href = data.authorize_url;
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/storage/oauth-url');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['type' => 'GoogleDrive']),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Adres tek basina yetmez: kullanici onay verip donmeden hedef OLUSTURULAMAZ.
$url = Api::Settings()->GetBackupOauthUrl(['type' => 'GoogleDrive'])['data']['authorize_url'];

Bunny Alanlarını Getirme

post/api/v1/admin/settings/backup/storage/bunny-zones
Settings/GetBunnyZones admin

Verilen hesap anahtarına bağlı Bunny depolama alanlarını döndürür.

Gövde 2
account_api_keystringreqBunny hesap anahtarı. Maske gönderirseniz hedef kimliği de gerekir.
idintVar olan hedefin kimliği.
Dönen alanlar data — 1
zonesarrayHesaba bağlı depolama alanları.
Hatalar 3
api_key_required422Hesap anahtarı verilmedi.
fetch_zones_failed422Alan listesi alınamadı.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl -X POST 'https://panel.ornek.com/api/v1/admin/settings/backup/storage/bunny-zones' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"account_api_key":"'"$BUNNY_KEY"'"}'
const res = await fetch('https://panel.ornek.com/api/v1/admin/settings/backup/storage/bunny-zones', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ account_api_key: bunnyKey }),
});

const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/storage/bunny-zones');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['account_api_key' => $bunnyKey]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Kayitli hedefin anahtari maskeli doner; maskeyi geri gonderirken KIMLIGI de verin.
$zones = Api::Settings()->GetBunnyZones([
    'account_api_key' => '*****',
    'id'              => $storageId,
])['data']['zones'];

Hedefleri Listeleme

get/api/v1/admin/settings/backup/storage
Settings/GetBackupStorages admin

Tanımlı yedek depolama hedeflerini döndürür.

Sorgu 1
searchstringAda göre arar.
Dönen alanlar data[] — 6
idintHedefin kimliği.
namestringHedefin adı.
typestringSağlayıcı tipi.
statusstringHedefin durumu.
validated_atstring | nullBağlantının son sınandığı an. Boşsa hedef hiç sınanmamıştır.
created_atstring | nullOluşturulma anı.
Hatalar 1
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl 'https://panel.ornek.com/api/v1/admin/settings/backup/storage' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.ornek.com/api/v1/admin/settings/backup/storage', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/storage');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Son sinama ani ESKI olabilir: sifre o gunden beri degismis olabilir.
$targets = Api::Settings()->GetBackupStorages()['data'];
$stale   = array_filter($targets, fn ($t) => $t['validated_at'] === null);

Hedef Oluşturma

post/api/v1/admin/settings/backup/storage
Settings/CreateBackupStorage admin önce bağlanır

Yeni bir depolama hedefi kurar; kaydetmeden önce bağlanmayı dener.

Gövde 3
namestringreqHedefin adı. En çok 150 karakter.
typestringreqSağlayıcı anahtarı.
configobjectSağlayıcının ayarları. Bulut sağlayıcıda onay belirteci de gerekir. Gönderilmeyen onay kutusu kapalı kaydedilir: FTP'nin ssl (FTPS) alanı panel formunda açık gelir; bağlantının şifreli kalması için "ssl": 1 gönderin.
Dönen alanlar 201 — data
dataobjectOluşan hedef. Detay ucuyla aynı şekildedir ve gizli alanlar maskelenir.
Hatalar 5
name_required422Ad boş.
invalid_provider422Sağlayıcı geçersiz.
oauth_required422Bulut sağlayıcı için onay eksik.
storage_test_failed422Bağlantı kurulamadı.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl -X POST 'https://panel.ornek.com/api/v1/admin/settings/backup/storage' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"name":"Uzak FTP","type":"FTP","config":{"host":"ftp.ornek.com","username":"backup","password":"gizli","folder_path":"/backups"}}'
const res = await fetch('https://panel.ornek.com/api/v1/admin/settings/backup/storage', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Offsite FTP',
    type: 'FTP',
    config: {
      host: 'ftp.example.com',
      username: 'backup',
      password: secret,
      folder_path: '/backups',
    },
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/storage');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'name'   => 'Offsite FTP',
        'type'   => 'FTP',
        'config' => [
            'host'        => 'ftp.example.com',
            'username'    => 'backup',
            'password'    => $secret,
            'folder_path' => '/backups',
        ],
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Maske burada ISE YARAMAZ: korunacak eski deger yok, gercek sifreyi gonderin.
Api::Settings()->CreateBackupStorage([
    'name'   => 'Offsite FTP',
    'type'   => 'FTP',
    'config' => ['host' => $host, 'username' => $user, 'password' => $secret],
]);

Hedef Detayı

get/api/v1/admin/settings/backup/storage/{id}
Settings/GetBackupStorage admin

Tek bir hedefi ayarlarıyla birlikte döndürür.

Dönen alanlar data — 7
idintHedefin kimliği.
namestringHedefin adı.
typestringSağlayıcı tipi.
statusstringHedefin durumu.
configobjectSağlayıcının ayarları. Gizli alanlar maskelenmiş gelir.
validated_atstring | nullBağlantının son sınandığı an.
created_atstring | nullOluşturulma anı.
Hatalar 2
not_found404Hedef bulunamadı.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl 'https://panel.ornek.com/api/v1/admin/settings/backup/storage/12' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch(`https://panel.ornek.com/api/v1/admin/settings/backup/storage/${id}`, {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/storage/' . $id);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Okudugunuzu OLDUGU GIBI baska bir hedef olusturmak icin kullanmayin: sifre maskelidir.
$target = Api::Settings()->GetBackupStorage(['id' => $id])['data'];

Hedefi Güncelleme

patch/api/v1/admin/settings/backup/storage/{id}
Settings/UpdateBackupStorage admin

Hedefin adını ve ayarlarını değiştirir.

Gövde 2
namestringYeni ad.
configobjectSağlayıcının ayarları; nesne bütün olarak yazılır. Tüm alanları gönderin: eksik bıraktığınız metin alanı düşer, onay kutusu ve sayı alanları sıfıra döner. ***** şifreli alanın eski değerini korur.
Dönen alanlar data
dataobjectHedefin son hâli. Detay ucuyla aynı şekildedir ve gizli alanlar maskelenir.
Hatalar 5
not_found404Hedef bulunamadı.
name_required422Ad boş.
oauth_required422Bulut sağlayıcı için onay eksik.
storage_test_failed422Bağlantı kurulamadı.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl -X PATCH 'https://panel.ornek.com/api/v1/admin/settings/backup/storage/12' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"name":"Uzak FTP (AB)","config":{"folder_path":"/backups-eu","password":"*****"}}'
const res = await fetch(`https://panel.ornek.com/api/v1/admin/settings/backup/storage/${id}`, {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Offsite FTP (EU)',
    config: { folder_path: '/backups-eu', password: '*****' },
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/storage/' . $id);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'name'   => 'Offsite FTP (EU)',
        'config' => ['folder_path' => '/backups-eu', 'password' => '*****'],
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Yol degisirse baglanti YENIDEN sinanir; yeni klasor yoksa guncelleme reddedilir.
Api::Settings()->UpdateBackupStorage([
    'id'     => $id,
    'config' => ['folder_path' => '/backups-eu', 'password' => '*****'],
]);

Hedefi Silme

delete/api/v1/admin/settings/backup/storage/{id}
Settings/DeleteBackupStorage admin onay geri alınır

Bir depolama hedefini kaldırır.

Dönen alanlar data — 2
deletedboolSilme çalıştı mı.
idintSilinen hedefin kimliği.
Hatalar 3
not_found404Hedef bulunamadı.
storage_in_use422Bir zamanlama bu hedefi kullanıyor.
insufficient_scope403Anahtar gerekli kapsamı taşımıyor.
İstek
curl -X DELETE 'https://panel.ornek.com/api/v1/admin/settings/backup/storage/12' \
  -H "Authorization: Bearer $API_KEY"
const res = await fetch(`https://panel.ornek.com/api/v1/admin/settings/backup/storage/${id}`, {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();
$ch = curl_init('https://panel.ornek.com/api/v1/admin/settings/backup/storage/' . $id);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Bulut hedefte silme ONAYI da geri alir: ayni hesabi yeniden eklemek yeni onay ister.
Api::Settings()->DeleteBackupStorage(['id' => $id]);

Tuzaklar

Maske okumada korur, oluşturmada işe yaramaz

Detay ve liste uçları gizli alanları maskeyle döndürür. Güncellemede maskeyi geri göndermek eski değeri korur. Oluşturmada ise korunacak eski değer yoktur: okuduğunuzu olduğu gibi yeni bir hedefe verirseniz şifre olarak maskenin kendisi kaydedilir ve bağlantı sınaması düşer.

Sınamak kaydetmek değildir

Sınama ucu hiçbir şey kaydetmez; yalnız bağlantıyı dener. Geçmesi hedefin oluştuğu anlamına gelmez. Panelde iki adım arka arkaya göründüğü için bu karışır: sınama başarılı çıkar, oluşturma çağrısı unutulur ve zamanlamaya verecek bir hedef bulunamaz.

Bulut sağlayıcı ayarla kurulmaz

Onay isteyen bir sağlayıcıda ayarları yazmak yetmez: kullanıcının tarayıcıda erişim vermesi gerekir. Belirteç olmadan oluşturma çağrısı onay eksik diyerek düşer. Sağlayıcı listesindeki onay alanı, hangi sağlayıcının bu üç adımlı yolu istediğini önceden söyler.

Zamanlamanın kullandığı hedef silinmez

Bir zamanlama hedefe bağlıyken silme çağrısı reddedilir. Önce zamanlamayı başka bir hedefe taşıyın ya da kaldırın. Bu koruma kasıtlıdır: hedefi sessizce silmek, zamanlamayı her gece boşa çalışan bir işe çevirirdi.

Silmek onayı da geri alır

Bulut hedefi silinirken sağlayıcıdaki erişim izni de iptal edilir. Aynı hesabı yeniden eklemek yeni bir onay turu ister; eski belirteç işe yaramaz. İptal elden geldiğince denenir, yani sağlayıcıya ulaşılamazsa hedef yine de silinir ve izin sağlayıcı tarafında kalabilir.

Faydalı oldu mu?

Geri bildiriminiz için teşekkürler!

Hâlâ Yardıma mı İhtiyacınız Var?

Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.