Skip to content

Commit 98abc4a

Browse files
authored
Merge pull request #15 from Icinga/persistent-volume-claims
Persistent volume claims
2 parents f7f278f + f7ed2bd commit 98abc4a

12 files changed

+515
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/* Icinga Kubernetes Web | (c) 2023 Icinga GmbH | GPLv2 */
4+
5+
namespace Icinga\Module\Kubernetes\Controllers;
6+
7+
use Icinga\Module\Kubernetes\Common\Database;
8+
use Icinga\Module\Kubernetes\Model\PersistentVolumeClaim;
9+
use Icinga\Module\Kubernetes\Web\PersistentVolumeClaimDetail;
10+
use ipl\Stdlib\Filter;
11+
use ipl\Web\Compat\CompatController;
12+
13+
class PersistentvolumeclaimController extends CompatController
14+
{
15+
public function indexAction(): void
16+
{
17+
$id = $this->params->getRequired('id');
18+
19+
$query = PersistentVolumeClaim::on(Database::connection())
20+
->filter(Filter::all(
21+
Filter::equal('pvc.id', $id),
22+
));
23+
24+
/** @var PersistentVolumeClaim $pvc */
25+
$pvc = $query->first();
26+
if ($pvc === null) {
27+
$this->httpNotFound($this->translate('Persistent Volume Claim not found'));
28+
}
29+
30+
$this->addTitleTab("Persistent Volume Claim $pvc->namespace/$pvc->name");
31+
32+
$this->addContent(new PersistentVolumeClaimDetail($pvc));
33+
}
34+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
/* Icinga Kubernetes Web | (c) 2023 Icinga GmbH | GPLv2 */
4+
5+
namespace Icinga\Module\Kubernetes\Controllers;
6+
7+
use Icinga\Module\Kubernetes\Common\Database;
8+
use Icinga\Module\Kubernetes\Model\PersistentVolumeClaim;
9+
use Icinga\Module\Kubernetes\Model\Pod;
10+
use Icinga\Module\Kubernetes\TBD\ObjectSuggestions;
11+
use Icinga\Module\Kubernetes\Web\Controller;
12+
use Icinga\Module\Kubernetes\Web\PersistentVolumeClaimList;
13+
use Icinga\Module\Kubernetes\Web\PodList;
14+
use ipl\Web\Compat\SearchControls;
15+
use ipl\Web\Control\LimitControl;
16+
use ipl\Web\Control\SortControl;
17+
18+
class PersistentvolumeclaimsController extends Controller
19+
{
20+
use SearchControls;
21+
22+
public function indexAction(): void
23+
{
24+
$this->addTitleTab($this->translate('Persistent Volume Claims'));
25+
26+
$pvcs = PersistentVolumeClaim::on(Database::connection());
27+
28+
$limitControl = $this->createLimitControl();
29+
$sortControl = $this->createSortControl(
30+
$pvcs,
31+
[
32+
'pvc.name' => $this->translate('Name'),
33+
'pvc.created' => $this->translate('Created')
34+
]
35+
);
36+
37+
$paginationControl = $this->createPaginationControl($pvcs);
38+
$searchBar = $this->createSearchBar($pvcs, [
39+
$limitControl->getLimitParam(),
40+
$sortControl->getSortParam(),
41+
]);
42+
43+
if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) {
44+
if ($searchBar->hasBeenSubmitted()) {
45+
$filter = $this->getFilter();
46+
} else {
47+
$this->addControl($searchBar);
48+
$this->sendMultipartUpdate();
49+
50+
return;
51+
}
52+
} else {
53+
$filter = $searchBar->getFilter();
54+
}
55+
56+
$pvcs->filter($filter);
57+
58+
$this->addControl($paginationControl);
59+
$this->addControl($sortControl);
60+
$this->addControl($limitControl);
61+
$this->addControl($searchBar);
62+
63+
$this->addContent(new PersistentVolumeClaimList($pvcs));
64+
65+
if (! $searchBar->hasBeenSubmitted() && $searchBar->hasBeenSent()) {
66+
$this->sendMultipartUpdate();
67+
}
68+
}
69+
70+
public function completeAction(): void
71+
{
72+
$suggestions = new ObjectSuggestions();
73+
$suggestions->setModel(PersistentVolumeClaim::class);
74+
$suggestions->forRequest($this->getServerRequest());
75+
$this->getDocument()->add($suggestions);
76+
}
77+
78+
public function searchEditorAction(): void
79+
{
80+
$editor = $this->createSearchEditor(PersistentVolumeClaim::on(Database::connection()), [
81+
LimitControl::DEFAULT_LIMIT_PARAM,
82+
SortControl::DEFAULT_SORT_PARAM,
83+
]);
84+
85+
$this->getDocument()->add($editor);
86+
$this->setTitle(t('Adjust Filter'));
87+
}
88+
89+
protected function getPageSize($default)
90+
{
91+
return parent::getPageSize($default ?? 50);
92+
}
93+
}

