Giter VIP home page Giter VIP logo

php-k8s's Introduction

PHP K8s

CI codecov StyleCI Maintainability License

Latest Stable Version Total Downloads Monthly Downloads

v1.24.12 K8s Version v1.25.8 K8s Version v1.26.3 K8s Version Client Capabilities Client Support Level

Control your Kubernetes clusters with this PHP-based Kubernetes client. It supports any form of authentication, the exec API, and it has an easy implementation for CRDs.

For Laravel projects, you might want to use renoki-co/laravel-php-k8s which eases the access for this particular case.

๐Ÿค Supporting

If you are using one or more Renoki Co. open-source packages in your production apps, in presentation demos, hobby projects, school projects or so, sponsor our work with Github Sponsors. ๐Ÿ“ฆ

๐Ÿ“ƒ Documentation

The entire documentation is available on Gitbook ๐ŸŒ

๐Ÿ› Testing

vendor/bin/phpunit

๐Ÿค Contributing

Please see CONTRIBUTING for details.

๐Ÿ”’ Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

๐ŸŽ‰ Credits

php-k8s's People

Contributors

0x0432 avatar bobab12 avatar cuppett avatar declum avatar dependabot-preview[bot] avatar dependabot[bot] avatar dunglas avatar georgeboot avatar laravel-shift avatar leo108 avatar mujibazizi avatar rennokki avatar siebeve avatar stefankonig avatar stylecibot avatar svenvanhees avatar theirritainer avatar tiagomichaelsousa avatar truechazza avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-k8s's Issues

[bug] Could not add .dockerconfigjson key inside Secret

Hello,

While trying to create a secret programmatically:

$cluster->secret()
    ->setName('regcred')
    ->addData('.dockerconfigjson', '{"auths":{"https://example.com/":{"username":"johnpdoe","password":"password","email":"[email protected]","auth":"qwertyuiopasdfghjklzxcvbnm=="}}}')
    ->create();

I'm facing the following error:

PHP Fatal error: Uncaught RenokiCo\PhpK8s\Exceptions\KubernetesAPIException: Client error: `POST https://wzb5w7.c1.gra7.k8s.ovh.net/api/v1/namespaces/default/secrets?pretty=1` resulted in a `400 Bad Request` response:
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {
    
  },
  "status": "Failure",
  "message": "Secret in version \"v1\" cannot be handled as a Secret: v1.Secret.Data: base64Codec: invalid input, error found in #10 byte of ...|      \"\": {\n        |..., bigger context ...|    \"apiVersion\": \"v1\",\n    \"data\": {\n        \"\": {\n            \"dockerconfigjson\": \"eyJhdXRocyI6eyJ|...",
  "reason": "BadRequest",
  "code": 400
}

This is due to the usage of a .dockerconfigjson key in the K8sSecret::addData method. The key is then transformed into a data..dockerconfigjson key wrongly interpreted as a 3-level data path in Illuminate\Support\Array::set method.

Is there a simple workaround for this?

vierbergenlars/php-semver

Hi,

is it possible to change the dependency of vierbergenlars/php-semver to a stable release instead of dev-master?

Container Argument #1 ($attributes) must be of type array

When I try create new deployment I got this error

RenokiCo\PhpK8s\K8s::container(): Argument #1 ($attributes) must be of type array, RenokiCo\PhpK8s\KubernetesCluster given, called in /home/rispy/Dokumenty/api-panel/vendor/renoki-co/php-k8s/src/KubernetesCluster.php on line 392

Here is code that I'm trying to run (It's from docs)

    $container = K8s::container()
        ->setName('mysql')
        ->setImage('mysql', '5.7')
        ->setPorts([
            ['name' => 'mysql', 'protocol' => 'TCP', 'containerPort' => 3306],
        ]);

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

    $dep = K8s::getCluster()
        ->deployment()
        ->setName('mysql')
        ->setSelectors(['matchLabels' => ['tier' => 'backend']])
        ->setReplicas(1)
        ->setTemplate($pod)
        ->create();
}    

[PHP 7.2] Issue with multiple traits being imported

The problem

We run into the following problem when running a simple test script:

Fatal error: Trait method setAttribute has not been applied, because there are collisions with other trait methods on RenokiCo\PhpK8s\Traits\RunsClusterOperations in /usr/share/php/vendor/renoki-co/php-k8s/src/Traits/RunsClusterOperations.php on line 20

Our setup

