yonahd / kor

A Golang Tool to discover unused Kubernetes Resources
MIT License
1.04k stars 96 forks source link

feat: add inUse label prompt for non deleted resources #150

Closed patricktalmeida closed 1 year ago

patricktalmeida commented 1 year ago

This PR covers issue #123

yonahd commented 1 year ago

Maybe we can have some generic function something like

func FlagResource(clientset kubernetes.Interface, namespace, resourceType, resourceName string) error {
    // Get the resource dynamically based on the resource type
    resource, err := getResource(clientset, namespace, resourceType, resourceName)
    if err != nil {
        return err
    }

    // Update the labels using reflection
    labelField := reflect.ValueOf(resource).Elem().FieldByName("Labels")
    if labelField.IsValid() {
        labels := labelField.Interface().(map[string]string)
        if labels == nil {
            labels = make(map[string]string)
        }
        labels["kor/used"] = "true"
        labelField.Set(reflect.ValueOf(labels))
    } else {
        return fmt.Errorf("unable to set labels for resource type: %s", resourceType)
    }

    // Update the resource
    _, err = updateResource(clientset, namespace, resourceType, resource)
    return err
}

And just have a switch case for getting and updating e.g.(and similar function for updating)

func getResource(clientset kubernetes.Interface, namespace, resourceType, resourceName string) (interface{}, error) {
    switch resourceType {
    case "ConfigMap":
        return clientset.CoreV1().ConfigMaps(namespace).Get(context.TODO(), resourceName, metav1.GetOptions{})
    case "Secret":
        return clientset.CoreV1().Secrets(namespace).Get(context.TODO(), resourceName, metav1.GetOptions{})
    ....
}
patricktalmeida commented 1 year ago

Maybe we can have some generic function something like

func FlagResource(clientset kubernetes.Interface, namespace, resourceType, resourceName string) error {
  // Get the resource dynamically based on the resource type
  resource, err := getResource(clientset, namespace, resourceType, resourceName)
  if err != nil {
      return err
  }

  // Update the labels using reflection
  labelField := reflect.ValueOf(resource).Elem().FieldByName("Labels")
  if labelField.IsValid() {
      labels := labelField.Interface().(map[string]string)
      if labels == nil {
          labels = make(map[string]string)
      }
      labels["kor/used"] = "true"
      labelField.Set(reflect.ValueOf(labels))
  } else {
      return fmt.Errorf("unable to set labels for resource type: %s", resourceType)
  }

  // Update the resource
  _, err = updateResource(clientset, namespace, resourceType, resource)
  return err
}

And just have a switch case for getting and updating e.g.(and similar function for updating)

func getResource(clientset kubernetes.Interface, namespace, resourceType, resourceName string) (interface{}, error) {
  switch resourceType {
  case "ConfigMap":
      return clientset.CoreV1().ConfigMaps(namespace).Get(context.TODO(), resourceName, metav1.GetOptions{})
  case "Secret":
      return clientset.CoreV1().Secrets(namespace).Get(context.TODO(), resourceName, metav1.GetOptions{})
  ....
}

updated with suggestion.