// 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. VS Code C++ 代码格式化(clang-format)

    --- # 语言: None, Cpp, Java, JavaScript, ObjC, Proto, TableGen, TextProto Language: Cpp # BasedOnStyle ...

  2. KingbaseES R6 集群创建流复制只读副本库案例

    一.环境概述 [kingbase@node2 bin]$ ./ksql -U system test ksql (V8.0) Type "help" for help. test= ...

  3. Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点

    Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...

  4. 【开源打印组件】vue-plugin-hiprint初体验

    vue-plugin-hiprint的学习与应用 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习 ...

  5. HTTP和Servlet快速入门

    目录 1.HTTP 1.1 请求数据格式 1.2 相应数据格式 2.Servlet 3.Servlert的xml配置 1.HTTP 1.1 请求数据格式 请求行:请求数据的第一行 包含三个内容,按顺序 ...

  6. .NET 7 SDK 开始 支持构建容器化应用程序

    微软于 8 月 25 日在.NET官方博客上,.NET 7 SDK 将包括对创建容器化应用程序的支持,作为构建发布过程的一部分,从而绕过需要.显式 Docker 构建阶段. 这一决定背后的基本认知是简 ...

  7. Ubuntu 系统服务器初始化配置、安全加固、内核优化和常用软件安装的Shell脚本分享

    转载自:https://www.bilibili.com/read/cv13875402?spm_id_from=333.999.0.0 描述: 适用于企业内部 Ubuntu 操作服务器初始化.系统安 ...

  8. Elasticsearch Reindex性能提升10倍+实战

    文章转载自: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247484134&idx=1&sn=750249a ...

  9. CentOS 7 下安装 MySQL 8.x

    CentOS 7 下安装 MySQL 8.x 作者:Grey 原文地址: 博客园:CentOS 7 下安装 MySQL 8.x CSDN:CentOS 7 下安装 MySQL 8.x 环境 CentO ...

  10. 关于将Azure云上磁盘导出-使用VirtualBox转换成vmdk格式的方法记录

    在工作中,经常会遇到虚拟磁盘文件格式的转换需求,尤其是在虚拟化迁移及云环境迁移到DC的虚拟化环境中 或者中转处理,如最近笔者遇到一个需要将Azure Cloud上的磁盘导出到VMware中,但Azur ...