Watch out! We use an older version of php-ks8: we have installed version 3.0.0 because that was the highest version number that works with PHP version 7.2.24. We installed php-k8s through composer.

Example script

The problem occured with the following (simple I think) script:

/**
 *  Include the Composer based code
 */
require_once('vendor/autoload.php');

/**
 *  Enable namespace
 */
use RenokiCo\PhpK8s\KubernetesCluster;

/**
 *  Get access to our API server
 *  @var KubernetesCluster
 */
$cluster = KubernetesCluster::fromUrl('https://whatever-hostname:8443');

/**
 *  Run a random method
 */
$cluster->getAllNamespaces();

Find resources in all namespaces

Is it possible to find resources located in all namespaces? For instance, all ingresses in every namespace? The Kubernetes API has this feature, but it looks like the library automatically filters resources with the default namespace of the current context.

Ability to apply labels and taints to Node

First off, thanks for creating this package, it makes management of my cluster infinitely simpler.

I'm trying to use the package to apply labels and taints to my Node. I can't find any reference to taints in the codebase so I assume that they're not supported, however when I try to apply a label to my node it simply doesn't show up - no error.

Am I missing something?

$k8sNode = $cluster->getNodeByName($nodeHostname);
$k8sNode->setLabels(
    [
        'nodeUuid' => 'test',
    ]
);

Error messages are truncated

Hello,

when using php-k8s library, and when issue on cluster happens - it is not possible to catch whole error message, like here:

Client error: GET https://kubernetes.default.svc/apis/apps/v1/deployments?pretty=1 resulted in a 403 Forbidden response:\n{\n "kind": "Status",\n "apiVersion": "v1",\n "metadata": {\n \n },\n "status": "Failure",\n "message": "deployments.a (truncated...)\n

It looks like it might be something related to Gozzle invocation here:
https://github.com/renoki-co/php-k8s/blob/master/src/Traits/Cluster/MakesHttpCalls.php#L89

Applying `HasLabels` trait to all children of `K8sResource`

Hi @rennokki โ€”ย first of all; you've got a great project going on here! I really like the work you've done so far.

Is there a specific reason you have not added the HasLabels trait to all classes/resources in https://github.com/renoki-co/php-k8s/blob/master/src/Kinds/ ? All of these resources support Labels, thus adding the HasLabels trait to the https://github.com/renoki-co/php-k8s/blob/master/src/Kinds/K8sResource.php file would make the usage consistent.

If you don't have any objections, I'd be more than happy to create a PR for this.

[bug] Pod exec/attach fails silently in case of errors

When calling pod exec https://php-k8s.renoki.org/resources/workloads/pod#pod-exec with KubernetesCluster::fromKubeConfigYamlFile it works fine.
But when authenticating with KubernetesCluster::inClusterConfiguration() it does not work. No errors. Just no connection established and therefore no messages returned.
All other api endpoints works fine with in-cluster authentication.

The pod service account has the following Cluster Role rules:

rules:
  - apiGroups: ["", "batch", "cert-manager.io", "extensions", "apps", "networking.k8s.io"]
    resources:
      - pods
      - jobs
      - pods/log
      - pods/exec
      - pods/attach
      - certificates
      - cronjobs
      - persistentvolumes
      - persistentvolumeclaims
      - deployments
      - services
      - ingresses
      - namespaces
    verbs:
      - get
      - list
      - create
      - delete
      - patch

As far as I understand the pods/exec and get verb should be sufficient.
I hope anyone can help me figure this one out.. Thank you. Can anyone else establish a web socket connection when using in-cluster authentication?

How to set Service type to NodePort?

Hi, I was trying to create a service and I tried with ->setType('NodePort') but it's not working and I get to create a service with the default type which is "ClusterIP", May I know what is the correct way of setting the type of a service?
image

Kind:Issuer

Method: $cluster->fromTemplatedYamlFile just skipping kubernetes resource Issuer.
I didn't find information about Issuer in your documentation.
Would be great if you add possibility to create this resource type.

delete() does not remove resources imported from YAML

I can create and update resources with

$x = $cluster->fromYaml($code);
$x->createOrUpdate();

But when doing

$x = $cluster->fromYaml($code);
$x->delete();

with the same $code the resources do not get deleted. Deleting works when I do
kubectl delete -f code.yaml
having the content of $code in the code.yaml.

Support for SelfSubjectAccessReview and SelfSubjectRulesReview

