Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,9 @@ $svc = $cluster->service()
->create();
```

## 📄 Extensive Documentation
## 📄 Getting Started

This package is Work in Progress and while there is in active development, PRs are also welcomed. Please refer to the [Resources docs](docs/RESOURCES.md) documentation and the [PR List](../../pulls) to know what's up for development.

Each existent resource has its own documentation, filled with examples:
Please refer to the [Resources docs](docs/RESOURCES.md) extensive documentation and the [PR List](../../pulls) to know what's up for development. Below you will find the list of supported resources for a quick and easy access.

| Resource | Default Version
| - | -
Expand All @@ -100,8 +98,6 @@ Each existent resource has its own documentation, filled with examples:
| [StatefulSet](docs/kinds/StatefulSet.md) | `apps/v1`
| [StorageClass](docs/kinds/StorageClass.md) | `storage.k8s.io/v1`

For other resources, you can check the [Resources Documentation](docs/RESOURCES.md)

## 🐛 Testing

``` bash
Expand Down
191 changes: 191 additions & 0 deletions docs/CRDS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
# Defining CRDs

The ease of using basic Kubernetes resources can be extended into creating CRDs for your custom use case. This needs a lot of context about what you can apply to the resources, based on your needs.

In these examples, we will be looking at the [Traefik CRDs](https://doc.traefik.io/traefik/routing/providers/kubernetes-crd) and [Agones CRDs](https://github.com/googleforgames/agones/tree/main/install/helm/agones/templates/crds). The versions might differ from the actual live Traefik docs, it's just for the example purposes.

# Getting started

Each CRD must extend the `K8sResource` class. This will provide the base PHP API functionalities that you can work with your resource.

Additionally, to be able to interact with the cluster and actually perform operations on it, you should implement the `InteractsWithK8sCluster` interface.


The following example will create an `IngressRoute` CRD-ready class for `traefik.containo.us/v1alpha1`:

```php
use RenokiCo\PhpK8s\Contracts\InteractsWithK8sCluster;
use RenokiCo\PhpK8s\Kinds\K8sResource;

class IngressRoute extends K8sResource implements InteractsWithK8sCluster
{
/**
* The resource Kind parameter.
*
* @var null|string
*/
protected static $kind = 'IngressRoute';

/**
* The default version for the resource.
*
* @var string
*/
protected static $defaultVersion = 'traefik.containo.us/v1alpha1';

/**
* Wether the resource has a namespace.
*
* @var bool
*/
protected static $namespaceable = true;
}

$ir = new IngressRoute([
'spec' => [
'entryPoints' => ...
],
]);

$ir->create();
```

**For non-namespaceable resources, you shall set the `$namespaceable` variable to `false`.**

## Watchable Resources

Watchable Resources are resources that can access the `/watch` endpoint in order to poll the changes over one or more resources. Typically, this can happen on any resource on which you can run `kubectl get some-crd --watch` upon.

For example, on basic CRDs (the default K8s ones), many resources like Service or Secret come with a watchable implementation.

You can read more about [how to watch a resource](Usage.md#watch-resource).

```php
use RenokiCo\PhpK8s\Contracts\InteractsWithK8sCluster;
use RenokiCo\PhpK8s\Contracts\Watchable;
use RenokiCo\PhpK8s\Kinds\K8sResource;

class IngressRoute extends K8sResource implements InteractsWithK8sCluster, Watchable
{
//
}

(new IngressRoute)->whereName('foo')->watch(function ($type, $ir) {
//
});
```

## Scalable Resources

Scalable resources need a custom API on which you can call scale operations on them. Usually, this is done for resources that open a `/scale` endpoint to the API.

On the default CRDs, this is applied to StatefulSets and Deployments.

You can look on [how StatefulSets are scaled](kinds/StatefulSet.md#scaling)

```php
use RenokiCo\PhpK8s\Contracts\InteractsWithK8sCluster;
use RenokiCo\PhpK8s\Contracts\Scalable;
use RenokiCo\PhpK8s\Kinds\K8sResource;
use RenokiCo\PhpK8s\Traits\CanScale;

class GameServerSet extends K8sResource implements InteractsWithK8sCluster, Scalable
{
use CanScale;
}

$scaler = $gameServerSet->scale(3);
```

## Podable Resources

Podable resources are resources that manage pods. You can easily get the pods that are ran under the resource.

For example, Jobs and DaemonSets are one of the kinds that have this behaviour.

In PHP, this implementation is a bit tricky and need some configuration on your side:

```php
use RenokiCo\PhpK8s\Contracts\InteractsWithK8sCluster;
use RenokiCo\PhpK8s\Contracts\Podable;
use RenokiCo\PhpK8s\Kinds\K8sResource;
use RenokiCo\PhpK8s\Traits\HasPods;

class GameServerSet extends K8sResource implements InteractsWithK8sCluster, Podable
{
use HasPods;

/**
* Get the selector for the pods that are owned by this resource.
*
* @return array
*/
public function podsSelector(): array
{
return [
'game-server-name' => $this->getName(),
];
}
}

$gameServerSet = new GameServerSet([
'metadata' => [
'name' => 'some-name',
],
'spec' => [
'template' => [
'metadata' => [
'labels' => [
'game-server-name' => 'some-name', // this must match
],
],
...
],
...
],
...
]);

foreach ($gameServerSet->getPods() as $pod) {
//
}
```

As you can see, there is a `podsSelector()` array where you can define a set of labels that a `Pod` managed by this resource needs to have in order to `->getPods()` to work on it.

The labels for the Pod can be defined in the template spec of the resource. [Read more about the pod template definition in StatefulSets](kinds/StatefulSet.md#example) and [how to retrieve pods in StatefulSets](kinds/StatefulSet.md#getting-pods)


## Loggable Resources

Loggable resources are resources that expose the `/log` endpoint and can easily get logs, both statically and in a polling request manner.

Check the [documentation on how to watch or get logs](kinds/Pod.md#pod-logs) using Pods.

```php
use RenokiCo\PhpK8s\Contracts\Loggable;
use RenokiCo\PhpK8s\Kinds\K8sResource;

class GameServerSet extends K8sResource implements InteractsWithK8sCluster, Loggable
{
//
}
```

# Helper Traits

"Helper Traits" are just traits that make the boring nested variables be easier set with a more friendly way.

You can find some in the [Traits folder](../../tree/master/src/Traits). By default, the `K8sResource` already uses the `HasAttributes` trait.

```php
use RenokiCo\PhpK8s\Kinds\K8sResource;
use RenokiCo\PhpK8s\Traits\HasStatus;

class GameServerSet extends K8sResource implements InteractsWithK8sCluster
{
use HasStatus;
}

$gameServerSet->getStatus('some.path');
```
20 changes: 12 additions & 8 deletions docs/RESOURCES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

## Cluster Interaction

- [Methods & Usage](Usage.md)
- [Cluster & Authentication](Cluster.md)
- [General Resources](kinds/Resource.md)
- [Methods & Usage - learn the basics](Usage.md)
- [Cluster & Authentication - authenticate to your cluster](Cluster.md)
- [General API - Methods implemented in all resources](kinds/Resource.md)

## Supported Instances
## Instances

Instances are custom classes that makes the build of containers, for example, more object-oriented that passing an array.
Instances are custom PHP classes that makes the nested YAML definitions be easier to define. For example, you can build containers configuration for a pod in a more object-oriented manner by simply passing an Instance object than building the array from scratch.

- [Affinity](instances/Affinity.md) - used to declare affinities and anti-affinities
- [Container](instances/Container.md) - used for Pods & Templates
Expand All @@ -18,11 +18,11 @@ Instances are custom classes that makes the build of containers, for example, mo
- [Rules](instances/Rules.md) - used for Roles & Cluster Roles
- [Volumes](instances/Volumes.md) - used for mounting volumes in pods and containers

## Supported Resources
## Resources (CRDs)

Each resource inherits a default "base" class that is making the Resource build-up easier.

**Check the documentation for [General Resources](kinds/Resource.md) and [K8s API Usage](Usage.md) before diving in to the actual resources documentation.**
**Check the documentation for [General API](kinds/Resource.md) and [K8s API Usage](Usage.md) before diving in to the actual resources documentation.**

| Resource | Default Version
| - | -
Expand All @@ -48,14 +48,18 @@ Each resource inherits a default "base" class that is making the Resource build-
| [StatefulSet](kinds/StatefulSet.md) | `apps/v1`
| [StorageClass](kinds/StorageClass.md) | `storage.k8s.io/v1`

## Default Versions for Reosurces
## Default Versions for Resources

Since we support multiple K8s Cluster versions, some versions do promote certain resources to GA. Since each resource needs a default version, the package will set **the default versions for the oldest Kubernetes version supported**.

For example, if the package supports `v1.18 +`, then the package will make sure the versions are defaults for `v1.18`. In some cases, like Ingress in `v1.19` that switched from Beta to GA, the `v1beta1` is no longer a default and instead, the `v1` is now a default. If `v1.17` is the oldest supported version, then it will stay to `v1beta`.

The minimum Kubernetes version that is supported by a given package version can be found at the top of [README.md](../README.md).

## Custom CRDs

The `K8sResource` class is extendable and expose a lot of PHP API that you can use to build your custom resources. [Head up to the CRDs docs](CRDS.md) to learn more about implementing your own custom resources.

## Planned

The following list of resources are planned and they will be available soon:
Expand Down
30 changes: 8 additions & 22 deletions docs/Usage.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
# Usage
# Methods & Usage

All delivered [Resources](Resources.md) coming with this package do interact with the K8s Cluster you define. For instance, the idea behind this is to be able to import or create resources, with or without YAML, using PHP.
CRDs are by default interacting with the API. For instance, the idea behind this is to be able to import or create resources, with or without YAML, using PHP.

## Retrieving all resources

Getting all resources can be done by calling `->all()`:

```php
$namespaces = $cluster->namespace()->all();
```

Or you can use a specific method to call it at once:

```php
// Or you can use a specific method to call it at once
$namespaces = $cluster->getAllNamespaces();
```

For namespaced resources, you may pass the namespace:

```php
// For namespaced resources, you may pass the namespace
$stagingServices = $cluster->getAllServices('staging');
```

Expand All @@ -38,23 +32,15 @@ Getting only one resource is done by calling `->get()`:

```php
$service = $cluster->service()->whereNamespace('staging')->whereName('nginx')->get();
```

You can also shorten it like:

```php
// You can also shorten it like
$service = $cluster->service()->whereNamespace('staging')->getByName('nginx');
```

Or you can use a specific method to call it in at once:

```php
// Or you can use a specific method to call it in at once
$service = $cluster->getServiceByName('nginx', 'staging');
```

Filters can vary, depending if the resources are namespaceable or not.

By default, the namespace is `default` and can be missed from the filters.
Filters can vary, depending if the resources are namespaceable or not. By default, the namespace is `default` and can be missed from the filters.

## Creating resources

Expand Down Expand Up @@ -91,7 +77,7 @@ Additionally, you can pass query parameters, grace period and the propagation po
The defaults are:

```php
delete(array $query = ['pretty' => 1], $gracePeriod = null, string $propagationPolicy = 'Foreground'
delete(array $query = ['pretty' => 1], $gracePeriod = null, string $propagationPolicy = 'Foreground')
```

## Creating or updating resources
Expand Down
2 changes: 1 addition & 1 deletion docs/kinds/CronJob.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ $container = K8s::container()

$pod = K8s::pod()
->setName('pi')
->setLabels(['tier' => 'backend'])
->setLabels(['job-name' => 'pi']) // needs job-name: pi so that ->getPods() can work
->setContainers([$container])
->restartOnFailure();

Expand Down
2 changes: 1 addition & 1 deletion docs/kinds/DaemonSet.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ $container = K8s::container()

$pod = K8s::pod()
->setName('mysql')
->setLabels(['tier' => 'backend'])
->setLabels(['daemonset-name' => 'mysql']) // needs daemonset-name: mysql so that ->getPods() can work
->setContainers([$mysql]);

$ds = $this->cluster->daemonSet()
Expand Down
2 changes: 1 addition & 1 deletion docs/kinds/Deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ $container = K8s::container()

$pod = K8s::pod()
->setName('mysql')
->setLabels(['tier' => 'backend'])
->setLabels(['tier' => 'backend']) // needs deployment-name: mysql so that ->getPods() can work
->setContainers([$mysql]);

$dep = $cluster->deployment()
Expand Down
2 changes: 1 addition & 1 deletion docs/kinds/Job.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ $container = K8s::container()

$pod = K8s::pod()
->setName('pi')
->setLabels(['tier' => 'backend'])
->setLabels(['job-name' => 'pi']) // needs job-name: pi so that ->getPods() can work
->setContainers([$container])
->restartOnFailure();

Expand Down
10 changes: 0 additions & 10 deletions docs/kinds/Pod.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,6 @@ if ($pod->isRunning()) {
}
```

For [Job](Job.md) support, you may also check if the pod ran successfully:

```php
foreach ($job->getPods() as $pod) {
if ($pod->isSuccessful()) {
//
}
}
```

## Containers' Statuses

You can check the container statuses:
Expand Down
Loading