对k8s集群进行操作时,往往要结合一些业务逻辑。比如判断某个用户有没有访问权限,有没有操作权限,能不能看到其他人部署的资源等需求。那么这时候往往是要把权限处理代码跟k8s操作代码写在一起了。非常不优雅,也难以复用。
kom 提供了get,list,create,update,patch,delete,exec,logs,watch九种callback处理链,支持设置多个自定义callback方法,而且可以排序,可以精确控制callback的处理顺序。后面将使用一个例子,来展示如何使用。
kom在项目中引入 kom 依赖:
import (
_ "github.com/weibaohui/kom/callbacks" // 导入回调机制
"github.com/weibaohui/kom"
)思路二:
1、查询所有的Pod出来
2、逐个过滤Pod,将带有user=username标签的Pod过滤出来,形成一个新的Pod 列表
3、返回过滤后的Pod 列表
通过分析,可以看出来,思路一更好,在查询前就附加条件,对资源的消耗也更小。我们按思路一来实现:
先上代码
func List(k8s *kom.Kubectl) error {
// 在这里可以统一进行权限认证等操作,返回error即可阻断执行
u := k8s.Statement.Context.Value("user")
options := k8s.Statement.ListOptions
if options == nil || len(options) == 0 {
options = []metav1.ListOptions{
{
LabelSelector: fmt.Sprintf("user=%s", u),
},
}
} else {
opt := options[0]
if opt.LabelSelector != "" {
opt.LabelSelector = fmt.Sprintf("%s,user=%s", opt.LabelSelector, u)
} else {
opt.LabelSelector = fmt.Sprintf("user=%s", u)
}
}
k8s.Statement.ListOptions = options
return nil
}主要分3分方面:
1、从context中拿到用户 u := k8s.Statement.Context.Value("user")
2、看ListOption中是否有LabelSelector,增加标签
这里有问题,就是我们的用户从哪里设置进去?
我们以gin框架为例,假设用户名为zhangshan,那么我们通过ctx进行传递。
使用context.WithValue(ctx, "user", "zhangsan")进行包裹。
然后,最重要的地方,我们在调用kom的时候,一定要使用.WithContext(ctx)将ctx传入kom,如果不传递,那么callback中,我们将无法获取用户。
传入的ctx,可以在callback中的kom.Kubectl.Statement.Context中将用户信息取出来。
func List(c *gin.Context) {
ns := c.Param("ns")
group := c.Param("group")
kind := c.Param("kind")
version := c.Param("version")
ctx := c.Request.Context()
ctx = context.WithValue(ctx, "user", "zhangsan")
var list []unstructured.Unstructured
err := kom.DefaultCluster().WithContext(ctx).Namespace(ns).GVK(group, version, kind).List(&list).Error
amis.WriteJsonListWithError(c, list, err)
}func RegisterCallback() {
queryCallback := kom.DefaultCluster().Callback().List()
_ = queryCallback.Before("kom:list").Register("user:list", List)
}我们注册callback,必须要使用Before指定位置,将我们自定义的逻辑,放在底层逻辑执行之前。这样才能放标签先设置,然后使用标签条件查询,这样才能生效
defaultKubeConfig := os.Getenv("KUBECONFIG")
if defaultKubeConfig == "" {
defaultKubeConfig = filepath.Join(homedir.HomeDir(), ".kube", "config")
}
_, _ = kom.Clusters().RegisterInCluster()
_, _ = kom.Clusters().RegisterByPathWithID(defaultKubeConfig, "default")
kom.Clusters().Show()
// 初始化回调
callback.RegisterCallback()在注册k8s集群后,一定记得执行RegisterCallback(),这样才能生效。
通过 kom 的callback机制,可以轻松的进行权限控制,提供了get,list,create,update,patch,delete,exec,logs,watch九种callback处理链。
那么我们按照上面的示例,我们可以对资源进行充分的管控。通过Before\After方法可以控制我们自定义的callback的顺序。这个顺序可以方便的进行执行前的处理,执行后的处理,能够满足几乎所有的处理逻辑。
尤其是可以将对k8s集群资源的操作跟业务逻辑彻底隔离开了,大大提升了灵活性。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。