Hello,

I am trying to build requests for the resource SelfSubjectAccessReview and SelfSubjectRulesReview but it looks like php-k8s does not support this out of the box.
Is it possible to execute this request by using php-k8s somehow or support for it needs to be developed?

Feature Request: CRD Support

Hi,
It would be nice to be able to support CRDs such as those provided by cert-manager and Itsio in a generic way. Alternately a documented way to create a package that registers those CRDs for use with this library.

Expose response received in ChecksClusterVersion#loadClusterVersion

Expose response received in ChecksClusterVersion#loadClusterVersion, to read the Kubernetes Version Response (/api/version)

$ kubectl version -o json

{
...
"serverVersion": {
"major": "1",
"minor": "22",
"gitVersion": "v1.22.3",
"gitCommit": "c92036820499fedefec0f847e2054d824aea6cd1",
"gitTreeState": "clean",
"buildDate": "2021-10-27T18:35:25Z",
"goVersion": "go1.16.9",
"compiler": "gc",
"platform": "linux/amd64"
}
}

[enhancement] exec shell in pod and interact with it

I'd love to integrate php-k8s in a Symfony CLI and automatically exec within a pod with bash and interact with bash.

Currently there seems no way to accomplish this, as the websocket is automatically closed by php-k8s.

Support for envFrom for containers

https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/pods/pod-single-configmap-env-variable.yaml

Hi there. If I create a configMap, I can load the env from it, without being explicit on keys.

This makes life very easy for an isolated application with multiple services to load all environments from one single configmap.

Intention is to have a generic "Container" builder to which I tell it's configmap for env.

You already support creation of configmaps, so probably this would be only an addition to support env from configmaps.

PS: Multe salutari.

Enabeling TLS on k8s ingress

Is there any way we can add tls hosts and a secretName to the ingress definition? Looked trough the code but could not find any way to set the tls hosts attribute, while also specifying the secretName.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-example-ingress
spec:
  tls:
  - hosts:
      - https-example.foo.com
    secretName: testsecret-tls
  rules:
  - host: https-example.foo.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: service1
            port:
              number: 80

Maybe there could be something like this?

$ing = $this->cluster->ingress()
            ->setName('nginx')
            ->setLabels(['tier' => 'backend'])
            ->setAnnotations(['nginx/ann' => 'yes'])
            ->setTls([
                    'hosts' => [
                        'api.example.com',
                        'test.example.com',
                    ],
                    'secretName' => 'test'
                ])

[bug] Metadata resourceVersion is not send on update of custom resource

On php-K8S version 3.1.3, with a custom resource definied like this ::

<?php

namespace App\Service\Core\Kubernetes;

use RenokiCo\PhpK8s\Contracts\InteractsWithK8sCluster;
use RenokiCo\PhpK8s\Kinds\K8sResource;
use RenokiCo\PhpK8s\Traits\Resource\HasAccessModes;
use RenokiCo\PhpK8s\Traits\Resource\HasAttributes;
use RenokiCo\PhpK8s\Traits\Resource\HasEvents;
use RenokiCo\PhpK8s\Traits\Resource\HasSelector;
use RenokiCo\PhpK8s\Traits\Resource\HasSpec;
use RenokiCo\PhpK8s\Traits\Resource\HasStatus;
use RenokiCo\PhpK8s\Traits\Resource\HasStatusConditions;
use RenokiCo\PhpK8s\Traits\Resource\HasTemplate;

class SealedSecretKind extends K8sResource implements InteractsWithK8sCluster
{
    use HasSelector;
    use HasSpec;
    use HasStatus;
    use HasStatusConditions;
    use HasTemplate;


    /**
     * The resource Kind parameter.
     *
     * @var string|null
     */
    protected static $kind = 'SealedSecret';

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

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

Registered this way :

SealedSecretKind::register('sealedSecret');

On this call :

            $manifest = $cluster->fromYaml($yamlManifest);
            $response = $manifest->createOrUpdate();

We have a 422 Unprocessable Entity error, because of metadata.resourceVersion attribute missing for an update

if I add this L227 of RunsClusterOperations file this is working:

$this->attributes['metadata']['resourceVersion'] = $this->original['metadata']['resourceVersion'];

This is a very dirty fix... and i have no idea how fix this properly.

Feature Request: Allow secret refs as env's

It would be great if we could use secrets to populate env's.

- name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: password

Was thinking we could add 2 new functions to the Container kind. While also editing the ->setEnv() function to allow for a valueFrom key to be set.

I tried the following, but it does not work yet...

