Skip to content
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
e603353
add srv_target column to cloudflare_domains migration
HarlequinSin Dec 28, 2025
5948e9c
add SRV record and target strings
HarlequinSin Dec 28, 2025
cc76657
add srv_target field to CloudflareDomain model and resource
HarlequinSin Dec 28, 2025
e17c617
add srv_record toggle to SubdomainRelationManager and SubdomainResource
HarlequinSin Dec 28, 2025
2e72466
Adding logic for srv records
HarlequinSin Dec 28, 2025
f20e58e
add error messages for missing SRV target and enhance tooltip logic i…
HarlequinSin Dec 28, 2025
58de843
add zone request status messages and improve logging for missing SRV …
HarlequinSin Dec 28, 2025
2ff7a99
add CloudflareService class for managing DNS records with upsert and …
HarlequinSin Dec 28, 2025
1572187
cleanup
HarlequinSin Dec 28, 2025
eb1a0eb
Remade script to utilize upsert with better error handling
HarlequinSin Dec 28, 2025
6951bc7
Update to CloudflareDomain model to fetch Cloudflare Zone ID with not…
HarlequinSin Dec 28, 2025
f18101a
Changed upsert to require a recordId to be known (prevents changing r…
HarlequinSin Dec 28, 2025
58f73e1
Cleanup
HarlequinSin Dec 28, 2025
89f45b8
Fixing notifications
HarlequinSin Dec 28, 2025
d369cc3
- Fixed issue with create record as SRV
HarlequinSin Dec 28, 2025
7d1b33a
Remove unused Hidden component
HarlequinSin Dec 28, 2025
910b812
- Added default for subdomain selection
HarlequinSin Dec 28, 2025
b42370d
- Fixed erroneous success logic
HarlequinSin Dec 28, 2025
ea4e602
Removed unused classes
HarlequinSin Dec 28, 2025
66d4384
lang support
HarlequinSin Dec 28, 2025
f7b98d3
corrected notification log
HarlequinSin Dec 28, 2025
9804937
Fixed http success logic
HarlequinSin Dec 28, 2025
d004dda
fixed style issues and syntax error
HarlequinSin Dec 28, 2025
a4d9827
fixing blank_line_before_statement
HarlequinSin Dec 28, 2025
c4654fd
append version to 1.1.0
HarlequinSin Dec 28, 2025
348099d
Add notification for missing SRV target in Cloudflare integration
HarlequinSin Dec 29, 2025
d64612d
minor wording updates
HarlequinSin Dec 29, 2025
5bfd8df
Dynamically disable SRV record toggle if domain is missing srv_target
HarlequinSin Dec 29, 2025
e781f6a
lang cleanup, removed redundent strings
HarlequinSin Dec 29, 2025
8a7e932
Make SRV record toggle reactive
HarlequinSin Dec 29, 2025
23c4e39
Fix capitalization in Cloudflare notification titles
HarlequinSin Dec 29, 2025
f31a101
clean up
HarlequinSin Dec 29, 2025
6b31686
migration to move srv_target from cloudflare domains to nodes
HarlequinSin Jan 1, 2026
d2c0e18
Changing srv_target from domains to node
HarlequinSin Jan 1, 2026
c476a60
lang updates for new notifications
HarlequinSin Jan 1, 2026
5125263
Changing SRV record service from hard-coded for minecraft to based on…
HarlequinSin Jan 1, 2026
de62b89
cleaning up record_type/srv_record code
HarlequinSin Jan 1, 2026
8b7df3e
Fixed undefined class
HarlequinSin Jan 1, 2026
194243c
cx and pint formatting
HarlequinSin Jan 1, 2026
079563f
pint style fixes
HarlequinSin Jan 1, 2026
12db61c
moving to different branch
HarlequinSin Jan 1, 2026
f2ba928
shortened/simplified all npe checks
HarlequinSin Jan 1, 2026
ccaa94e
more simplified npe checks
HarlequinSin Jan 1, 2026
f4757fd
npe and pint style issues
HarlequinSin Jan 1, 2026
060dd6e
Added field updated check for srv_target
HarlequinSin Jan 1, 2026
fa0e3a6
creating set srv_target button
HarlequinSin Jan 2, 2026
565adf6
changing subdomain model logic to:
HarlequinSin Jan 2, 2026
912984c
fixing notification issues
HarlequinSin Jan 2, 2026
98b5f64
Merge branch 'main' into main
HarlequinSin Jan 2, 2026
c771faa
moved to button
HarlequinSin Jan 2, 2026
b51f784
Merge branch 'main' of https://github.com/HarlequinSin/pelican-plugins
HarlequinSin Jan 2, 2026
8b6c3b0
unused imports
HarlequinSin Jan 2, 2026
2b30342
phpstan issues
HarlequinSin Jan 2, 2026
109a2c6
fixing phpstan issues
HarlequinSin Jan 3, 2026
f16ed67
pint/phpstan issues
HarlequinSin Jan 3, 2026
0d8b080
fixing more pint/phpstan issues
HarlequinSin Jan 4, 2026
5e4f739
phpstan issues
HarlequinSin Jan 4, 2026
c54cbeb
phpstan issues, again
HarlequinSin Jan 4, 2026
0fe6e8f
change domains to require cloudflare_id to be set
HarlequinSin Jan 4, 2026
03a351d
- Added check for existing record before updating/deleting
HarlequinSin Jan 4, 2026
5c2b23f
php stan fixes
HarlequinSin Jan 4, 2026
dc91cca
Updated subdomains information
HarlequinSin Jan 4, 2026
3b2dd88
fixed invalid column issue
HarlequinSin Jan 4, 2026
c09e050
Remove null cloudflare_id entries from subdomains table
HarlequinSin Jan 4, 2026
660b0b6
fixing various null issues
HarlequinSin Jan 4, 2026
52b1589
phpstan issues
HarlequinSin Jan 4, 2026
75c17da
more npes
HarlequinSin Jan 4, 2026
0173530
more null checks
HarlequinSin Jan 4, 2026
a746d35
phpstan ignore errors
HarlequinSin Jan 4, 2026
53e6dab
phpstan ignores
HarlequinSin Jan 4, 2026
87d4de8
more phpstan ignores...
HarlequinSin Jan 4, 2026
732e925
npe fixes
HarlequinSin Jan 4, 2026
a288d46
phpstan ignores... again
HarlequinSin Jan 4, 2026
54cc9ee
improve server relation handling during creation
HarlequinSin Jan 4, 2026
0c75e5a
no_unused_imports
HarlequinSin Jan 4, 2026
a82334a
simplify server relation handling during creation
HarlequinSin Jan 4, 2026
de10ede
nullcheck for domainName & zoneId
HarlequinSin Jan 4, 2026
0ba3dc6
phpstan ignores
HarlequinSin Jan 4, 2026
113db00
Change requests for:
HarlequinSin Jan 4, 2026
465e8b0
pint and missing use reference
HarlequinSin Jan 4, 2026
543393f
Added some additional egg tag types for SRV records
HarlequinSin Jan 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void
{
Schema::table('cloudflare_domains', function (Blueprint $table) {
$table->string('srv_target')->nullable()->after('cloudflare_id');
});
}

public function down(): void
{
Schema::table('cloudflare_domains', function (Blueprint $table) {
$table->dropColumn('srv_target');
});
}
};
19 changes: 19 additions & 0 deletions subdomains/lang/en/strings.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,25 @@