configuration.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,15 @@
9393
]
9494
);
9595

96+
$section->add(
97+
N_('Persistent Volume Claims'),
98+
[
99+
'description' => $this->translate('Persistent Volume Claims'),
100+
'url' => 'kubernetes/persistentvolumeclaims',
101+
'priority' => $i++
102+
]
103+
);
104+
96105
$this->provideConfigTab(
97106
'database',
98107
[

library/Kubernetes/Common/Icons.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ abstract class Icons
1818

1919
public const POD_FAILED = 'circle-triangle';
2020

21+
public const PVC_PENDING = 'spinner';
22+
23+
public const PVC_BOUND = 'link';
24+
25+
public const PVC_LOST = 'file-circle-exclamation';
26+
2127
public const DEPLOYMENT_HEALTHY = 'circle-check';
2228

2329
public const DEPLOYMENT_UNHEALTHY = 'exclamation-triangle';

library/Kubernetes/Common/Links.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Icinga\Module\Kubernetes\Model\Pod;
1414
use Icinga\Module\Kubernetes\Model\ReplicaSet;
1515
use Icinga\Module\Kubernetes\Model\StatefulSet;
16+
use Icinga\Module\Kubernetes\Model\PersistentVolumeClaim;
1617
use ipl\Web\Url;
1718

1819
abstract class Links
@@ -61,4 +62,9 @@ public static function event(Event $event): Url
6162
{
6263
return Url::fromPath('kubernetes/event', ['id' => bin2hex($event->id)]);
6364
}
65+
66+
public static function pvc(PersistentVolumeClaim $persistentVolumeClaim): Url
67+
{
68+
return Url::fromPath('kubernetes/persistentvolumeclaim', ['id' => bin2hex($persistentVolumeClaim->id)]);
69+
}
6470
}

library/Kubernetes/Model/Label.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ public function createRelations(Relations $relations)
6565
$relations
6666
->belongsToMany('pod', Pod::class)
6767
->through('pod_label');
68+
69+
$relations
70+
->belongsToMany('pvc', PersistentVolumeClaim::class)
71+
->through('pvc_label');
6872
//
6973
// $relations->belongsToMany('contact', Contact::class)
7074
// ->through('incident_contact');
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
3+
/* Icinga Kubernetes Web | (c) 2023 Icinga GmbH | GPLv2 */
4+
5+
namespace Icinga\Module\Kubernetes\Model;
6+
7+
use ipl\Orm\Behavior\Binary;
8+
use ipl\Orm\Behavior\MillisecondTimestamp;
9+
use ipl\Orm\Behaviors;
10+
use ipl\Orm\Model;
11+
use ipl\Orm\Relations;
12+
13+
class PersistentVolumeClaim extends Model
14+
{
15+
public const PHASE_PENDING = 'pending';
16+
17+
public const PHASE_BOUND = 'bound';
18+
19+
public const PHASE_LOST = 'failed';
20+
21+
public function getTableName()
22+
{
23+
return 'pvc';
24+
}
25+
26+
public function getKeyName()
27+
{
28+
return 'id';
29+
}
30+
31+
public function getColumns()
32+
{
33+
return [
34+
'namespace',
35+
'name',
36+
'uid',
37+
'resource_version',
38+
'desired_access_modes',
39+
'actual_access_modes',
40+
'minimum_capacity',
41+
'actual_capacity',
42+
'phase',
43+
'volume_name',
44+
'volume_mode',
45+
'storage_class',
46+
'created'
47+
];
48+
}
49+
50+
public function getColumnDefinitions()
51+
{
52+
return [
53+
'namespace' => t('Namespace'),
54+
'name' => t('Name'),
55+
'phase' => t('Phase'),
56+
'created' => t('Created At')
57+
];
58+
}
59+
60+
public function getSearchColumns()
61+
{
62+
return ['name'];
63+
}
64+
65+
public function getDefaultSort()
66+
{
67+
return ['namespace', 'created desc'];
68+
}
69+
70+
public function createBehaviors(Behaviors $behaviors)
71+
{
72+
$behaviors->add(
73+
new Binary([
74+
'id'
75+
])
76+
);
77+
$behaviors->add(
78+
new MillisecondTimestamp([
79+
'created'
80+
])
81+
);
82+
}
83+
84+
public function createRelations(Relations $relations)
85+
{
86+
$relations->hasMany('condition', PersistentVolumeClaimCondition::class);
87+
88+
$relations
89+
->belongsToMany('label', Label::class)
90+
->through('pvc_label');
91+
92+
$relations
93+
->belongsTo('pod', Pod::class);
94+
}
95+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
/* Icinga Kubernetes Web | (c) 2023 Icinga GmbH | GPLv2 */
4+
5+
namespace Icinga\Module\Kubernetes\Model;
6+
7+
use ipl\Orm\Behavior\Binary;
8+
use ipl\Orm\Behavior\MillisecondTimestamp;
9+
use ipl\Orm\Behaviors;
10+
use ipl\Orm\Model;
11+
use ipl\Orm\Relations;
12+
13+
class PersistentVolumeClaimCondition extends Model
14+
{
15+
public function getTableName()
16+
{
17+
return 'pvc_condition';
18+
}
19+
20+
public function getKeyName()
21+
{
22+
return ['pvc_id', 'type'];
23+
}
24+
25+
public function getColumns()
26+
{
27+
return [
28+
'status',
29+
'last_probe',
30+
'last_transition',
31+
'message',
32+
'reason'
33+
];
34+
}
35+
36+
public function getColumnDefinitions()
37+
{
38+
return [
39+
'type' => t('Type'),
40+
'status' => t('Status'),
41+
'last_probe' => t('Last Probe'),
42+
'last_transition' => t('Last Transition'),
43+
'message' => t('Message'),
44+
'reason' => t('Reason')
45+
];
46+
}
47+
48+
public function getDefaultSort()
49+
{
50+
return ['last_transition desc'];
51+
}
52+
53+
public function createBehaviors(Behaviors $behaviors)
54+
{
55+
$behaviors->add(
56+
new Binary([
57+
'pvc_id'
58+
])
59+
);
60+
$behaviors->add(
61+
new MillisecondTimestamp([
62+
'last_probe',
63+
'last_transition'
64+
])
65+
);
66+
}
67+
68+
public function createRelations(Relations $relations)
69+
{
70+
$relations
71+
->belongsTo('pvc', PersistentVolumeClaim::class);
72+
}
73+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/* Icinga Kubernetes Web | (c) 2023 Icinga GmbH | GPLv2 */
4+
5+
namespace Icinga\Module\Kubernetes\TBD;
6+
7+
class AccessModes
8+
{
9+
public const READ_WRITE_ONCE = 1 << 0;
10+
11+
public const READ_ONLY_MANY = 1 << 1;
12+
13+
public const READ_WRITE_MANY = 1 << 2;
14+
15+
public const READ_WRITE_ONCE_POD = 1 << 3;
16+
17+
public static $names = [
18+
self::READ_WRITE_ONCE => 'ReadWriteOnce',
19+
self::READ_ONLY_MANY => 'ReadOnlyMany',
20+
self::READ_WRITE_MANY => 'ReadWriteMany',
21+
self::READ_WRITE_ONCE_POD => 'ReadWriteOncePod'
22+
];
23+
24+
public static function asNames(int $bitmask): array
25+
{
26+
$names = [];
27+
28+
foreach (static::$names as $flag => $name) {
29+
if ($bitmask & $flag) {
30+
$names[] = $name;
31+
}
32+
}
33+
34+
return $names;
35+
}
36+
}

0 commit comments

Comments
 (0)