in pkg/provider/branch/provider.go [315:411]
func (b *branchENIProvider) CreateAndAnnotateResources(podNamespace string, podName string, resourceCount int) (ctrl.Result, error) {
// Get the pod from cache
pod, err := b.apiWrapper.PodAPI.GetPod(podNamespace, podName)
if err != nil {
branchProviderOperationsErrCount.WithLabelValues("create_get_pod").Inc()
return ctrl.Result{}, err
}
if _, ok := pod.Annotations[config.ResourceNamePodENI]; ok {
// Pod from cache already has annotation, skip the job
return ctrl.Result{}, nil
}
// Get the pod object again directly from API Server as the cache can be stale
pod, err = b.apiWrapper.PodAPI.GetPodFromAPIServer(b.ctx, podNamespace, podName)
if err != nil {
branchProviderOperationsErrCount.WithLabelValues("get_pod_api_server").Inc()
return ctrl.Result{}, err
}
if _, ok := pod.Annotations[config.ResourceNamePodENI]; ok {
// Pod doesn't have an annotation yet. Create Branch ENI and annotate the pod
b.log.Info("skipping pod event as the pod already has pod-eni allocated",
"namespace", pod.Namespace, "name", pod.Name)
return ctrl.Result{}, nil
}
securityGroups, err := b.apiWrapper.SGPAPI.GetMatchingSecurityGroupForPods(pod)
if err != nil {
return ctrl.Result{}, err
}
if len(securityGroups) == 0 {
b.apiWrapper.K8sAPI.BroadcastEvent(pod, ReasonSecurityGroupRequested,
"Pod will get the instance security group as the pod didn't match any Security Group from "+
"SecurityGroupPolicy", v1.EventTypeWarning)
} else {
b.apiWrapper.K8sAPI.BroadcastEvent(pod, ReasonSecurityGroupRequested, fmt.Sprintf("Pod will get the following "+
"Security Groups %v", securityGroups), v1.EventTypeNormal)
}
log := b.log.WithValues("pod namespace", pod.Namespace, "pod name", pod.Name, "nodeName", pod.Spec.NodeName)
start := time.Now()
trunkENI, isPresent := b.getTrunkFromCache(pod.Spec.NodeName)
if !isPresent {
// This should never happen
branchProviderOperationsErrCount.WithLabelValues("get_trunk_create").Inc()
return ctrl.Result{}, fmt.Errorf("trunk not found for node %s", pod.Spec.NodeName)
}
// Get the list of branch ENIs that will be allocated to the pod object
branchENIs, err := trunkENI.CreateAndAssociateBranchENIs(pod, securityGroups, resourceCount)
if err != nil {
if err == trunk.ErrCurrentlyAtMaxCapacity {
return ctrl.Result{RequeueAfter: cooldown.GetCoolDown().GetCoolDownPeriod(), Requeue: true}, nil
}
b.apiWrapper.K8sAPI.BroadcastEvent(pod, ReasonBranchAllocationFailed,
fmt.Sprintf("failed to allocate branch ENI to pod: %v", err), v1.EventTypeWarning)
return ctrl.Result{}, err
}
branchProviderOperationLatency.WithLabelValues(operationCreateBranchENI, strconv.Itoa(resourceCount)).
Observe(timeSinceSeconds(start))
jsonBytes, err := json.Marshal(branchENIs)
if err != nil {
trunkENI.PushENIsToFrontOfDeleteQueue(pod, branchENIs)
b.log.Info("pushed the ENIs to the delete queue as failed to unmarshal ENI details", "ENI/s", branchENIs)
branchProviderOperationsErrCount.WithLabelValues("annotate_branch_eni").Inc()
return ctrl.Result{}, err
}
start = time.Now()
// Annotate the pod with the created resources
err = b.apiWrapper.PodAPI.AnnotatePod(pod.Namespace, pod.Name, pod.UID,
config.ResourceNamePodENI, string(jsonBytes))
if err != nil {
trunkENI.PushENIsToFrontOfDeleteQueue(pod, branchENIs)
b.log.Info("pushed the ENIs to the delete queue as failed to annotate the pod", "ENI/s", branchENIs)
b.apiWrapper.K8sAPI.BroadcastEvent(pod, ReasonBranchENIAnnotationFailed,
fmt.Sprintf("failed to annotate pod with branch ENI details: %v", err), v1.EventTypeWarning)
branchProviderOperationsErrCount.WithLabelValues("annotate_branch_eni").Inc()
return ctrl.Result{}, err
}
// Broadcast event to indicate the resource has been successfully created and annotated to the pod object
b.apiWrapper.K8sAPI.BroadcastEvent(pod, ReasonResourceAllocated,
fmt.Sprintf("Allocated %s to the pod", string(jsonBytes)), v1.EventTypeNormal)
branchProviderOperationLatency.WithLabelValues(operationAnnotateBranchENI, strconv.Itoa(resourceCount)).
Observe(timeSinceSeconds(start))
log.Info("created and annotated branch interface/s successfully", "branches", branchENIs)
return ctrl.Result{}, nil
}