  /**
     * Add an env variable by using a secret reference to the container.
     *
     * @param  string  $name
     * @param  string  $refName
     * @param  string  $refKey
     * @return $this
     */
    public function addSecretKeyRef(string $name, string $refName, string $refKey)
    {
        return $this->addToAttribute('env', [
            'name' => $name,
            'valueFrom' => [
                'secretKeyRef' => [
                    'name' => $refName,
                    'key' => $refKey
                ]
            ]
        ]);
    }

Any Ideas/suggestions?

p.s. Great work on the package overall !

Kubernetes References:
https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core

Probes with empty header causes a bad request.

Container probes that don't have any headers supplied with result in a bad request because empty arrays like this: [] are replaced with {}.

Solution is to removed the httpHeaders key when the length of the headers array is < 0.

Will make a pull request shortly.

Can nont create namespace

$cluster =new KubernetesCluster('http://127.0.0.1:8001');
 $ns = $cluster->namespace()->setName("$name")->create();

and I have this error
RenokiCo\PhpK8s\Exceptions\KubernetesAPIException: Client error: POST http://127.0.0.1:8001/api/v1/namespaces?pretty=1 resulted in a 422 Unprocessable Entity response: { "kind": "Status", "apiVersion": "v1", "metadata": { }, "status": "Failure", "message": "Namespace "T (truncated...) in

[enhancement] Mocking during testing

I would love to test our code that implements this package. However, I can't seem to find an easy way to mock this package cq the underlying HTTP client.

What approach are others using?

Kubernetes Job not working as expected

I am working with the example given in the unit test here

         $pi = K8s::container()
            ->setName('pi')
            ->setImage('perl')
            ->setCommand(['perl',  '-Mbignum=bpi', '-wle', 'print bpi(2000)']);

        $pod = $this->cluster->pod()
            ->setName('perl')
            ->setContainers([$pi])
            ->restartOnFailure()
            ->neverRestart();