'name' => 'Name',

'srv_record' => 'SRV Record',
'srv_record_help' => 'Enable this option to create a SRV record instead of an A or AAAA record.',

'srv_target' => 'SRV Target',
'srv_target_help' => 'The hostname that SRV records point to (for example: play.example.com).',

'errors' => [
'srv_target_missing' => 'Cannot enable SRV record because the selected domain does not have an SRV target set.',
],

'api_token' => 'Cloudflare API Token',
'api_token_help' => 'The token needs to have read permissions for Zone.Zone and write for Zone.Dns. For better security you can also set the "Zone Resources" to exclude certain domains and add the panel ip to the "Client IP Adress Filtering".',

'notifications' => [
'dns_created' => 'DNS record created on Cloudflare',
'dns_updated' => 'DNS record updated on Cloudflare',
'dns_deleted' => 'DNS record deleted from Cloudflare',
'dns_action_failed' => 'Cloudflare DNS action failed',
'zone_request_failed' => 'Cloudflare zone request failed',
'zone_request_succeeded' => 'Cloudflare zone request succeeded',
],
];
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public static function table(Table $table): Table
->columns([
TextColumn::make('name')
->label(trans('subdomains::strings.name')),
TextColumn::make('srv_target')
->label(trans('subdomains::strings.srv_target')),
TextColumn::make('subdomains_count')
->label(trans_choice('subdomains::strings.subdomain', 2))
->counts('subdomains'),
Expand All @@ -77,6 +79,11 @@ public static function form(Schema $schema): Schema
->label(trans('subdomains::strings.name'))
->required()
->unique(),
TextInput::make('srv_target')
->label(trans('subdomains::strings.srv_target'))
->helperText(trans('subdomains::strings.srv_target_help'))
->placeholder('play.example.com')
->rules(['nullable', 'string', 'regex:/^(?=.{1,253}$)(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.(?!-)[A-Za-z0-9-]{1,63}(?<!-))*$/']),
]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ protected function getHeaderActions(): array
{
return [
CreateAction::make()
->createAnother(false),
->createAnother(false)
->successNotification(null),
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteAction;
use Filament\Actions\EditAction;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Notifications\Notification;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Schema;
Expand Down Expand Up @@ -83,8 +83,10 @@ public function form(Schema $schema): Schema
->relationship('domain', 'name')
->preload()
->searchable(),
Hidden::make('record_type')
->default(fn () => is_ipv6($this->getOwnerRecord()->allocation->ip) ? 'AAAA' : 'A'),
Toggle::make('srv_record')
->label(trans('subdomains::strings.srv_record'))
->helperText(trans('subdomains::strings.srv_record_help'))
->default(false),
]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
use Filament\Actions\DeleteAction;
use Filament\Actions\EditAction;
use Filament\Facades\Filament;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Support\Enums\IconSize;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\ToggleColumn;
use Filament\Tables\Table;

class SubdomainResource extends Resource
Expand Down Expand Up @@ -78,10 +79,15 @@ public static function table(Table $table): Table
TextColumn::make('label')
->label(trans('subdomains::strings.name'))
->state(fn (Subdomain $subdomain) => $subdomain->getLabel()),
ToggleColumn::make('srv_record')
->label(trans('subdomains::strings.srv_record'))
->tooltip(fn (Subdomain $record) => $record->domain && $record->domain->srv_target ? trans('subdomains::strings.srv_record_help') : trans('subdomains::strings.errors.srv_target_missing'))
->disabled(fn (Subdomain $record) => !$record->domain || empty($record->domain->srv_target)),
])
->recordActions([
EditAction::make(),
DeleteAction::make(),
DeleteAction::make()
->successNotification(null),
])
->toolbarActions([
CreateAction::make()
Expand All @@ -92,6 +98,7 @@ public static function table(Table $table): Table
->createAnother(false)
->hiddenLabel()
->iconButton()
->successNotification(null)
->iconSize(IconSize::ExtraLarge),
]);
}
Expand All @@ -110,14 +117,13 @@ public static function form(Schema $schema): Schema
->required()
->relationship('domain', 'name')
->preload()
->default(fn () => CloudflareDomain::first()?->id ?? null)
->searchable(),
Hidden::make('record_type')
->default(function () {
/** @var Server $server */
$server = Filament::getTenant();

return is_ipv6($server->allocation->ip) ? 'AAAA' : 'A';
}),
Toggle::make('srv_record')
->label(trans('subdomains::strings.srv_record'))
->helperText(trans('subdomains::strings.srv_record_help'))
->disabled(false) // TODO: Dynamically disable if domain missing srv_target
->default(false),
]);
}

