diff options
Diffstat (limited to 'pkg/resources/deployments.go')
-rw-r--r-- | pkg/resources/deployments.go | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/pkg/resources/deployments.go b/pkg/resources/deployments.go new file mode 100644 index 0000000..065d03b --- /dev/null +++ b/pkg/resources/deployments.go @@ -0,0 +1,184 @@ +package resources + +import ( + "context" + "io" + "math/rand" + "strconv" + "time" + + "github.com/docker/go-p9p" + v1 "k8s.io/api/apps/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + appsv1 "k8s.io/client-go/informers/apps/v1" + "sigs.k8s.io/yaml" +) + +type Deployments struct { + namespace string + deploymentInformer appsv1.DeploymentInformer + session Session + info *p9p.Dir + readdir *p9p.Readdir +} + +func NewDeployments(namespace string, session Session) *Deployments { + deploymentInformer := session.Informer().Apps().V1().Deployments() + return &Deployments{ + namespace: namespace, + deploymentInformer: deploymentInformer, + session: session, + } +} + +func (r *Deployments) Info() p9p.Dir { + if r.info != nil { + return *r.info + } + + dir := p9p.Dir{} + dir.Qid.Path = rand.Uint64() + dir.Qid.Version = 0 + + dir.Name = "deployments" + dir.Mode = 0664 + dir.Length = 0 + dir.AccessTime = time.Now() + dir.ModTime = time.Now() + dir.MUID = "none" + + uname, _ := r.session.GetAuth() + dir.UID = uname + dir.GID = uname + + dir.Qid.Type |= p9p.QTDIR + dir.Mode |= p9p.DMDIR + r.info = &dir + + return dir +} + +func (r *Deployments) Get(name string) (Ref, error) { + deployment, err := r.deploymentInformer.Lister().Deployments(r.namespace).Get(name) + if apierrors.IsNotFound(err) { + return nil, p9p.ErrNotfound + } + if err != nil { + return nil, err + } + + return NewDeploymentRef(deployment, r.session), nil +} + +func (r *Deployments) Read(ctx context.Context, p []byte, offset int64) (n int, err error) { + if r.readdir != nil { + return r.readdir.Read(ctx, p, offset) + } + + deployments, err := r.deploymentInformer.Lister().Deployments(r.namespace).List(labels.Everything()) + if err != nil { + return 0, err + } + + deploymentRefs := make([]Ref, 0, len(deployments)) + + for _, deployment := range deployments { + deployment := deployment + deploymentRefs = append(deploymentRefs, NewDeploymentRef(deployment, r.session)) + } + + r.readdir = p9p.NewReaddir(p9p.NewCodec(), func() (p9p.Dir, error) { + if len(deploymentRefs) == 0 { + return p9p.Dir{}, io.EOF + } + + deployment := deploymentRefs[0] + deploymentRefs = deploymentRefs[1:] + + return deployment.Info(), nil + }) + + n, err = r.readdir.Read(ctx, p, offset) + + return n, err +} + +type DeploymentRef struct { + deployment *v1.Deployment + session Session + info *p9p.Dir + readdir *p9p.Readdir + children map[string]Ref +} + +func NewDeploymentRef(deployment *v1.Deployment, session Session) *DeploymentRef { + y, _ := yaml.Marshal(deployment) + children := map[string]Ref{ + "data.yaml": &Static{ + name: "data.yaml", + content: y, + session: session, + }, + "scale": &Static{ + name: "scale", + content: []byte(strconv.Itoa(int(*deployment.Spec.Replicas))), + session: session, + }, + } + return &DeploymentRef{ + deployment: deployment, + session: session, + children: children, + } +} + +func (r *DeploymentRef) Info() p9p.Dir { + if r.info != nil { + return *r.info + } + + dir := p9p.Dir{} + dir.Qid.Path = rand.Uint64() + dir.Qid.Version = 0 + + dir.Name = r.deployment.Name + dir.Mode = 0664 + dir.Length = 0 + dir.AccessTime = r.deployment.CreationTimestamp.Time + dir.ModTime = r.deployment.CreationTimestamp.Time + dir.MUID = "none" + + uname, _ := r.session.GetAuth() + dir.UID = uname + dir.GID = uname + + dir.Qid.Type |= p9p.QTDIR + dir.Mode |= p9p.DMDIR + r.info = &dir + + return dir +} + +func (r *DeploymentRef) Get(name string) (Ref, error) { + ref, ok := r.children[name] + if !ok { + return nil, p9p.ErrNotfound + } + + return ref, nil +} + +func (r *DeploymentRef) Read(ctx context.Context, p []byte, offset int64) (int, error) { + if r.readdir != nil { + return r.readdir.Read(ctx, p, offset) + } + + dir := make([]p9p.Dir, 0, len(r.children)) + for _, child := range r.children { + dir = append(dir, child.Info()) + } + + r.readdir = p9p.NewFixedReaddir(p9p.NewCodec(), dir) + return r.readdir.Read(ctx, p, offset) +} |