        $job = $this->cluster->job()
            ->setName('pi')
            ->setLabels(['tier' => 'backend'])
            ->setAnnotations(['perl/annotation' => 'yes'])
            ->setTTL(3600)
            ->setTemplate($pod);

Calling json_encode($job->toJsonPayload()) Outputs

{
    "apiVersion": "batch/v1",
    "kind": "Job",
    "metadata": {
        "name": "pi",
        "labels": {
            "tier": "backend"
        },
        "annotations": {
            "perl/annotation": "yes"
        },
        "namespace": "default"
    },
    "spec": {
        "ttlSecondsAfterFinished": 3600,
        "template": {
            "apiVersion": "v1",
            "kind": "Pod",
            "metadata": {
                "name": "perl",
                "namespace": "default"
            },
            "spec": {
                "containers": [
                    {
                        "name": "pi",
                        "image": "perl:latest",
                        "command": [
                            "perl",
                            "-Mbignum=bpi",
                            "-wle",
                            "print bpi(2000)"
                        ]
                    }
                ],
                "restartPolicy": "Never"
            }
        }
    }
}

Then finally calling $job = $job->createOrUpdate(); returns this error

{
	"kind": "Status",
	"apiVersion": "v1",
	"metadata": [],
	"status": "Failure",
	"message": "Job.batch \"pi\" is invalid: [spec.selector: Required value, spec.template.metadata.labels: Invalid value: map[string]string(nil): `selector` does not match template `labels`, spec.selector: Invalid value: \"null\": field is immutable, spec.template: Invalid value: core.PodTemplateSpec{ObjectMeta:v1.ObjectMeta{Name:\"perl\", GenerateName:\"\", Namespace:\"default\", SelfLink:\"\", UID:\"\", ResourceVersion:\"\", Generation:0, CreationTimestamp:v1.Time{Time:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}}, DeletionTimestamp:(*v1.Time)(nil), DeletionGracePeriodSeconds:(*int64)(nil), Labels:map[string]string(nil), Annotations:map[string]string(nil), OwnerReferences:[]v1.OwnerReference(nil), Finalizers:[]string(nil), ClusterName:\"\", ManagedFields:[]v1.ManagedFieldsEntry(nil)}, Spec:core.PodSpec{Volumes:[]core.Volume(nil), InitContainers:[]core.Container(nil), Containers:[]core.Container{core.Container{Name:\"pi\", Image:\"perl:latest\", Command:[]string{\"perl\", \"-Mbignum=bpi\", \"-wle\", \"print bpi(2000)\"}, Args:[]string(nil), WorkingDir:\"\", Ports:[]core.ContainerPort(nil), EnvFrom:[]core.EnvFromSource(nil), Env:[]core.EnvVar(nil), Resources:core.ResourceRequirements{Limits:core.ResourceList(nil), Requests:core.ResourceList(nil)}, VolumeMounts:[]core.VolumeMount(nil), VolumeDevices:[]core.VolumeDevice(nil), LivenessProbe:(*core.Probe)(nil), ReadinessProbe:(*core.Probe)(nil), StartupProbe:(*core.Probe)(nil), Lifecycle:(*core.Lifecycle)(nil), TerminationMessagePath:\"\/dev\/termination-log\", TerminationMessagePolicy:\"File\", ImagePullPolicy:\"Always\", SecurityContext:(*core.SecurityContext)(nil), Stdin:false, StdinOnce:false, TTY:false}}, EphemeralContainers:[]core.EphemeralContainer(nil), RestartPolicy:\"Never\", TerminationGracePeriodSeconds:(*int64)(0xc0076c8840), ActiveDeadlineSeconds:(*int64)(nil), DNSPolicy:\"ClusterFirst\", NodeSelector:map[string]string(nil), ServiceAccountName:\"\", AutomountServiceAccountToken:(*bool)(nil), NodeName:\"\", SecurityContext:(*core.PodSecurityContext)(0xc006528800), ImagePullSecrets:[]core.LocalObjectReference(nil), Hostname:\"\", Subdomain:\"\", SetHostnameAsFQDN:(*bool)(nil), Affinity:(*core.Affinity)(nil), SchedulerName:\"default-scheduler\", Tolerations:[]core.Toleration(nil), HostAliases:[]core.HostAlias(nil), PriorityClassName:\"\", Priority:(*int32)(nil), PreemptionPolicy:(*core.PreemptionPolicy)(nil), DNSConfig:(*core.PodDNSConfig)(nil), ReadinessGates:[]core.PodReadinessGate(nil), RuntimeClassName:(*string)(nil), Overhead:core.ResourceList(nil), EnableServiceLinks:(*bool)(nil), TopologySpreadConstraints:[]core.TopologySpreadConstraint(nil)}}: field is immutable]",
	"reason": "Invalid",
	"details": {
		"name": "pi",
		"group": "batch",
		"kind": "Job",
		"causes": [{
			"reason": "FieldValueRequired",
			"message": "Required value",
			"field": "spec.selector"
		}, {
			"reason": "FieldValueInvalid",
			"message": "Invalid value: map[string]string(nil): `selector` does not match template `labels`",
			"field": "spec.template.metadata.labels"
		}, {
			"reason": "FieldValueRequired",
			"message": "Required value",
			"field": "spec.selector"
		}, {
			"reason": "FieldValueInvalid",
			"message": "Invalid value: map[string]string(nil): `selector` does not match template `labels`",
			"field": "spec.template.metadata.labels"
		}, {
			"reason": "FieldValueInvalid",
			"message": "Invalid value: \"null\": field is immutable",
			"field": "spec.selector"
		}, {
			"reason": "FieldValueInvalid",
			"message": "Invalid value: core.PodTemplateSpec{ObjectMeta:v1.ObjectMeta{Name:\"perl\", GenerateName:\"\", Namespace:\"default\", SelfLink:\"\", UID:\"\", ResourceVersion:\"\", Generation:0, CreationTimestamp:v1.Time{Time:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}}, DeletionTimestamp:(*v1.Time)(nil), DeletionGracePeriodSeconds:(*int64)(nil), Labels:map[string]string(nil), Annotations:map[string]string(nil), OwnerReferences:[]v1.OwnerReference(nil), Finalizers:[]string(nil), ClusterName:\"\", ManagedFields:[]v1.ManagedFieldsEntry(nil)}, Spec:core.PodSpec{Volumes:[]core.Volume(nil), InitContainers:[]core.Container(nil), Containers:[]core.Container{core.Container{Name:\"pi\", Image:\"perl:latest\", Command:[]string{\"perl\", \"-Mbignum=bpi\", \"-wle\", \"print bpi(2000)\"}, Args:[]string(nil), WorkingDir:\"\", Ports:[]core.ContainerPort(nil), EnvFrom:[]core.EnvFromSource(nil), Env:[]core.EnvVar(nil), Resources:core.ResourceRequirements{Limits:core.ResourceList(nil), Requests:core.ResourceList(nil)}, VolumeMounts:[]core.VolumeMount(nil), VolumeDevices:[]core.VolumeDevice(nil), LivenessProbe:(*core.Probe)(nil), ReadinessProbe:(*core.Probe)(nil), StartupProbe:(*core.Probe)(nil), Lifecycle:(*core.Lifecycle)(nil), TerminationMessagePath:\"\/dev\/termination-log\", TerminationMessagePolicy:\"File\", ImagePullPolicy:\"Always\", SecurityContext:(*core.SecurityContext)(nil), Stdin:false, StdinOnce:false, TTY:false}}, EphemeralContainers:[]core.EphemeralContainer(nil), RestartPolicy:\"Never\", TerminationGracePeriodSeconds:(*int64)(0xc0076c8840), ActiveDeadlineSeconds:(*int64)(nil), DNSPolicy:\"ClusterFirst\", NodeSelector:map[string]string(nil), ServiceAccountName:\"\", AutomountServiceAccountToken:(*bool)(nil), NodeName:\"\", SecurityContext:(*core.PodSecurityContext)(0xc006528800), ImagePullSecrets:[]core.LocalObjectReference(nil), Hostname:\"\", Subdomain:\"\", SetHostnameAsFQDN:(*bool)(nil), Affinity:(*core.Affinity)(nil), SchedulerName:\"default-scheduler\", Tolerations:[]core.Toleration(nil), HostAliases:[]core.HostAlias(nil), PriorityClassName:\"\", Priority:(*int32)(nil), PreemptionPolicy:(*core.PreemptionPolicy)(nil), DNSConfig:(*core.PodDNSConfig)(nil), ReadinessGates:[]core.PodReadinessGate(nil), RuntimeClassName:(*string)(nil), Overhead:core.ResourceList(nil), EnableServiceLinks:(*bool)(nil), TopologySpreadConstraints:[]core.TopologySpreadConstraint(nil)}}: field is immutable",
			"field": "spec.template"
		}]
	},
	"code": 422
}

What could I be doing wrong here?

Initializing k8s object gives null

Hi, I would like to ask why is it returning null object here, I was trying to get all services which I have verified it with Postman and it works perfectly fine but when I tried to use the PHP client here, it show me an error that the getAllServices() function run on null. The code below is how initialize the k8s object. Did I miss out anything?

`$cluster = new KubernetesCluster("https://my-k8s-ip", my-k8s-port);
$token = "my-service-account-token";
$cluster->withoutSSLChecks()->withToken($token);

function list_all_services() {
return json_encode($cluster);
// $services = $cluster->getAllServices('training-lab');
}`

Correct way mapping pvc to volume

Is this the correct way to mount pvc to volume and add it to the pod?

$data = K8s::volume($cluster->persistentVolumeClaim()->whereNamespace($hosting->namespace_details->namespace)->getByName($hosting->deployment_details->deployment_name.'-hosting')->ToArray());

$pod = K8s::pod()
            ->setName('namepod')
            ->addVolumes([$data])

Becouse for now i get a error that the volume name is required.

Call to undefined function RenokiCo\PhpK8s\yaml_parse()

When calling fromYamlFile() it raises

Call to undefined function RenokiCo\PhpK8s\yaml_parse()

I could fix it by changing yaml_parse($yaml, -1) to \yaml_parse($yaml, -1) in line 30 in K8s.php but I don't know if this will break something else...

cURL ssl verification failed

First of all thank you for this module. Very helpful.

The question is how to skip SSL verification for cURL in this module?
I'm using:

    $cluster = KubernetesCluster::fromKubeConfigVariable('KUBECONFIG_PATH');
    $ns = $cluster->getAllNamespaces();

Error:

GuzzleHttp\Exception\RequestException
cURL error 1: (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for /api/v1/namespaces?pretty=1

Autoscaling

Hey,

is autoscaling for deployments supported? I am not sure if it is the K8sScale. Thank you in advance.

watch() takes 60s to access object method and only runs once

Hi!

I'm hoping to write an operator in laravel but I'm finding that the watch method isn't working as expected.

Taking the following quick test command:

    public function __construct()
    {
        parent::__construct();
        $this->cluster = K8s::getCluster();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    { 
        $start = time();
        $this->info('Getting name. Time: ' . $start);
        $this->info($this->cluster->pod()->whereName('speaker-nqd27')->whereNamespace('metallb-system')->getName());
        $this->info('Took: ' . time() - $start);

        $start = time();
        $this->info('Getting name in watch. Time: ' . $start);
        $this->cluster->pod()->whereName('speaker-nqd27')->whereNamespace('metallb-system')->watch(function ($type, $pod) use ($start) {
            $this->info($pod->getName());
            $this->info('Took: ' . time() - $start);
            $start = time();
        });

        $this->info('Loop done');
    }

I get the following output:

> php artisan test:watch
Getting name. Time: 1668994421
speaker-nqd27
Took: 0
Getting name in watch. Time: 1668994421
speaker-nqd27
Took: 60
Loop done

As you can see the watch function both takes 60s to access the name (and this is consistent every time) and only runs once, though it does take another 60s after the Took: 60 line is outputted for the Loop done line to be output.

This occurs both against a GKE cluster running 1.23 and a local k3s cluster running 1.25 using both the kubeconfig connection and a bearer token connection. It's also not just pods affected but other resources seem affected too.

Deployment templates cast to `K8sPod` should not use "default" namespace

We primarily provision our infrastructure using Terraform, however in large configurations it takes a long time to plan and apply changes; particularly as the most frequent changes are to container tags.

I've been experimenting with this package as part of a workflow that will first patch all of our deployment within a cluster, and then start a Terraform run to validate everything has been updated correctly.

I've noticed that we started seeing that the "default" namespace had been added to spec.template.metadata.namespace; which was not there before. The deployment itself belongs to a different namespace.

As far as I'm aware (I haven't tested), Kubernetes won't create the pods in a namespace that's different to the deployment, and therefore this property is redundant. This is always causing the deployments to be replaced in our "validation" Terraform run, which negates manipulating the deployments directly in the first place.

I've managed to work around it by manually removing the namespace key manually before updating it:

$templateArray = Arr::except($template->toArray(), [
    'metadata.namespace',
]);

$deployment->setTemplate($templateArray);

However I feel like it would be nice to not have to worry about this, or for it to catch others out in future.

I'd be happy to submit a PR with some guidance on the preferred approach. Couple of options I can think of:

  1. Create a new K8sPodTemplate resource that extends from K8sPod, with protected static $namespaceable = false;
    • This would inherit all of the methods from K8sPod
  2. Add K8sPodTemplate, which is the parent of K8sPod and doesn't include any of the methods that are only pertinent to a "live" resource.

Thanks

getPods not work

Hello,
$dep = $cluster->getDeploymentByName('whoami');
var_dump($dep->getPods());
Result this : object(RenokiCo\PhpK8s\ResourcesList)#939 (1) { ["items":protected]=> array(0) { } }
I have 4 pods in whoami deployment how i can get all pod of deployment ?
Can you help me ?
I can scale and get the number of replicas maybe i can get the pod info of deployment

Support for laravel 9

I think the below packages need to be updated to support laravel 9.

    "illuminate/macroable": "^7.30|^8.40",
    "illuminate/support": "^7.30|^8.40",

Getting below error on upgrade
- Only one of these can be installed: illuminate/macroable[dev-master, v8.0.0, ..., 8.x-dev, v9.0.0-beta.1, ..., 9.x-dev], laravel/framework[v9.0.0-beta.1, ..., 9.x-dev]. laravel/framework replaces illuminate/macroable and thus cannot coexist with it.
- renoki-co/php-k8s[3.5.1, ..., 3.5.2] require illuminate/macroable ^7.30|^8.40 -> satisfiable by illuminate/macroable[v8.40.0, ..., 8.x-dev].
- Root composer.json requires renoki-co/php-k8s ^3.5 -> satisfiable by renoki-co/php-k8s[3.5.0, 3.5.1, 3.5.2].
- Root composer.json requires laravel/framework ^9.0 -> satisfiable by laravel/framework[v9.0.0-beta.1, ..., 9.x-dev].`

Filter by label?

I apologize if i'm misunderstanding the docs on this, but I'm struggling to find a way to filter pods by a label. I'm currently doing:

$cluster->pod()->whereNamespace('mynamespace')->whereLabel([key' => 'value'])->get();

... to no avail. All pods are returned. Is this possible?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.