apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: cloud-node-manager
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
  name: cloud-node-manager
  namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: cloud-node-manager
  labels:
    k8s-app: cloud-node-manager
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["watch","list","get","update", "patch"]
- apiGroups: [""]
  resources: ["nodes/status"]
  verbs: ["patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cloud-node-manager
  labels:
    k8s-app: cloud-node-manager
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cloud-node-manager
subjects:
- kind: ServiceAccount
  name: cloud-node-manager
  namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: cloud-node-manager
  namespace: kube-system
  labels:
    component: cloud-node-manager
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 50%
  selector:
    matchLabels:
      k8s-app: cloud-node-manager
  template:
    metadata:
      labels:
        k8s-app: cloud-node-manager
      annotations:
        cluster-autoscaler.kubernetes.io/daemonset-pod: "true"
    spec:
      priorityClassName: system-node-critical
      serviceAccountName: cloud-node-manager
      hostNetwork: true {{/* required to fetch correct hostname */}}
      nodeSelector:
        kubernetes.io/os: linux
      tolerations:
      - key: CriticalAddonsOnly
        operator: Exists
      - key: node-role.kubernetes.io/master
        operator: "Exists"
        effect: NoSchedule        
      - key: node-role.kubernetes.io/control-plane
        operator: "Exists"
        effect: NoSchedule
      - operator: "Exists"
        effect: NoExecute
      - operator: "Exists"
        effect: NoSchedule
      containers:
      - name: cloud-node-manager
        image: {{ContainerImage "cloud-node-manager"}}
        imagePullPolicy: IfNotPresent
        command:
        - cloud-node-manager
        - --node-name=$(NODE_NAME)
        {{- if IsAzureStackCloud}}
        - --use-instance-metadata=false
        - --cloud-config=/etc/kubernetes/azure.json
        - --kubeconfig=/var/lib/kubelet/kubeconfig
        {{end}}
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        {{- if IsAzureStackCloud}}
        - name: AZURE_ENVIRONMENT_FILEPATH
          value: /etc/kubernetes/azurestackcloud.json
        - name: AZURE_GO_SDK_LOG_LEVEL
          value: INFO
        {{end}}
        resources:
          requests:
            cpu: 50m
            memory: 50Mi
          limits:
            cpu: 2000m
            memory: 512Mi
        {{- if IsAzureStackCloud}}
        securityContext:
          runAsUser: 0
          runAsGroup: 0
        volumeMounts:
        - name: etc-kubernetes
          mountPath: /etc/kubernetes
          readOnly: true
        - name: etc-ssl
          mountPath: /etc/ssl
          readOnly: true
        - name: path-kubeconfig
          mountPath: /var/lib/kubelet/kubeconfig
          readOnly: true
      volumes:
        - name: etc-kubernetes
          hostPath:
            path: /etc/kubernetes
        - name: etc-ssl
          hostPath:
            path: /etc/ssl
        - name: path-kubeconfig
          hostPath:
            path: /var/lib/kubelet/kubeconfig
            type: FileOrCreate
        {{end}}
{{- if and HasWindows (IsKubernetesVersionGe "1.18.0")}}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: cloud-node-manager-windows
  namespace: kube-system
  labels:
    component: cloud-node-manager
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 50%
  selector:
    matchLabels:
      k8s-app: cloud-node-manager-windows
  template:
    metadata:
      labels:
        k8s-app: cloud-node-manager-windows
      annotations:
        cluster-autoscaler.kubernetes.io/daemonset-pod: "true"
    spec:
      priorityClassName: system-node-critical
      serviceAccountName: cloud-node-manager
      securityContext:
        windowsOptions:
          runAsUserName: "NT AUTHORITY\\system"
      nodeSelector:
        kubernetes.io/os: windows
      tolerations:
      - key: CriticalAddonsOnly
        operator: Exists
      - key: node-role.kubernetes.io/master
        operator: "Exists"
        effect: NoSchedule            
      - key: node-role.kubernetes.io/control-plane
        operator: "Exists"
        effect: NoSchedule
      - operator: "Exists"
        effect: NoExecute
      - operator: "Exists"
        effect: NoSchedule
      containers:
      - name: cloud-node-manager
        image: {{ContainerImage "cloud-node-manager"}}
        imagePullPolicy: IfNotPresent
        command:
        - /cloud-node-manager.exe
        - --node-name=$(NODE_NAME)
        - --kubeconfig=C:\k\config
        {{- if IsAzureStackCloud}}
        - --use-instance-metadata=false
        - --cloud-config=C:\k\azure.json
        lifecycle:
          postStart:
            exec:
              command:
              - C:\k\addazsroot.bat
        {{end}}
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        {{- if IsAzureStackCloud}}
        - name: AZURE_ENVIRONMENT_FILEPATH
          value: C:\k\azurestackcloud.json
        - name: AZURE_GO_SDK_LOG_LEVEL
          value: INFO
        {{end}}
        resources:
          requests:
            cpu: 50m
            memory: 50Mi
          limits:
            cpu: 2000m
            memory: 512Mi
        volumeMounts:
        - name: azure-config
          mountPath: C:\k
      volumes:
        - name: azure-config
          hostPath:
            path: C:\k
            type: Directory
{{end}}