Expand Down
41 changes: 22 additions & 19 deletions subdomains/src/Models/CloudflareDomain.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,53 @@

namespace Boy132\Subdomains\Models;

use Boy132\Subdomains\Services\CloudflareService;
use Filament\Notifications\Notification;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Facades\Http;

/**
* @property int $id
* @property string $name
* @property ?string $cloudflare_id
* @property ?string $srv_target
*/
class CloudflareDomain extends Model
{
protected $fillable = [
'name',
'cloudflare_id',
'srv_target',
];

protected static function boot(): void
{
parent::boot();

static::created(function (self $model) {
$model->fetchCloudflareId();
$service = new CloudflareService();

$zoneId = $service->getZoneId($model->name);
if (!$zoneId) {
Notification::make()
->title('Failed to fetch Cloudflare Zone ID for domain: ' . $model->name)
->danger()
->send();
} else {
Notification::make()
->title('Successfully saved domain: ' . $model->name)
->success()
->send();

$model->update([
'cloudflare_id' => $zoneId,
]);
}
});
}

public function subdomains(): HasMany
{
return $this->hasMany(Subdomain::class, 'domain_id');
}

public function fetchCloudflareId(): void
{
$response = Http::cloudflare()->get('zones', [
'name' => $this->name,
])->json();

if ($response['success']) {
$zones = $response['result'];

if (count($zones) > 0) {
$this->update([
'cloudflare_id' => $zones[0]['id'],
]);
}
}
}
}
Loading
Loading