
# 使用client-go访问CCI
本节将介绍如何将CCI认证工具cci-iam-authenticator与client-go结合使用以调用API。
#### 安装cci-iam-authenticator
下载安装及设置cci-iam-authenticator。
#### 安装kubernetes client-go
详情请参考[Installing client-go](https://github.com/kubernetes/client-go/blob/master/INSTALL.md) 。
![](https://support.huaweicloud.com/sdkreference-cci/public_sys-resources/note_3.0-zh-cn.png)
- 当前**CCI服务开放的API对应的Kubernetes版本为1.19** ，根据[Compatibility: client-go \<-\> Kubernetes clusters](https://github.com/kubernetes/client-go#compatibility-client-go---kubernetes-clusters)，推荐使用的SDK版本为k8s.io/client-go@kubernetes-1.19.0。
- CCI服务是共享集群，不支持watch集群下全量的命名空间以及全量命名空间下的资源，支持watch指定命名空间下的资源。
 
#### 使用Go SDK
![](https://support.huaweicloud.com/sdkreference-cci/public_sys-resources/note_3.0-zh-cn.png)
示例已通过以下版本的测试：
1. k8s.io/client-go@kubernetes-1.15.0
2. k8s.io/client-go@kubernetes-1.16.0
3. k8s.io/client-go@kubernetes-1.17.0
4. k8s.io/client-go@kubernetes-1.18.0
5. k8s.io/client-go@kubernetes-1.19.0
6. k8s.io/client-go@kubernetes-1.20.0
 
使用用户名/密码进行认证
```
import (
"fmt"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/clientcmd/api"
)
const (
apiVersion = "client.authentication.k8s.io/v1beta1"
// 云容器实例 CCI，参考https://developer.huaweicloud.com/endpoint
        
cciEndpoint = "<例如华北-北京四: https://cci.cn-north-4.myhuaweicloud.com>"
// 统一身份认证服务 IAM，参考https://developer.huaweicloud.com/endpoint
        
iamEndpoint = "<例如华北-北京四: https://iam.cn-north-4.myhuaweicloud.com>"
// 地区和终端节点，参考https://developer.huaweicloud.com/endpoint
        
        projectName = "<例如华北-北京四: cn-north-4>"
)
// userName, domainName, password分别表示用户名、账号名及密码，需用户自行传入，因用户名、账号名及密码用于认证，存在安全风险，请用户注意使用安全；
var userName, domainName, password string
// NewClient 通过username/password创建Clientset
func NewClient() (*kubernetes.Clientset, error) {
config, err := clientcmd.BuildConfigFromFlags(cciEndpoint, "")
if err != nil {
return nil, err
}
var optionArgs []string
optionArgs = append(optionArgs, fmt.Sprintf("--iam-endpoint=%s", iamEndpoint))
optionArgs = append(optionArgs, fmt.Sprintf("--project-name=%s", projectName))
optionArgs = append(optionArgs, fmt.Sprintf("--token-only=false"))
optionArgs = append(optionArgs, fmt.Sprintf("--domain-name=%s", domainName))
optionArgs = append(optionArgs, fmt.Sprintf("--user-name=%s", userName))
optionArgs = append(optionArgs, fmt.Sprintf("--password=%s", password))
config.ExecProvider = &api.ExecConfig{
Command:    "cci-iam-authenticator",
APIVersion: apiVersion,
Args:       append([]string{"token"}, optionArgs...),
Env:        make([]api.ExecEnvVar, 0),
}
return kubernetes.NewForConfig(config)
}
```
使用AK/SK进行认证
```
import (
"fmt"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/clientcmd/api"
)
const (
apiVersion = "client.authentication.k8s.io/v1beta1"
// 云容器实例 CCI，参考https://developer.huaweicloud.com/endpoint
        
cciEndpoint = "<例如华北-北京四: https://cci.cn-north-4.myhuaweicloud.com>"
// 统一身份认证服务 IAM，参考https://developer.huaweicloud.com/endpoint
        
iamEndpoint = "<例如华北-北京四: https://iam.cn-north-4.myhuaweicloud.com>"
// 地区和终端节点，参考https://developer.huaweicloud.com/endpoint
        
projectName = "<例如华北-北京四: 'cn-north-4'>"
)
// 获取AK/SK参考: https://support.huaweicloud.com/devg-cci/cci_kubectl_01.html#cci_kubectl_01__section17023744719
// ak，sk分别表示用户AK/SK，需用户自行传入，因AK/SK用于认证，存在安全风险，请用户注意使用安全。
var ak, sk string
// NewClient 通过AK/SK认证创建Clientset
func NewClient() (*kubernetes.Clientset, error) {
config, err := clientcmd.BuildConfigFromFlags(cciEndpoint, "")
if err != nil {
return nil, err
}
var optionArgs []string
optionArgs = append(optionArgs, fmt.Sprintf("--iam-endpoint=%s", iamEndpoint))
optionArgs = append(optionArgs, fmt.Sprintf("--project-name=%s", projectName))
optionArgs = append(optionArgs, fmt.Sprintf("--token-only=false"))
optionArgs = append(optionArgs, fmt.Sprintf("--ak=%s", ak))
optionArgs = append(optionArgs, fmt.Sprintf("--sk=%s", sk))
config.ExecProvider = &api.ExecConfig{
Command:    "cci-iam-authenticator",
APIVersion: apiVersion,
Args:       append([]string{"token"}, optionArgs...),
Env:        make([]api.ExecEnvVar, 0),
}
return kubernetes.NewForConfig(config)
}
```
生成kubeconfig配置文件用于认证配置
```
import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
// NewClient 通过kubeconfig配置文件创建Clientset
// kubeconfig配置文件需包含认证相关信息
func NewClient() (*kubernetes.Clientset, error) {
config, err := clientcmd.BuildConfigFromFlags("", "/path/to/kubeconfig")
if err != nil {
return nil, err
}
return kubernetes.NewForConfig(config)
}
```
#### 代码示例
您可以前往[开发体验馆Codelabs / Namespace生命周期代码示例（Go）](https://codelabs.developer.huaweicloud.com/codelabs/home?direction=down(is_recommend),down(published_at)&pageno=1&pagesize=18&productshorts=CCI)下载相关代码，并在线调试。
#### FAQ
**问：上述代码示例是否存在请求结果返回码为401的情况？**
**答：** 一般情况下，如果密码或AK/SK配置无误，client-go提供的定期刷新token的机制（即定期调用cci-iam-authenticator刷新token，具体实现参考<https://github.com/kubernetes/client-go/blob/master/plugin/pkg/client/auth/exec/exec.go>），能确保token不会因过期而失效（token的有效期为24小时），从而避免请求结果返回码为401。
但当账号权限发生变更时，token可能也会失效，不属于超期失效的情形，在该情形下，仍会出现请求结果返回码为401的情况。
