- [X] APISnoop org-flow : CoreV1ServiceAccountResourceLifecycleTest.org
- [X] test approval issue : kubernetes/kubernetes#89071
- [X] test pr : kuberenetes/kubernetes#90193
- [X] two weeks soak start date : 23/04/2020 NZDT
- [ ] two weeks soak end date : 07/05/2020 NZDT
- [ ] test promotion pr : kubernetes/kubernetes#90930
According to this APIsnoop query, there are still some remaining ServiceAccount endpoints which are untested.
SELECT
operation_id,
-- k8s_action,
-- path,
-- description,
kind
FROM untested_stable_core_endpoints
where path not like '%volume%'
and kind like 'ServiceAccount'
-- and operation_id ilike '%%'
ORDER BY kind,operation_id desc
-- LIMIT 25
;
operation_id | kind
------------------------------------------------+----------------
patchCoreV1NamespacedServiceAccount | ServiceAccount
listCoreV1ServiceAccountForAllNamespaces | ServiceAccount
deleteCoreV1CollectionNamespacedServiceAccount | ServiceAccount
(3 rows)
- Create a ServiceAccount with a static label
- Create a Secret
- Patch the ServiceAccount with a new Label and a new Secret
- Get the ServiceAccount to ensure it’s patched
- Create a ServiceAccountToken
- List all ServiceAccounts in all Namespaces find the ServiceAccount(1) ensure that the ServiceAccount is found and is patched
- Delete Namespaced ServiceAccount(1) via a Collection with a LabelSelector
- Delete the Secret
package main
import (
"encoding/json"
"fmt"
"flag"
"os"
v1 "k8s.io/api/core/v1"
// "k8s.io/client-go/dynamic"
// "k8s.io/apimachinery/pkg/runtime/schema"
authenticationv1 "k8s.io/api/authentication/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/clientcmd"
)
func main() {
// uses the current context in kubeconfig
kubeconfig := flag.String("kubeconfig", fmt.Sprintf("%v/%v/%v", os.Getenv("HOME"), ".kube", "config"), "(optional) absolute path to the kubeconfig file")
flag.Parse()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
fmt.Println(err)
return
}
// make our work easier to find in the audit_event queries
config.UserAgent = "live-test-writing"
// creates the clientset
ClientSet, _ := kubernetes.NewForConfig(config)
// DynamicClientSet, _ := dynamic.NewForConfig(config)
// podResource := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}
testNamespaceName := "default"
testServiceAccountName := "testserviceaccount"
testSecretName := "testsecret"
fmt.Println("creating a ServiceAccount")
testServiceAccount := v1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: testServiceAccountName,
Labels: map[string]string{"test-serviceaccount-static": "true"},
},
}
_, err = ClientSet.CoreV1().ServiceAccounts(testNamespaceName).Create(&testServiceAccount)
if err != nil {
fmt.Println(err, "failed to create a ServiceAccount")
return
}
fmt.Println("creating a Secret")
testSecret := v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: testSecretName,
},
Data: map[string][]byte{
"test-field": []byte("test-value"),
},
Type: "Opaque",
}
_, err = ClientSet.CoreV1().Secrets(testNamespaceName).Create(&testSecret)
if err != nil {
fmt.Println(err, "failed to create a Secret")
return
}
fmt.Println("patching the ServiceAccount")
testServiceAccountPatchData, err := json.Marshal(map[string]interface{}{
"secrets": []map[string]interface{}{{
"name": testSecretName,
}},
})
if err != nil {
fmt.Println(err, "failed to marshal JSON patch for the ServiceAccount")
return
}
_, err = ClientSet.CoreV1().ServiceAccounts(testNamespaceName).Patch(testServiceAccountName, types.StrategicMergePatchType, []byte(testServiceAccountPatchData))
if err != nil {
fmt.Println(err, "failed to patch the ServiceAccount")
return
}
fmt.Println("creating a ServiceAccountToken")
tokenExpirySeconds := int64(10000)
serviceAccountToken := authenticationv1.TokenRequest{
Spec: authenticationv1.TokenRequestSpec{
ExpirationSeconds: &tokenExpirySeconds,
Audiences: []string{testServiceAccountName},
},
}
_, err = ClientSet.CoreV1().ServiceAccounts(testNamespaceName).CreateToken(testServiceAccountName, &serviceAccountToken)
if err != nil {
fmt.Println(err, "failed to create the ServiceAccountToken")
return
}
fmt.Println("finding ServiceAccount in list of all ServiceAccounts (by LabelSelector)")
serviceAccountList, err := ClientSet.CoreV1().ServiceAccounts("").List(metav1.ListOptions{LabelSelector: "test-serviceaccount-static=true"})
foundServiceAccount := false
for _, serviceAccountItem := range serviceAccountList.Items {
if serviceAccountItem.ObjectMeta.Name == testServiceAccountName && serviceAccountItem.ObjectMeta.Namespace == testNamespaceName && serviceAccountItem.Secrets[0].Name == testSecretName {
foundServiceAccount = true
fmt.Println(serviceAccountItem)
break
}
}
if foundServiceAccount != true {
fmt.Println(err, "failed to find the created ServiceAccount")
return
}
fmt.Println("deleting the ServiceAccount")
err = ClientSet.CoreV1().ServiceAccounts(testNamespaceName).DeleteCollection(&metav1.DeleteOptions{}, metav1.ListOptions{})
if err != nil {
fmt.Println(err, "failed to delete the ServiceAccount by Collection")
return
}
fmt.Println("deleting the Secret")
err = ClientSet.CoreV1().Secrets(testNamespaceName).Delete(testSecretName, &metav1.DeleteOptions{})
if err != nil {
fmt.Println(err, "failed to delete the Secret")
return
}
fmt.Println("[status] complete")
}
Discover useragents:
select distinct useragent from audit_event where bucket='apisnoop' and useragent not like 'kube%' and useragent not like 'coredns%' and useragent not like 'kindnetd%' and useragent like 'live%';
useragent
-------------------
live-test-writing
(1 row)
List endpoints hit by the test:
select * from endpoints_hit_by_new_test where useragent like 'live%';
useragent | operation_id | hit_by_ete | hit_by_new_test
-------------------+------------------------------------------------+------------+-----------------
live-test-writing | createCoreV1NamespacedSecret | t | 2
live-test-writing | createCoreV1NamespacedServiceAccount | t | 2
live-test-writing | deleteCoreV1CollectionNamespacedServiceAccount | f | 2
live-test-writing | deleteCoreV1NamespacedSecret | t | 2
live-test-writing | listCoreV1ServiceAccountForAllNamespaces | f | 1
live-test-writing | patchCoreV1NamespacedServiceAccount | f | 2
(6 rows)
Display endpoint coverage change:
select * from projected_change_in_coverage;
category | total_endpoints | old_coverage | new_coverage | change_in_number
---------------+-----------------+--------------+--------------+------------------
test_coverage | 445 | 195 | 198 | 3
(1 row)
If a test with these calls gets merged, **test coverage will go up by 3 points**
This test is also created with the goal of conformance promotion.
/sig testing
/sig architecture
/area conformance