// Copyright (c) 2021. Huawei Technologies Co., Ltd. All rights reserved.

// Package common define common utils
package common

import (
"context"
"fmt"
"os"
"sync"
"time"

v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"volcano.sh/apis/pkg/client/clientset/versioned"

"huawei.com/npu-exporter/hwlog"
"huawei.com/npu-exporter/utils"
)

const (
maxLen = 200

// PVCVolumeName the volume name of storage pvc
PVCVolumeName = "platform"
// StoragePVCName the PVC name of storage
StoragePVCName = "storage-pvc"
// PublicPVCName the PVC name of public dir
PublicPVCName = "storage-pvc-public"
)

var (
k8sClientOnce sync.Once
vcClientOnce sync.Once
kubeClientSet *kubernetes.Clientset
vcClientSet *versioned.Clientset
// Kubeconfig the k8s master config file
Kubeconfig string
)

// K8sBaseClient base k8s client for other component to extend
type K8sBaseClient struct {
Clientset *kubernetes.Clientset
VcClientSet *versioned.Clientset
NameSpace string
}

// K8SController is a controller for k8s client
type K8SController struct {
KubeClientSet kubernetes.Interface
}

// K8sClient Get the internal k8s client of the cluster
func K8sClient(kubeconfig string) (*kubernetes.Clientset, error) {
k8sClientOnce.Do(func() {
if kubeconfig == "" {
configPath := os.Getenv("KUBECONFIG")
if len(configPath) > maxLen {
hwlog.RunLog.Fatal("the path is too long")
}
kubeconfig = configPath
}
cfgPath, err := utils.CheckPath(kubeconfig)
if err != nil {
hwlog.RunLog.Fatal(err)
}
config, err := clientcmd.BuildConfigFromFlags("", cfgPath)
if err != nil {
hwlog.RunLog.Fatal(err)
}
// Create a new k8sClientSet based on the specified config using the current context
kubeClientSet, err = kubernetes.NewForConfig(config)
if err != nil {
hwlog.RunLog.Fatal(err)
}
})

return kubeClientSet, nil
}

// NewK8sController init k8s controller client
func NewK8sController(kc *kubernetes.Clientset) *K8SController {
return &K8SController{
KubeClientSet: kc,
}
}

// VcClient Get the internal volcano client of the cluster
func VcClient(vcConfig string) (*versioned.Clientset, error) {
vcClientOnce.Do(func() {
if vcConfig == "" {
configPath := os.Getenv("KUBECONFIG")
if len(configPath) > maxLen {
hwlog.RunLog.Fatal("the path is too long")
}
vcConfig = configPath
}
cfgPath, err := utils.CheckPath(vcConfig)
if err != nil {
hwlog.RunLog.Fatal(err)
}
config, err := clientcmd.BuildConfigFromFlags("", cfgPath)
if err != nil {
hwlog.RunLog.Fatal(err)
}
// Create a new vcClientSet based on the specified config using the current context
vcClientSet, err = versioned.NewForConfig(config)
if err != nil {
hwlog.RunLog.Fatal(err)
}
})

return vcClientSet, nil
}

// GetDBConnectionPath get db connection path
func (handler *K8sBaseClient) GetDBConnectionPath(retryCount, timeInterval int,
secretName, namespace string) (string, error) {
for {
if retryCount < 0 {
return "", fmt.Errorf("the secret of db information with name(%s) cannot be find in namespace(%s)",
secretName, namespace)
}

secret, err := handler.GetDBSecret(secretName, namespace)
if err != nil {
retryCount--
hwlog.RunLog.Error(err)
time.Sleep(time.Duration(timeInterval) * time.Second)
continue
}

return fmt.Sprintf("%s", secret.Data[DBSecretConnectionPathKey]), nil
}
}

func (handler *K8sBaseClient) getDBSecret(name, namespace string) (*v1.Secret, error) {
secret, err := handler.Clientset.CoreV1().Secrets(namespace).Get(context.TODO(),
name, metav1.GetOptions{})

return secret, err
}

// GetDBSecret get db secret
func (handler *K8sBaseClient) GetDBSecret(name, namespace string) (*v1.Secret, error) {
secret, err := handler.getDBSecret(name, namespace)
if err != nil {
return nil, err
}

if err = handler.validDBSecret(secret); err != nil {
return nil, err
}

return secret, nil
}

func (handler *K8sBaseClient) validDBSecret(secret *v1.Secret) error {
var err error
if secret.Data == nil {
err = fmt.Errorf("the secret data for connect to database is empty")
return err
}

if _, ok := secret.Data[DBSecretConnectionPathKey]; !ok {
err = fmt.Errorf("the %s field for connecting to the database in the secret is incorrect",
DBSecretConnectionPathKey)
return err
}

return nil
}

