Skip to content

Commit

Permalink
add resource list
Browse files Browse the repository at this point in the history
  • Loading branch information
datewu committed Sep 9, 2023
1 parent 2e6c7e5 commit 5291245
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 25 deletions.
49 changes: 38 additions & 11 deletions cmd/api/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ func (k k8sHandler) listBio(w http.ResponseWriter, r *http.Request) {
data := handler.Envelope{}
switch kind {
case "deploy":
ls, err := k8s.ListDeploy(ns)
ls, err := k8s.ListBios(ns)
if err != nil {
handler.ServerErr(w, err)
return
}
data["developments"] = ls
case "sts":
ls, err := k8s.ListSts(ns)
ls, err := k8s.ListStsBios(ns)
if err != nil {
handler.ServerErr(w, err)
return
Expand Down Expand Up @@ -288,18 +288,21 @@ type myHandler struct {

func (m *myHandler) middlerware(next http.HandlerFunc) http.HandlerFunc {
middle := func(w http.ResponseWriter, r *http.Request) {
user := handler.ReadQuery(r, "user", "")
if user == "" {
handler.BadRequestMsg(w, "missing user")
return
}
m.user = user
co, err := r.Cookie("access_token")
if err != nil {
handler.BadRequestMsg(w, "missing access_token cookie")
return
}
m.token = co.Value
t := co.Value
gh := ghLoginHandler{}
user, err := gh.userInfo(t)
if err != nil {
handler.ClearSimpleCookie(w, "access_token")
handler.ServerErr(w, err)
return
}
m.user = user.Login
m.token = t
next(w, r)
}
return middle
Expand All @@ -311,11 +314,35 @@ func (m *myHandler) profile(w http.ResponseWriter, r *http.Request) {
}

func (m *myHandler) deploys(w http.ResponseWriter, r *http.Request) {
view := front.TableView{TODO: "todo deployments table"}
ns := handler.ReadQuery(r, "ns", "wu")
view := &front.TableView{
Description: "deployments by " + m.user,
Namespace: ns,
Kind: "deploy",
}
label := fmt.Sprintf("image-user=%s", m.user)
ds, err := k8s.ListDeployWithLabels(ns, label)
if err != nil {
handler.ServerErr(w, err)
return
}
view.AddDeploys(ds)
view.Render(w)
}

func (m *myHandler) sts(w http.ResponseWriter, r *http.Request) {
view := front.TableView{TODO: "todo statefulset table"}
ns := handler.ReadQuery(r, "ns", "wu")
view := &front.TableView{
Description: "statefulsets by " + m.user,
Namespace: ns,
Kind: "sts",
}
label := fmt.Sprintf("image-user=%s", m.user)
ss, err := k8s.ListStsWithLabels(ns, label)
if err != nil {
handler.ServerErr(w, err)
return
}
view.AddSts(ss)
view.Render(w)
}
8 changes: 4 additions & 4 deletions front/index-layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@
<div class="app">
{i{ if .User }i}
<div hx-target="#content">
<a href="/my/profile?user={i{ .User }i}"> {i{ .User }i} </a>
<a href="/my/deploys?user={i{ .User }i}">Deploys</a>
<a href="/my/sts?user=?user={i{ .User }i}">Statefulsets</a>
<a href="/my/profile"> {i{ .User }i} </a>
<a href="/my/deploys">Deploys</a>
<a href="/my/sts">Statefulsets</a>
</div>
{i{ else }i}
<div id="profile" hx-get="/login/github/init" hx-swap="outerHTML" hx-trigger="load"></div>
{i{ end }i}
<div hx-disable="true">
<div hx-disable>
<a href="https://github.com/datewu/set-img" target="_blank">
<img src="/static/fav.svg" class="logo" alt="logo" />
</a>
Expand Down
33 changes: 31 additions & 2 deletions front/table.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,33 @@
<table>
{{ .TODO }}

<tr>
<th>{{ or .Description "deployments" }}</th>
</tr>
<tr>
<th>Name</th>
<th>Replicas</th>
<th>Age</th>
<th>Image</th>
<th>Edit image Tag</th>
</tr>
{{ $ns := .Namespace}}
{{ $kind := .Kind}}
{{ range .Data}}
<tr>
{{ $rowspan := len .Containers }}
<td rowspan="{{ $rowspan }}">{{ .Name }}</td>
<td rowspan="{{ $rowspan }}">{{ .Replicas }}</td>
<td rowspan="{{ $rowspan }}">{{ .Age }}</td>
{{ $name := .Name}}
{{ range .Containers }}
<form hx-put="/my/update/{{ $ns }}/{{ $kind }}/{{ $name }}?container={{ .Name }}">
<td> <input name="image" type="text" value="{{ .Image }}" /> </td>
<td> <button type="submit"> update </button> </td>
</form>
{{ end }}
</tr>
{{ else }}
<tr>
<td>no data</td>
{{ end}}
</tr>
</table>
71 changes: 70 additions & 1 deletion front/table.tpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"html/template"
"io"

apps "k8s.io/api/apps/v1"

_ "embed"
)

Expand All @@ -14,7 +16,74 @@ var tableTpl = template.Must(template.New("table").Parse(tableHtml))

// TableView ...
type TableView struct {
TODO string
Description string
Namespace string
Kind string
Data []Resource
}

// AddDeploys ...
func (t *TableView) AddDeploys(ds []apps.Deployment) {
var res []Resource
for _, d := range ds {
res = append(res, *newDeployResource(&d))
}
t.Data = res
}

// AddSts ...
func (t *TableView) AddSts(ss []apps.StatefulSet) {
var res []Resource
for _, s := range ss {
res = append(res, *newStsResource(&s))
}
t.Data = res
}

type Resource struct {
Containers []Container
Name string
Replicas int
Age string
}

func newDeployResource(d *apps.Deployment) *Resource {
res := &Resource{
Name: d.Name,
Replicas: int(*d.Spec.Replicas),
Age: d.ObjectMeta.CreationTimestamp.Time.String(),
}
containes := d.Spec.Template.Spec.Containers
cs := make([]Container, len(containes))
for i, c := range containes {
cs[i] = Container{
Name: c.Name,
Image: c.Image,
}
}
res.Containers = cs
return res
}
func newStsResource(s *apps.StatefulSet) *Resource {
res := &Resource{
Name: s.Name,
Replicas: int(*s.Spec.Replicas),
Age: s.ObjectMeta.CreationTimestamp.Time.String(),
}
containes := s.Spec.Template.Spec.Containers
cs := make([]Container, len(containes))
for i, c := range containes {
cs[i] = Container{
Name: c.Name,
Image: c.Image,
}
}
res.Containers = cs
return res
}

type Container struct {
Name, Image string
}

func (t TableView) Render(w io.Writer) {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/datewu/set-img
go 1.21.1

require (
github.com/datewu/gtea v0.5.3
github.com/datewu/gtea v0.5.5
k8s.io/api v0.28.1
k8s.io/apimachinery v0.28.1
k8s.io/client-go v0.28.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/datewu/gtea v0.5.3 h1:EYOmhbcXSrwRBgkM1A3xhCKA9WglbrvTrewd8Junh2k=
github.com/datewu/gtea v0.5.3/go.mod h1:9v9nj7WglTrkKxC2E6eOAyGxa3FUCGf3owT/HM3Jv80=
github.com/datewu/gtea v0.5.5 h1:P9GV1w3dO6ImbJJRMuhf0B87DIz72uzqlq29JUGI36A=
github.com/datewu/gtea v0.5.5/go.mod h1:8Gk1F47xW8SD+NGHoxtNp2HNCTL3agQGxoIX+EzFEhA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down
30 changes: 28 additions & 2 deletions internal/k8s/deploy_crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,19 @@ func GetDBio(ns, name string) (*Bio, error) {
return newDBio(d), nil
}

// ListDeploy list deployment bios
func ListDeploy(ns string) ([]*Bio, error) {
// ListDeployWithLabels list deployment by label
func ListDeployWithLabels(ns, label string) ([]apps_v1.Deployment, error) {
ctx := context.Background()
opts := v1.ListOptions{LabelSelector: label}
deploys, err := classicalClientSet.AppsV1().Deployments(ns).List(ctx, opts)
if err != nil {
return nil, err
}
return deploys.Items, nil
}

// ListBios list deployment bios
func ListBios(ns string) ([]*Bio, error) {
ctx := context.Background()
opts := v1.ListOptions{}
deploys, err := classicalClientSet.AppsV1().Deployments(ns).List(ctx, opts)
Expand All @@ -54,15 +65,30 @@ func ListDeploy(ns string) ([]*Bio, error) {
return res, nil
}

// SetDeployImgWithLabel ...
func SetDeployImgWithLabel(id *ContainerPath, label ...string) error {
return setDeployImg(id, label...)
}

// SetDeployImg ...
func SetDeployImg(id *ContainerPath) error {
return setDeployImg(id)
}

func setDeployImg(id *ContainerPath, labels ...string) error {
ctx := context.Background()
opts := v1.GetOptions{}
d, err := classicalClientSet.AppsV1().Deployments(id.Ns).Get(ctx, id.Name, opts)
if err != nil {
jsonlog.Err(err, map[string]any{"name": id.Name, "msg": "get deploy failed"})
return err
}
if labels != nil {
ls := d.GetLabels()
if err = checkLabels(ls, labels); err != nil {
return err
}
}
cpy := d.DeepCopy()
found := false
for i, c := range cpy.Spec.Template.Spec.Containers {
Expand Down
18 changes: 18 additions & 0 deletions internal/k8s/k8s.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package k8s

import (
"errors"
"strings"
)

// Bio wrap container bio
type Bio struct {
Name string `json:"name"`
Expand All @@ -21,3 +26,16 @@ type ContainerPath struct {
CName string `json:"container_name" binding:"required"`
Img string `json:"img" binding:"required"`
}

func checkLabels(table map[string]string, labels []string) error {
for _, l := range labels {
kv := strings.Split(l, "=")
if len(kv) != 2 {
return errors.New("invalid label selector")
}
if kv[1] != table[kv[0]] {
return errors.New("filter out by labels: " + l)
}
}
return nil
}
30 changes: 28 additions & 2 deletions internal/k8s/sts_crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,19 @@ func GetSBio(ns, name string) (*Bio, error) {
return newSBio(s), nil
}

// ListSts list all statefulset bio in :ns
func ListSts(ns string) ([]*Bio, error) {
// ListStsWithLables list statefulset
func ListStsWithLabels(ns, label string) ([]apps_v1.StatefulSet, error) {
ctx := context.Background()
opts := v1.ListOptions{LabelSelector: label}
stses, err := classicalClientSet.AppsV1().StatefulSets(ns).List(ctx, opts)
if err != nil {
return nil, err
}
return stses.Items, nil
}

// ListStsBios list all statefulset bio in :ns
func ListStsBios(ns string) ([]*Bio, error) {
ctx := context.Background()
opts := v1.ListOptions{}
stses, err := classicalClientSet.AppsV1().StatefulSets(ns).List(ctx, opts)
Expand All @@ -54,15 +65,30 @@ func ListSts(ns string) ([]*Bio, error) {
return res, nil
}

// SetStsImgWithLabel ...
func SetStsImgWithLabel(id *ContainerPath, label ...string) error {
return setStsImg(id, label...)
}

// SetStsImg update statefulset image field
func SetStsImg(id *ContainerPath) error {
return setStsImg(id)
}

func setStsImg(id *ContainerPath, labels ...string) error {
ctx := context.Background()
opts := v1.GetOptions{}
s, err := classicalClientSet.AppsV1().StatefulSets(id.Ns).Get(ctx, id.Name, opts)
if err != nil {
jsonlog.Err(err, map[string]any{"sts": id.Name, "msg": "get sts failed"})
return err
}
if labels != nil {
ls := s.GetLabels()
if err = checkLabels(ls, labels); err != nil {
return err
}
}
cpy := s.DeepCopy()
found := false
for i, c := range cpy.Spec.Template.Spec.Containers {
Expand Down

0 comments on commit 5291245

Please sign in to comment.