mindxdl--common--k8s_utils.go的更多相关文章

  1. Socket聊天程序——Common

    写在前面: 上一篇记录了Socket聊天程序的客户端设计,为了记录的完整性,这里还是将Socket聊天的最后一个模块--Common模块记录一下.Common的设计如下: 功能说明: Common模块 ...

  2. angularjs 1 开发简单案例(包含common.js,service.js,controller.js,page)

    common.js var app = angular.module('app', ['ngFileUpload']) .factory('SV_Common', function ($http) { ...

  3. Common Bugs in C Programming

    There are some Common Bugs in C Programming. Most of the contents are directly from or modified from ...

  4. ANSI Common Lisp Practice - My Answers - Chatper - 3

    Ok, Go ahead. 1 (a) (b) (c) (d) 2 注:union 在 Common Lisp 中的作用就是求两个集合的并集.但是这有一个前提,即给的两个列表已经满足集合的属性了.具体 ...

  5. [LeetCode] Lowest Common Ancestor of a Binary Tree 二叉树的最小共同父节点

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

  6. [LeetCode] Lowest Common Ancestor of a Binary Search Tree 二叉搜索树的最小共同父节点

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  7. [LeetCode] Longest Common Prefix 最长共同前缀

    Write a function to find the longest common prefix string amongst an array of strings. 这道题让我们求一系列字符串 ...

  8. 48. 二叉树两结点的最低共同父结点(3种变种情况)[Get lowest common ancestor of binary tree]

    [题目] 输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点. 二叉树的结点定义如下:  C++ Code  123456   struct BinaryTreeNode {     int ...

  9. 动态规划求最长公共子序列(Longest Common Subsequence, LCS)

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  10. 【leetcode】Longest Common Prefix

    题目简述: Write a function to find the longest common prefix string amongst an array of strings. 解题思路: c ...

随机推荐

  1. HC32L110(五) Ubuntu20.04 VSCode的Debug环境配置

    目录 HC32L110(一) HC32L110芯片介绍和Win10下的烧录 HC32L110(二) HC32L110在Ubuntu下的烧录 HC32L110(三) HC32L110的GCC工具链和VS ...

  2. KingbaseES V8R6 维护管理案例之---Kstudio在CentOS 7启动故障

    ​ 案例说明: 在CentOS 7上安装KingbaseES V8R6C006数据库后,启动Kstudio图形界面启动失败,gtk动态库加载失败,安装gtk相关动态库后,问题解决. 适用版本: Kin ...

  3. 如何修改SAO用户密码

    KingbaseES SAO 用户是专门用于审计管理的用户,用户配置审计策略需要使用该用户.在initdb 完成后,SAO  用户的默认密码保存在参数 sysaudit.audit_table_pas ...

  4. 【Android 逆向】ARM while 逆向

    #include <stdio.h> int dowhile(int n){ int i = 1; int s = 0; do{ s += i; }while(i++ < n); r ...

  5. 【HMS Core】集成地图服务不显示地图问题

    ​[问题描述] 关于华为HMS-地图服务不显示地图的问题. 背景:集成华为地图服务运行后页面不显示地图,运行app后不展示地图报错MapsInitializer is not initialized. ...

  6. 跨语言调用C#代码的新方式-DllExport

    简介 上一篇文章使用C#编写一个.NET分析器文章发布以后,很多小伙伴都对最新的NativeAOT函数导出比较感兴趣,今天故写一篇短文来介绍一下如何使用它. 在以前,如果有其他语言需要调用C#编写的库 ...

  7. 升级Windows 2003域控制器到Windows 2012 R2

    由于Windows 2003包括R2的扩展支持在今年7月14日就会过期.如果在扩展周期结束之前没有和微软签订昂贵服务协议,那么系统将得不到任何补丁和技术支持. 我这里准备了两台测试用的机器做这个实验. ...

  8. 在 CentOS 8 上使用 FirewallD 设置防火墙

    简介 一个 Linux 防火墙可用于保护您的工作站或服务器免受不需要的流量干扰.您可以设置规则来阻止或允许流量通过.CentOS 8 带有一个动态的.可定制的基于主机的防火墙和一个 D-Bus 接口. ...

  9. 8. Ceph 基础篇 - 运维常用操作

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247485300&idx=1&sn=aacff9f7 ...

  10. 5.使用nexus3配置npm私有仓库

    当我们运行前端项目的时候,常常在解决依赖的时候会加上一个参数npm install --registry=https://registry.npm.taobao.org将源指定为淘宝的源,以期让速度加 ...